随着企业的发展,我们的服务架构也变得庞大、复杂,在不同内部功能模块之间像调用函数一样进行数据通信,架构演变成微服务架构是一个不错的解决方案。
微服务这种分布式的架构如何实现不同服务、不同编程语言、不同进程之间的简单、高效通信?
微服务除了基于HTTP协议进行API、消息队列进行数据交互,也可以统一使用gRPC协议的Protobuf数据格式进行更加简单、高效的数据交互。
使用RPC协议和HTTP协议实现微服务的数据交互区别是什么?如何完成Golang、Python...数据交互?
什么是RPC?
RPC是Remote Procedure Call的缩写,就是像调用本地函数一样调用远程服务器上运行程序的函数,并返回调用结果。
说起来很简单做起来难,把原来本地的函数放到另一台服务器上去进行远程调用,会面临以下几大问题。
Call的id映射:服务端提供了很多可调用服务就跟Django的视图函数,如何保证客户端发送远程调用时可以区别不同可调用服务、并可以返回结果是关键。
序列化和反序列化:数据进行序列化/反序列化的速度,和二进制数据的大小会影响网络传输速度。
网络传输:既然远程调用肯定要通过网络协议进行传输,是采用TCP还HTTP网络传输协议呢?
RPC框架的组成
一个基本RPC框架由4部分组成,分别是:客户端、客户端存根、服务端、服务端存根
客户端(Client):服务调用的发起方,也称为消费者。
客户端存根(ClientStub):
该程序运行在客户端所在的计算机上,主要用来存储 要调用服务器地址,对客户端发送的数据进行序列化、建立网络连接之后发送数据包给Server端的存根程序。
接收Server端存根程序响应的消息,对消息进行反序列化。
服务端(Server):提供客户端想要调用的函数
服务端存根(ServerStub):接收客户端的消息并反序列化,对server端响应的消息进行序列化并响应给Client端
总体来讲客户端和服务端的Stub在底层帮助我们实现了Call ID的映射、数据的序列化和反序列化、网络传输
这样RPC客户端和RPC服务端 只需要专注于服务端和客户端的业务逻辑层。
RPC和HTTP的区别?
RPC是一种解决客户端和服务端之间数据通信的方案
HTTP协议可以实现RPC即在服务端和客户端之间完成远程过程调用,但是HTTP仅仅是实现RPC的方式之一并非唯一方式。
从传输性能角度来说HTTP协议并不是实现RPC的最优方案
但是从客户端兼容性角度来说支持HTTP协议的客户端非常广泛,尤其是浏览器天然支持HTTP协议,HTTP客户端的开发成本也比较低。
import json from http.server import HTTPServer, BaseHTTPRequestHandler from urllib.parse import urlparse, parse_qsl host = ("", 8003) class AddHandler(BaseHTTPRequestHandler): def do_GET(self): # 获取当前访问URL current_url = urlparse(self.path) # 获取URL携带的参数 query_args = dict(parse_qsl(current_url.query)) print(query_args) arg1, arg2 = int(query_args.get("arg1", 1)), int(query_args.get("arg2", 1)) self.send_response(200) self.send_header("content-type", "application/json") self.end_headers() self.wfile.write(json.dumps({"result":arg1 + arg2},ensure_ascii=False).encode("utf-8")) if __name__ == '__main__': server = HTTPServer(host, AddHandler) print("启动服务器") server.serve_forever()