1. 程式人生 > >微服務之協議概述

微服務之協議概述

核心 原型 -type mat 標記 win eve 分隔符 cap

微服務協議

互聯網協議很多,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, 成對的 {} 或 []. 二進制格式中一般會在包頭指定長度, 以便分割, 例如 SMTP 和 HTTP 協議,

$ curl https://tools.ietf.org/rfc/rfc768.txt -vvv

*   Trying 4.31.198.61...
* TCP_NODELAY set
* Connected to tools.ietf.org (4.31.198.61) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
* Server certificate: *.tools.ietf.org
* Server certificate: Starfield Secure Certificate Authority - G2
* Server certificate: Starfield Root Certificate Authority - G2
> GET /rfc/rfc768.txt HTTP/1.1
> Host: tools.ietf.org
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Sun, 20 May 2018 02:29:29 GMT
< Server: Apache/2.2.22 (Debian)
< Last-Modified: Thu, 15 Oct 1992 21:56:01 GMT
< ETag: "108828d-1708-28e1893a75e40"
< Accept-Ranges: bytes
< Content-Length: 5896
< Vary: Accept-Encoding
< Strict-Transport-Security: max-age=3600
< X-Frame-Options: SAMEORIGIN
< X-Xss-Protection: 1; mode=block
< X-Content-Type-Options: nosniff
< X-Clacks-Overhead: GNU Terry Pratchett
< Content-Type: text/plain; charset=UTF-8
<


RFC 768                                                        J. Postel
...

UDP 本身就是以數據包為單位的, 一個一個包收就好了, 不過一般在包中會承載序號信息, 以便對丟包或亂序進行處理, 之後我們來詳細分析下文本協議的代表 HTTP, 以及二進制協議的代表 RTP

協議分析

協議標準理解

分析協議的第一步是閱讀相應的協議標準 RFC(Request for Comments), 互聯網的核心是 TCP/IP 協議簇

  • Internet Protocol (IP) -- RFC 791(https://tools.ietf.org/rfc/rfc791.txt)
    就OSI模型而言,IP是網絡層協議。 它在應用程序之間提供數據報服務,支持TCP和UDP

packet header + payload 是基本格式,

IP packet 的包頭為20個字節, IP 包頭中包含 IP源地址, 目的地址, TTL 存活時間 (所經過路由器的跳數)

上層協議不必關心下層協議, 但是是知道IP是3層協議, 2層所使用的數據鏈路協議如果是以太網, 以最大傳輸單元(MTU)為 1500 字節, 如果你的包的長度超過這個長度, 網絡設備會將這個IP數據包分片傳輸, 劃分成多個 IP packet

  • Transmission Control Protocol (TCP) - RFC 793(https://tools.ietf.org/rfc/rfc793.txt)
    TCP是一種傳輸層協議。 它在應用程序之間提供可靠的虛擬電路連接; 即在數據傳輸開始之前建立連接。 數據發送時沒有錯誤或重復,並且按照發送的順序接收數據。 沒有對數據施加任何界限; TCP將數據視為一個字節流。

TCP 包頭中包含源端口, 目的端口, 序列號, 確認號, 類型標記, 窗口大小, 校驗和等.
TCP是一個很復雜和強大的協議

  • User Datagram Protocol (UDP) - RFC 768(https://tools.ietf.org/rfc/rfc768.txt)
    UDP也是一種傳輸層協議,是TCP的一種替代方案。 它在應用程序之間提供了不可靠的數據報連接。 數據通過鏈路傳輸; 沒有端到端的連接。 該服務不提供任何擔保。 數據可能丟失或重復,數據報可能無序到達。

UDP 包頭包含源端口, 目的端口, 內容長度, 校驗和, 它非常簡單, 所以你可以發現基於它之上的眾多協議會建立許多類似於TCP的序號, 標記等機制

協議包分析

第二步就是抓包, 最常用的是 tcpdump 和 wireshark, 通常在服務器端用 tcpdump 抓完包後, 用 wireshark 打開抓包文件 *. pcap 進行詳細分析

這裏還推薦一個 python 工具 scapy , 它是一個功能強大的基於Python的交互式數據包操作程序和庫。
可以從 https://github.com/secdev/scapy 下載, 或者直接用 pip 安裝

pip install scapy
pip install matplotlib
pip install pyx

它能夠偽造或解碼大量協議的數據包,在線上發送它們,捕獲它們,使用pcap文件存儲或讀取它們,匹配請求和回復等等。 它旨在通過使用默認值來實現快速數據包原型設計。

簡單用它來看來 IP 和 TCP 的包頭

$ scapy

>>> pkt =IP(ttl=10, dst="192.168.1.1")/TCP(flags="SF")
>>> pkt.summary()
‘IP / TCP 10.79.102.90:ftp_data > 192.168.1.1:http FS‘
>>> pkt.show()
###[ IP ]###
  version= 4
  ihl= None
  tos= 0x0
  len= None
  id= 1
  flags=
  frag= 0
  ttl= 10
  proto= tcp
  chksum= None
  src= 10.79.102.90
  dst= 192.168.1.1
  \options###[ TCP ]###
     sport= ftp_data
     dport= http
     seq= 0
     ack= 0
     dataofs= None
     reserved= 0
     flags= FS
     window= 8192
     chksum= None
     urgptr= 0
     options= {}



微服務之協議概述