微服务之协议篇

151 阅读3分钟

微服务协议

互联网协议很多,TCP IP 是基础协议,在它之上有众多应用层协议,这里关注的微服务以什么协议向外提供服务, 即以什么方式, 或者说以什么手段, 通过什么媒介来提供面向用户或者其他服务提供他们所需要的服务。传统的单体服务对外一般提供RPC (远程方法调用)的接口, 对内的组件之间通过方法调用或者线程/进程间通信就行了.

而微服务一般所提供的服务都是节点与节点之间的远程分布式调用, 基于流式的TCP 连接或基于数据包的UDP 连接

协议都是分层的, OSI的七层网络模型中, 我们关心的是传输层以上的协议

协议分类

按照它所针对的语义可以分为

面向资源

比如 REST, 主要是对于资源的存取和修改

面向命令

比如SOAP, RMI,RPC , 主要是指对于方法, 命令及过程的远程调用

面向事件

比如 XMPP, JMS,AMQP, 主要是对于消息的传递和转发

按照远程调用协议的编码可以分为

文本协议

例如 HTTP + JSON/XML, SIP

二进制协议

例如 WebSocket + BSon/Protobuf

按照协议的用途可以分为

信令及控制协议

例如 SIP, SDP, Jingle, ROAP

媒体传输协议

例如 HTTP, RTP, RTMP

安全相关协议

例如 TLS, DTLS, oAuth2

按交互方式分类

基本上是 Request 请求/ Response 响应 方式, 这其中的响应有所区别, 主要就是看是不是最终响应

请求/搞定

client->server: POST /calls
server-->client: 201 created

或者

client->server: send request PDU
server-->client: send response PDU

请求/收到

这时候, 一般客户端只是收到一个接受的响应, 最终结果需要客户端轮询和给一个回调的地址

client->server: POST /orders (including callbackUrl)
server-->client: 202 accepted
client->server: GET /orders/tasks/taskid
server->client: 200 OK (state: doing)
server->client: POST /callbackurl
client->server: 200 OK (state:finished)

如果是基于长连接的协议, 比如 WebSocket, 应用层的TCP协议包, 这种方式用得最多

client->server: send PDU(request)
server-->client: reply PDU(ack)
server->client: send PDU (result)
server->client: reply PDU (ack)

请求/协商/确认

典型的 SIP 会话搭建流程

client->server: SIP Invite
server-->client: SIP 200 OK
server->client: SIP Ack

Pub/sub 发布/订阅

image.png

client1->broker: subscribe
broker->client1: ok
client2->broker: publish event
broker-->client2: ok
broker->client1: event
client1-->broker: ok

按数据传输格式分类

任何一个服务会使用一个协议栈, 从下到上采用相应的协议, 上层服务应用协议所使用的数据传输格式很多,但无非表示为文本和二进制格式

HTTP 是互联网的最主要的协议, 也是微服务中最流行的协议, 在它之上, 又有 RPC (Remote Procedure Call 远程过程调用) 和 REST (Representational state transfer 表述性状态转移) 两种风格. 前者多使用 HTTP + XML(SOAP), 后者多使用 HTTP + JSON(REST)

WebSocket + Protobuf 也是一个比较流行的做法, 发挥了长连接双向通讯的优势, 并且编解码速度比较快

文本格式

常用的有

  • 键值对
  • Json
  • Xml

二进制格式

常用的有

  • Proto buffer
  • BSON
  • Thrift
  • PDU

基于 TCP 的流式传输, 在数据包之间必需有易于识别的分隔符, 文本格式中用得最多的就是 \r\n, 或者类似于 xml/json 之类明显的成对 tag, {} 或 []. 二进制格式中一般会在包头指定长度, 以便分割

UDP 本身就是以数据包为单位的, 一个一个包收就好了, 不过一般在包中会承载序号信息, 以便对丢包或乱序进行处理