grpc 是rpc的一类。
grpc官网 : http://www.grpc.io/docs/tutorials/basic/python.html
序列化使用的是:https://developers.google.com/protocol-buffers/
cs模式,stub校验
四种模式,其实也就两种大模式有stream,没stream的;使用stream只不过是为了减少系统的开销
以下例子是python版,其它版体是大同小异
使用步聚:
1)定义IDL
syntax = "proto3"; package hello; service Greeter { rpc SayHello (HelloRequest) returns (stream HelloReply) {} }service ConnMysql { rpc ConnectMysql (MyqlRequest) returns (MysqlResponse) {} }message HelloRequest { string message = 1; int64 age = 2; }message HelloReply { string message = 1; int64 age = 2; }message MyqlRequest { string dbname = 1; }//连接mysql,响应返回值 message MysqlResponse { repeated string selectlist = 1; }
生成接口代码:
python -m grpc.tools.protoc -I=. --python_out=/Users/admin/devops/logCenter/logops/grpc/--grpc_python_out=/Users/admin/devops/logCenter/logops/grpc/proto/log.proto
生成的是一个log_pb2.py
2)写server端代码
# coding:utf-8 import log_pb2 from concurrent import futures import grpc import time_ONE_DAY_IN_SECONDS = 60 * 60 * 24 import MySQLdbclass Greeter(log_pb2.GreeterServicer): def SayHello(self, request, context): try:conn = MySQLdb.connect( host='127.0.0.1', port=3306, user='root', passwd='hugo', db='jiraconnector' ) cur = conn.cursor() sqli = "insert into api_taskid (task_id,task_name,task_env,create_time) VALUES (%s,%s,%s,%s)" cur.execute(sqli, (request.message, request.age, '4', '2016-06-20 06:54:28.488573')) cur.close() conn.commit() conn.close() print request.message print request.age yield log_pb2.HelloReply(message='hello hugo', age=10) except Exception as e: print eclass ConnMysql(log_pb2.ConnMysqlServicer): def ConnectMysql(self, request, context): print request.dbname return log_pb2.MysqlResponse(selectlist='1')def server(): server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) log_pb2.add_GreeterServicer_to_server(Greeter(), server) log_pb2.add_ConnMysqlServicer_to_server(ConnMysql(), server) server.add_insecure_port('127.0.0.1:15000') server.start() try: while True: time.sleep(_ONE_DAY_IN_SECONDS) except KeyboardInterrupt: server.stop(0)if __name__ == '__main__': server()
3)写client端
# coding:utf-8 import grpc import log_pb2_TIMEOUT_SECONDS = 10def run(): try: # with log_pb2.beta_create_Greeter_stub(,'127.0.0.1',15000) as stub : #response = stub.SayHello(log_pb2.HelloRequest(message='hello hugo',name='18'),_TIMEOUT_SECONDS) #print responsechannel = grpc.insecure_channel('127.0.0.1:15000') stub = log_pb2.GreeterStub(channel) response = stub.SayHello(log_pb2.HelloRequest(message='hugo000000', age=19), _TIMEOUT_SECONDS) conn_mysql_stub = log_pb2.ConnMysqlStub(channel) res = conn_mysql_stub.ConnectMysql(log_pb2.MyqlRequest(dbname='jiraconnector'), _TIMEOUT_SECONDS) print res print response.next() except Exception as e: print eif __name__ == '__main__': run()
4)结果
selectlist: "1"
message: "hello hugo"
age: 10
总结:简单易用,文档规范。
常见错误
<_Rendezvous of RPC that terminated with (StatusCode.UNIMPLEMENTED, Method not found!)> <_Rendezvous of RPC that terminated with (StatusCode.UNKNOWN, Exception calling application: 'int' object is not iterable) log.proto: Required fields are not allowed in proto3.
log.proto: Required fields are not allowed in proto3. reference :
http://maqiangthunder.github.io/2016/07/04/%E6%9D%82/gRPC/
https://github.com/geekan/grpc-python-demos/blob/master/helloworld/client.py
http://guojing.me/posts/grpc-python-bind-source-code-1/
【grpc实战示例】