日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

goim 中的 data flow 数据流转及思考

發布時間:2025/3/17 编程问答 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 goim 中的 data flow 数据流转及思考 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

goim 文章系列(共5篇):

  • goim 架構與定制
  • 從goim定制, 淺談 golang 的 interface 解耦合與gRPC
  • goim中的 bilibili/discovery (eureka)基本概念及應用
  • goim 的 data flow 數據流
  • goim的業務集成(分享會小結與QA)

有個 slack 頻道, 不少朋友在交流 goim , 歡迎加入slack #goim

[簡述] goim.io 是 非常成功的 IM (Instance Message) 即時消息平臺 , 本文介紹 goim 中的數據定義與 data flow 數據流轉

1. goim 中的 data flow 數據流轉

1.1 架構中的數據流轉

看圖

數據流轉

  • http 接口向 logic 發送數據
  • logic 從 redis 中獲取會話數據, 以 protobuf 序列化數據, 發送到 MQ
  • job 從 MQ 中訂閱數據, 取出 im 發送數據中的 server / room 向指定 server 的 comet 發送數據
  • comet 接收 job 分發的數據后, 存入 指定 channel 的 ring buffer , 再轉為 tcp/websocket 數據包, 發送到指定 channel 的客戶端
  • 1.2 簡化后的數據流轉細節

    上示意圖標注了 goim 中的關鍵數據結構:

  • 標注了 im 發送數據構成, 注意, 這個數據結構是被logic 以 protobuf 序列化后發到 MQ , 并在 job 中反序列化后, 分發到 comet
  • 這里的會話信息, 主要是 mid --> server 與 room-->server 的對應關系, 存在 redis 中
  • comet 中的 im 信息, 由 job 從 MQ 中反序列化后, 取出 server / room / keys( 一到多個key , 對應 channel ) 發送到指定 comet server
  • comet 以 tcp / websocket 封裝數據包, 發送給終端用戶, 終端解包后顯示
  • 2. goim 中的數據定義

    2.1. logic 發送 im 信息

    發布 im 信息定義( 在 protobuf 中的定義)

    message PushMsg {enum Type {PUSH = 0;ROOM = 1;BROADCAST = 2;}Type type = 1;int32 operation = 2;int32 speed = 3;string server = 4;string room = 5;repeated string keys = 6;bytes msg = 7; } 復制代碼

    2.2 會話數據

    當 tcp client 或 websocket client 連接 comet server 時, comet 以 gRPC 向 logic 進行內部通訊, 生成會話數據, 存在 redis 中, 具體細節不展開, 看代碼

    當 http client 向 logic 發送 im 消息時, logic 向 redis 查詢會話數據, 對于已經存在的 room--> server / mid ( memberID) --> server 即發送消息到 MQ , 該部分代碼比較清楚, 也不再加說明

    2.3. tcp / websocket 數據包定義

    推送 im 信息, 對象名稱為 proto, 在 protobuf 中定義

    message Proto {int32 ver = 1 [(gogoproto.jsontag) = "ver"];int32 op = 2 [(gogoproto.jsontag) = "op"];int32 seq = 3 [(gogoproto.jsontag) = "seq"];bytes body = 4 [(gogoproto.jsontag) = "body"]; } 復制代碼

    protobuf 文件 github.com/Terry-Mao/g… 中第12行

    tcp / websocket 數據包組包/折包操作在 /api/comet/grpc/protocol.go

    由上圖可見, goim 在 tcp /websocket 數據包的數據包定義, 與 go 中 proto 定義, 多了, 數據包總長度 / 包頭長度兩個字段

    3. comet 中的處理

    簡化數據流轉, 從發送端數據到 接收端數據, 可以看到, serverID / roomID / channel ( 用 mid 或 key 來指示) 的主要作用作為分流/分發用, 在最后推送數據包中, 就不在包含這三個字段了.

    同時, comet 中使用了 ring buffer 來緩存一個 channel 送達的多條信息并推送到終端, 這里, 并沒有看到對推送下發的信息作更多處理.

    _

    _


    看代碼, 補充細節

    // Channel used by message pusher send msg to write goroutine. type Channel struct {c *conf.CometConfigRoom *RoomCliProto Ringsignal chan *grpc.ProtoWriter xbufio.WriterReader xbufio.ReaderNext *ChannelPrev *ChannelMid int64 // ######### memberID Key stringIP stringwatchOps map[int32]struct{}mutex sync.RWMutex } 復制代碼

    這里:

  • mid 就是 memberID , 當前 channel ( 用戶端與 comet 的長連接) 是哪個用戶連接上的 該長連接使用 key 作為長連接的會話標識, 換個方式說, key 也就標定了一個 im 信息要發給哪個/哪幾個在線長連接對端的用戶
  • key 就是長連接的會話ID, 可以這么理解, 就算是 sessionID 吧
  • watchOps 是一個map 映射表, 其中的 int32 是房間號. map 多個房間號, map 結構是用來查詢房間號是否在 map 中存在或不存在. watchOps 是當前長連接用戶用來監聽當前客戶端接收哪個房間的 im 消息推送, 換個方式說, 一個 goim 終端可以接收多個房間發送來的 im 消息
  • watchOps 初始化是在 tcp / websocket 客戶端進行首次連接時處理的, 細節看代碼.

  • _

    _

    從 logic 自 http 的 post 請求中, 獲取發布 im 信息后, 序列化發到 MQ, 在 job 中拆包反序列化, 再組包, 這一步驟對性能是否有影響, 需發測試數據來定位, 但個人感覺, 這幾次拆包組包, 有點重復.

    4. 小結

    以上, 應開源社區的朋友要求, 對內部數據結構作了一個簡化分析, 花時不多,水平有限, 或有考慮不周或分析不當, 歡迎批評指點.

    最后, goim.io 在網絡上相關文章不少, 好文不少, 給我啟迪, 一并感謝.

    推薦以下文章:

    • alexstocks.github.io/html/im.htm… 作者 AlexStcks, 非常棒的文章, 集思踐行, 很有深度
    • github.com/LinkinStars… 作者: LinkinStars, 這個值得一看
    • moonshining.github.io/2018/03/09/… 寫得很細致

    再一次, 感謝 www.bilibili.com 的開源 & 毛劍 及眾多開源社區的前輩們,朋友們

    _

    關于我

    網名 tsingson (三明智, 江湖人稱3爺)

    原 ustarcom IPTV/OTT 事業部播控產品線技術架構濕/解決方案工程濕角色(8年), 自由職業者,

    喜歡音樂(口琴,是第三/四/五屆廣東國際口琴嘉年華的主策劃人之一), 攝影與越野,

    喜歡 golang 語言 (商用項目中主要用 postgres + golang )

    _

    _ tsingson 寫于中國深圳 小羅號口琴音樂中心, 2019/05/07

    轉載于:https://juejin.im/post/5cd12fa16fb9a0320b40ec32

    總結

    以上是生活随笔為你收集整理的goim 中的 data flow 数据流转及思考的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。