随着企业 IT 服务的不断发展,单台服务器逐渐没法承受用户日益增加的请求压力时,就须要多台服务器联合起来构成「服务集群」共同对外提供服务。python
同时业务服务会随着产品需求的增多愈来愈肿,架构上必须进行服务拆分,一个完整的大型服务会被打散成不少不少独立的小服务,每一个小服务会由独立的进程去管理来对外提供服务,这就是「微服务」。
nginx
当用户的请求到来时,咱们须要将用户的请求分散到多个服务去各自处理,而后又须要将这些子服务的结果汇总起来呈现给用户。那么服务之间该使用何种方式进行交互就是须要解决的核心问题。web
RPC 就是为解决服务之间信息交互而发明和存在的。编程
RPC(Remote Procedure Call)——远程过程调用,它是一种经过网络从远程计算机程序上请求服务,而不须要了解底层网络技术的协议。后端
RPC采用客户机/服务器模式。请求程序就是一个客户机,而服务提供程序就是一个服务器。服务器
首先,客户机调用进程发送一个有进程参数的调用信息到服务进程,而后等待应答信息。网络
在服务器端,进程保持睡眠状态直到调用信息到达为止。架构
当一个调用信息到达,服务器得到进程参数,计算结果,发送答复信息负载均衡
而后等待下一个调用信息,最后,客户端调用进程接收答复信息,得到进程结果,而后调用执行继续进行。框架
RPC就是一种远程调用函数接口的方式,说白了,就是一种远程调用函数接口的方式,客户端和服务端之间约定一种契约(函数接口),而后服务端一直等待客户端的调用。
有点像日常的WEB网络请求。
一种用途是在多台服务器之间互相进行调用。
另外一个用途则在于,不一样编程语言之间都支持这种方式,像Python更是内置对其的支持,不须要额外安装什么库,因此能够直接在多语言的服务器之间互相进行调用。
Socket编程就是RPC通讯
这二者的关系比如
要进行跨企业服务调用时,每每都是经过 HTTP API,也就是普通话,虽然效率不高,可是通用,没有太多沟通的学习成本。
可是在企业内部仍是 RPC 更加高效,同一个企业公用一套方言进行高效率的交流,要比通用的 HTTP 协议来交流更加节省资源。
中国各地都有本身方言,你回了老家仍是流行说方言
本质上,普通话也是一种方言,只不过是官方的方言,使用的最普遍的方言。
Ngnix 是互联网企业使用最为普遍的代理服务器。
它能够为后端分布式服务提供负载均衡的功能,它能够将后端多个服务地址聚合为单个地址来对外提供服务。
如图,Django 是 Python 技术栈最流行的 Web 框架。
你可能会问,python web部署不是用的uwsgi吗,是的,也能够走uwsgi协议
,它是比HTTP协议更省流量的二进制协议。
uwsgi 通信协议在 Python 语言体系里使用很是广泛,若是一个企业内部使用 Python 语言栈搭建 Web 服务,那么他们在生产环境部署 Python 应用的时候不是在使用 HTTP 协议就是在使用 uwsgi 协议来和 Nginx 之间创建通信。
RPC是两个子系统之间进行的直接消息交互,使用操做系统提供的套接字做为消息的载体
python的socket编程就是一种RPC通讯
rpc_server.py
import socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind(("localhost", 8080)) sock.listen(1) # 监听客户端链接 while True: conn, addr = sock.accept() # 接收一个客户端链接 print(conn.recv(1024)) # 从接收缓冲读消息 recv buffer conn.sendall(b"world") # 将响应发送到发送缓冲 send buffer conn.close() # 关闭链接
rpc_client.py
import socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(("localhost", 8080)) # 链接服务器 sock.sendall(b"hello") # 将消息输出到发送缓冲 send buffer print(sock.recv(1024)) # 从接收缓冲 recv buffer 中读响应 sock.close() # 关闭套接字...
简单的服务端
像web请求同样,咱们须要肯定供客户端访问的url和端口号,以及供客户端调用的方法实现,最后要让咱们服务器一直处于等待被访问的状态:
from xmlrpc.server import SimpleXMLRPCServer # 调用函数 def respon_string(str): return "get string:%s"%str if __name__ == '__main__': server = SimpleXMLRPCServer(('localhost', 8888)) # 初始化 server.register_function(respon_string, "get_string") # 注册函数 print ("Listening for Client") server.serve_forever() # 保持等待调用状态
能够看到,代码中就实现了上面说的几点。
register_function用于注册一个供调用的函数
,第一个参数为本身实现的方法名
,第二个参数为供客户端调用的方法名
。
简单的客户端
根据url和端口号初始化一个服务器对象,而后调用须要的方法便可:
from xmlrpc.client import ServerProxy if __name__ == '__main__': server = ServerProxy("http://localhost:8888") # 初始化服务器 print (server.get_string("oldboy_python6666")) # 调用函数并传参
分别启动服务端和客户端,客户端便可远程调用服务端的功能函数