異步不是萬能的,實作異步重要的手段,消息隊列在使用中也是有很多注意事項的。
消息隊列至少有三處容易出現瓶頸,我們一經典的釋出/訂閱模式為例。分析一下都可能存在哪些瓶頸。
釋出 ---> 隊列 ---> 訂閱
入隊瓶頸,釋出消息隊列,處理太慢,釋出端堵塞應用程式。
隊列持久化瓶頸,隊列持久化是需要寫入磁盤的,大量的密集io操作
出隊瓶頸,(茶壺煮餃子,有嘴倒不出)出隊瓶頸還包括訂閱端的處理能力,
如果訂閱端的處理能力跟不上,也會出現瓶頸。
消息大小,每個消息包的大小也決定了性能
釋出端問題表現在入隊速度影響了釋出端應用程式的性能,例如
上面僞代碼 publish()将阻塞 task3()與task4(),必須等待publish()執行完成才能繼續運作。
這樣的情況是 釋出數量 > 入隊的速度, 影響釋出端的性能
消息的持久化,既影響入隊速度,也影響出對速度,入隊是寫磁盤操作,出對是修改或者删除操作。 在隊列同時進行入隊與出隊的操作是,還涉及到各種“鎖”,例如線程鎖與檔案鎖等等。 最終結果是消息隊列性能驟降。
訂閱端的處理能力也影響到隊列的堆積程度。如果訂閱端處理速度過慢,我們就會發現消息在隊列中堆積。
訂閱端改進,将隊列交給線程處理
我們應該盡量減小消息的體積,例如選擇輕量的協定,超過一定體積做壓縮處理。
就消息協定而言, 二進制協定 < 文本協定。而文本協定中 json < xml 等等。
xml 成對出現的閉合标簽占用了大量的空間,二進制的 msgpack 也好于文本的 json。 選擇使用那種協定還要看你的場景。
另外還需要注意的就是 序列化/反序列化的開銷。
我們要盡量做到釋出,隊列與訂閱之間的平衡,才能發揮消息隊列的優勢。
作者
轉載請注明出處與作者聲明