天天看點

zeromq解決了什麼問題

很早就聽說了zeromq 這個項目,當時不太在意.

後來同僚kasicass 對這個項目做了研究和分享 ,開始重視起這個項目來.

再後來,就是看到這篇博文:<<zeromq:雲時代最好的通信庫 >>,下定決心也要看看這個傳說的神器.

最開始,考慮的問題是,zeromq和libevent,ACE這樣定位的項目有什麼差別沒有?

1) libevent封裝了對網絡I/O,信号,定時器等的處理,可以基于它之上做網絡層的開發.

2) ACE封裝了不同平台下的系統調用,也提供好幾種網絡程式設計的模型.

然而,zeromq不是libevent,也不是ACE,因為它的主要特性是:面向消息進行通信.是以,它提供的是比libevent,ACE處在網絡通 信中更高一層的元件.使用它,程式員不再需要上面提到的libevent,ACE之類的庫需要關心的東西,程式員如果要使用zeromq,隻需要做如下的 事情:

1) 告知所使用的patten,比如request-reply,pub-sub,push-pull等(下面會詳細解釋這個pattern).

2) 告知是用于機器之間,還是程序之間,線程之間的通信.

然後,将所需要發送的資料封裝到zeromq自帶的msg結構體中發送出去,使用者自己關心如何序列化/反序列化這些資料,然後如何處理這些資料就是使用者的事情了.

這樣看上來,使用者要關注的事情”高”了一層,大部分的精力都可以放在業務邏輯之上了.簡而言之,它讓使用者的精力放在了通信模式和業務邏輯上,而不是更下面一層的網絡層上.

下面解釋一下zeromq常用的幾種網絡pattern:

1) request-reply

就是一般的C/S架構中,client與server之間一問一答的通信模式,比如最經典的echo服務.需要注意的是,client發送一個request,server必須有一個回應.

這個pattern并不是什麼亮點,下面亮點來了.

2) publish-subscribe

server端作為publish端,而任何連接配接到服務端的client都會成為subscribe端.也就是說,server端會把目前的所有需要publish出去的消息全部發送到目前連接配接上去的client上.

3) push-pull

server端作為push端,而client端作為pull端.如果有多個client端同時連接配接到這個server,則伺服器會在内部做一個負載均衡,采用平均配置設定的算法,将所有的消息均衡釋出到client端上.

看上去,很稀松平常?接下來亮點真的來了.

2),3)兩種模式中,無論是server端還是client端在啟動時 都是不知道client實際數量的,這就意味着,一個使用zeromq搭建的服務,可以進行”熱更新”.

考慮如下一種場景.一個server端做為一組伺服器叢集最上層的一個proxy,起到負載均衡的作用,将請求按照它下面對應伺服器叢集依次派發到不同的 client端進行處理.某個時刻可能處理的機器隻有2台,而随着負載越來越大,可能需要3台機器了,這個時候如果使用zeromq的push-pull 搭建的proxy端,則可以不用對之前搭建的server,client端進行停機,隻需要新啟動一個client連接配接上去,proxy層就會自動根據當 前的機器配置設定平均派發任務了.cool.

實際上,這些模式并不是什麼新東西,隻不過zeromq為使用者做了一個封裝,而不是像libevent,ACE等還局限在網絡層部分的封裝,它關注的是通信層,通信模式等.

個人感覺,zeromq部分解決 了erlang所要解決的問題:在多台機器中通信,派發任務等,是分布式通信的利器,但是局限于語言的限制,它沒有辦法做的跟erlang一樣的完善(erlang已經可以算的上一個簡易微型的OS了),但是許多的時候,似乎隻使用這一部分功能也就足夠了.

zeromq的代碼量,截至到我目前閱讀的2.0.10-stable版本,也隻有不到2W行代碼.提供出去的API也極為簡單,但是内部的實作比 較”繞”,zeromq是我閱讀過的項目中少數的非常需要依賴調試工具跟進代碼才能看懂代碼流程的項目,同時代碼中類的繼承層次也比較多,閱讀起來并不像 它提供的API那樣簡單直白.後續會對其中的一些難點做一些分析.