文章目录
要解决的问题:分布式环境下的服务器间服务调用
在微服务架构,服务器更多,而且服务器能随时扩展,如何解决服务器之间服务调用?
目前使用普遍的通讯方式:HTTP RESTful
通过 GET、POST等 /api/user/:id/orders 进行获取数据,然后对数据进行解码(json、xml)等处理再返回给用户,传递的数据同样也是 json 或 xml 编码协议。
在分布式环境下的缺陷
传统架构,接口不多、系统与系统交互较少的情况下。用RESTful通讯简单、直接、开发方便。
但在分布式环境下,子系统多、接口多、服务还随时可能扩展。在这样的环境下RESTful就有问题了:
- 要知道服务端的 ip:port
- 服务间走 http 开销太大。
tcp短链接要一直3次握手4次挥手
http 要传递的无用的元数据太多(header 等),再一个就是 http 协议本身比较慢。 - 另外还有一个原因就是 xml 和 json 的编码解码速度效率不算高
RPC
引入服务注册中心,
用更有效的连接方式(长连接、http2…),
更快的序列化方式(protobuf…)
来实现服务之间的通讯
把这些功能尽量封装起来 弄成通用的stup桩代码,让调用双方无感、开发方便简单
演变过程
https://www.bilibili.com/video/BV17Z4y1s7cG?t=1331
- 原始方式
客户端 网络传输 对象的属性值,
服务端 获取属性值 创建对象 - 客户端 封装网络传输方法
只需要关注方法服务实现,不要写网络传输 - 客户端 用动态代理封装
客户端 动态传输 【方法名,方法参数类型,方法参数】
服务端 根据 【方法名,方法参数类型,方法参数】,执行方法,返回结果 - 实现对同一个接口,所有方法的调用支持
- 引入 服务注册中心
RPC(Remote Procedure Call)远程过程调用
RPC 只是一种概念、一种设计,不是协议也不是框架
客户端存根(User Stub) 与 服务端存根(Server Stub):屏蔽了底层 通讯与序列化 的细节
就是为了解决 不同服务之间的调用问题, 它一般会包含有 传输协议 和 序列化协议 这两个。
传输协议
TCP
传输效率高,但是开发难度相对较高
提供方定义socket端口和提供的方法名称
调用方通过连接服务方的socket端口,将需要通信的数据作为参数传递进而调用相关方法,
在调用端进行序列化, 然后在提供端进行反序列化
HTTP
与现在的restful风格很类似,主要是在服务调用方通过标识请求,GET,POST然后通过url来定位到服务提供方提供的服务,数据通过xml或者json来传输,省去了TCP的序列化和反序列化
HTTP2
gRPC就是基于http2
序列化协议
常见的有使用Java本身内置的序列化方式、Hession、JSON、XML等。
proto
https://blog.csdn.net/xyc1211/article/details/121244969
https://blog.csdn.net/xyc1211/article/details/125181616
实现框架
- RMI(JDK自带)
- 阿里的 Dubbo
- Google 的 gRPC
- Hessian
- Apache(Facebook)的 Thrift