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 MySQLdb
class 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 e
class 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 = 10
def 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 response
channel = 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 e
if __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.
<!--?xml version="1.0" encoding="UTF-8" standalone="no"?-->
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/