浅谈 Socket.D 与响应式编程
一、Socket.D 的主要特性
首先,Scoket.D 是高效一個二進制的網絡通訊協議(官方我講法是:基于事件和語義消息流的網絡應用協議),能夠滿足很多場景下使用。其次,Scoket.D 是溫和的響應式(采用回調風格)。
1、三種通訊模式
- send 只是發送(發送后不管了)
發送一個請求,無需為這個請求發送答復報文。適用于監控埋點,日志上報等,這種場景下無需回執,丟失幾個請求無傷大雅。
- sendAndRequest(發送并請求,要求一個“答復”)
發送一條請求消息,響應方收到后發回一個答復消息。傳統的 HTTP 就是典型的 sendAndRequest。
- sendAndSubscribe(發送并訂閱,可接收N個“答復”)
發送一個訂閱消息,響應方收到后發回N個答復報文。傳統的 MQ 是典型的 sendAndSubscribe。
2、雙向監聽雙向會話
Server 可以監聽 Client 發來的消息;Client 也可以監聽 Server 發來的消息。形成的 Session,更是可以相互對發消息。
3、其它
- 二進制協議,緊湊高效
- 有語議、有事件
- 多路復用
- 靈活的傳輸層切換: TCP/UDP/WebSocket等
- 支持自動分等高級特性
4、與其它協議對比
感觀上像是各協議的優點提純。簡單且強大,非常有未來感!
| 對比項目 | socket.d | http | websocket | rsocket | socket.io |
|---|---|---|---|---|---|
| 發消息(Qos0) | 有 | 無 | 有 | 有 | 有 |
| 發送并請求(Qos1) | 有 | 有 | 無 | 有 | 無 |
| 發送并訂閱 | 有 | 無 | 無 | 有 | 無 |
| 答復或響應 | 有 | 有 | 無 | 有 | 無 |
| 單連接雙向通訊 | 有 | 無 | 有(不便) | 有 | 有(不便) |
| 數據分片 | 有 | / | 無 | 有 | 有 |
| 斷線自動重連 | 有 | / | 無 | 有 | 有 |
| 有元信息 | 有 | 有 | 無 | 有 | 無 |
| 有事件(或路徑) | 有 | 有 | 無 | 無 | 有 |
| 有流(或消息關聯性) | 有 | 無 | 無 | 有 | 無 |
| Broker 模式集群 | 有 | 無 | 無 | 有 | 無 |
| 異步 | 異步 | 同步 | 異步 | 異步 | 異步 |
| 接口體驗 | 經典 | 經典 | 經典 | 響應式(復雜) | 經典 |
| 基礎傳輸協議 | tcp, udp, ws | tcp | http | tcp, udp, ws | ws |
二、Socket.D 的內部實現
1、幀的設計
socket.d 是以幀為單位進行傳輸。大的幀還會自動分片成小幀進行傳輸(超過 16MB 自動分裂重組,大小可配置),到達接收端后再自動聚合。
- 幀的邏輯結構
frame: {flag, message: {sid, event, entity: { metaString, data}}}
幀的數據邏輯結構:幀里有標志和消息;消息里有流標識、事件、實體;實體里有元信息字符串和數據。
- 完整的標準幀碼
[len:int][flag:int][sid:str(<64)][\n][event:str(<512)][\n][metaString:str(<4k)][\n][data:byte(<16m)]
| 字段 | 類型 | 大小 | 說明 |
|---|---|---|---|
| len | int | 4字節 | 幀長度(包括它自己的 4字節占位) |
| flag | int | 4字節 | 標志(相當于協議指令) |
| sid | String | 64字節以內 | 流標識。格式為: guid
|
| event | String | 512字節以內 | 事件。格式為:可見字符 string
|
| metaString | String | 4Kb以內 | 元信息字符串。格式為:通用的 uri queryString
|
| data | byte[] | 16Mb以內 | 數據。格式為: byte[]
|
注意:當使用 udp 傳輸時,幀長度不能超過 2k (聽說,實際不能超過 1.4k )
- 簡化的輔助幀碼(Ping, Pong, Close),取消了 message 部分
[len:int][flag:int]
2、數據實體——Entity
基于幀之上,一般開發者接觸到的是 Entity, 它類似一個HTTP報文,可以是一個Request,也可以是一個Response。由兩個部分組成:
- MetaString 元信息字符串,類似 HTTP 的 header。格式:字符串
- Data 數據,類似 HTTP 的 body。格式:二進制
3、玩法
Socket.D 有很多玩法,傳統的 RPC 自然不在話下,用來做 IM 也未嘗不可,開發 MQ 也很簡單(FolkMQ 就是用它開發的)。某些特性也可以用來做代理或者網絡穿透。
IoT的場景,比如小明的家里有個智能空調,小明想在外面通過手機 APP 來控制空調開關,如何優雅地描述這個控制問題?最精煉的解決方案就是"小明調用空調上開關的API"。
另外最經典的玩法就是Broker了,Broker類似一種“軟路由”的方案,可以讓服務的發布訪問變得簡單。發布服務只要連接到Broker,調用方通過反向請求的方式來讓Broker透明轉發即可,摒棄了傳統的注冊中心,端口管理等常見的服務治理手段。
4、關于 Socket.D Broker
Broker 有很多優勢,發布服務不需要監聽端口,無需 Sidecar,服務注冊變得簡單,無需 zk、etcd 之類,LoadBalance 變得簡單,也更安全,沒監聽端口后很難攻擊。也有很多劣勢,網絡上多了一跳,性能是有一定損耗的,Broker 是中心化設計,類似我們平時全局的 Nginx 一樣,但是 Broker 的優雅啟停顯然更加復雜,受限于整個 Broker 集群的瓶頸等等。上帝為你關閉了一扇門,就一定會為你打開一扇窗。
三、響應式編程,難嗎?
響應式編程是個老話題了,它早已無處不在,甚至你在Excel里SUM求和,本質上也是種響應式的思維。響應式本質上就是響應變化的數據流。Socket.D 這個協議本身就是以響應式之名,將其擴展到網絡層面。
但是,響應式接口對一般程序員,不太友好。Socket.D 是響應式,但采用"經典的回調界面"。
四、總結
Socket.D 是個很有趣的網絡協議,未來應該會普及流行。它解決問題的思路和設計很令人耳目一新。如果大家有興趣,可以去它的官網了解下。
總結
以上是生活随笔為你收集整理的浅谈 Socket.D 与响应式编程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 推荐给前端开发的 5 款 Chrome
- 下一篇: Java五种设计模式实现奶茶订单生成系统