RPC(Remote Procedure Call)即遠程過程調用,說簡單點就是服務端和客戶端遵守一套約定好的協議,然後客戶端就可以調用服務端的函數。目前主流的rpc框架對比如下:
功能 | Hessian | Montan | rpcx | gRPC | Thrift | Dubbo | Dubbox | Spring Cloud |
---|---|---|---|---|---|---|---|---|
開發語言 | 跨語言 |
Java |
Go | 跨語言 | 跨語言 | Java | Java | Java |
分佈式(服務治理) | × | √ | √ | × | × | √ | √ | √ |
多序列化框架支持 | hessian | √(支持Hessian2、Json,可擴展) | √ | × 只支持protobuf) | ×(thrift格式) | √ | √ | √ |
多種註冊中心 | × | √ | √ | × | × | √ | √ | √ |
管理中心 | × | √ | √ | × | × | √ | √ | √ |
跨編程語言 | √ | ×(支持php client和C server) | × | √ | √ | × | × | × |
支持REST | × | × | × | × | × | × | √ | √ |
關注度 | 低 | 中 | 低 | 中 | 中 | 中 | 高 | 中 |
上手難度 | 低 | 低 | 中 | 中 | 中 | 低 | 低 | 中 |
運維成本 | 低 | 中 | 中 | 中 | 低 | 中 | 中 | 中 |
開源機構 | Caucho | Apache | Apache | Alibaba | Dangdang | Apache |
公司內部目前使用的方案是(server mesh or http) + protobuf,並不是真正意義上的RPC,最近自己研究了下,可以採用Thrift實現遠程服務調用,然後使用zookeeper構建服務發現和治理功能。下面主要介紹Thrift的使用。
Thrift項目的使用主要爲以下流程(安裝工具環境等請自行百度):
服務端:
1.定義接口文件
2.根據接口文件利用命令生成服務端對應語言的接口代碼
3.構建服務端代碼,部署服務端代碼
客戶端:
1.找服務端開發獲取其定義的接口文件
2.根據接口文件利用命令生成客戶端對應語言的接口代碼
3.構建客戶端代碼,調用服務端方法
下面介紹利用Thrift服務端和客戶端都是python實現RPC的案例
1.定義接口文件test.thrift
service TestService {
string test(1: i32 num,
2: string name)
}
這就是一個很簡單的接口,接口有連個參數,第一個爲32位的整數,第二個爲字符串,返回值爲字符串。
2.服務端根據接口文件生成接口代碼
thrift -gen py test.thrift
運行完這個命令後你會收穫以下文件
3.根據接口代碼編寫服務端代碼server.py,放在gen-py根目錄,並運行main函數啓動服務
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.server import TServer
from test import TestService
class TestServiceHandler:
def test(self, num, name):
return 'My name is ' + name + ', my age is ' + str(num)
if __name__ == '__main__':
handler = TestServiceHandler()
processor = TestService.Processor(handler)
transport = TSocket.TServerSocket(host='0.0.0.0', port=9090)
tfactory = TTransport.TBufferedTransportFactory()
pfactory = TBinaryProtocol.TBinaryProtocolFactory()
server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)
print 'python server:ready to start'
server.serve()
4.將test.thrift文件人肉發送給客戶端開發,然後客戶端開發重複第二步。
5.根據生成的接口代碼開發客戶端代碼
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from test8 import TestService
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
transport = TSocket.TSocket('0.0.0.0', 9090)
transport = TTransport.TBufferedTransport(transport)
protocol = TBinaryProtocol.TBinaryProtocol(transport)
client = TestService.Client(protocol)
transport.open()
cmd = 20
token = 'zhang san'
msg = client.test(cmd, token)
print(msg)
transport.close()
6.運行客戶端代碼,服務端返回結果
My name is zhang san, my age is 20
ps:需要保證客戶端和服務端在一個局域網內,能互相拼通