網(wǎng)絡(luò)編程,這一塊目前應(yīng)用最廣,包括Web應(yīng)用、API應(yīng)用、下載應(yīng)用、
成都網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)公司!專注于網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開(kāi)發(fā)、微信小程序開(kāi)發(fā)、集團(tuán)成都企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。核心團(tuán)隊(duì)均擁有互聯(lián)網(wǎng)行業(yè)多年經(jīng)驗(yàn),服務(wù)眾多知名企業(yè)客戶;涵蓋的客戶類型包括:輕質(zhì)隔墻板等眾多領(lǐng)域,積累了大量豐富的經(jīng)驗(yàn),同時(shí)也獲得了客戶的一致稱揚(yáng)!
內(nèi)存數(shù)據(jù)庫(kù),前一段時(shí)間google開(kāi)發(fā)的groupcache,couchbase的部分組建
云平臺(tái),目前國(guó)外很多云平臺(tái)在采用Go開(kāi)發(fā),CloudFoundy的部分組建,前VMare的技術(shù)總監(jiān)自己出來(lái)搞的apcera云平臺(tái)。
3、Go成功的項(xiàng)目
nsq:bitly開(kāi)源的消息隊(duì)列系統(tǒng),性能非常高,目前他們每天處理數(shù)十億條的消息
docker:基于lxc的一個(gè)虛擬打包工具,能夠?qū)崿F(xiàn)PAAS平臺(tái)的組建。這就是已經(jīng)有記錄的,go語(yǔ)言能夠做什么的統(tǒng)計(jì),希望能幫到你
重點(diǎn)提示:
這樣我們就啟動(dòng)了一個(gè) nsqd 的實(shí)例
編寫(xiě)一個(gè)消息生產(chǎn)者
nsq_single_product.go
編寫(xiě)一個(gè)消息消費(fèi)者
nsq_single_consumer.go
添加第一個(gè)實(shí)例
添加第二個(gè)實(shí)例
消息生產(chǎn)者
nsq_cluster_product.go
消息消費(fèi)者
nsq_cluster_consumer.go
golangchannel和mq的區(qū)別
我是一個(gè)著迷于產(chǎn)品和運(yùn)營(yíng)的技術(shù)人,樂(lè)于跨界的終身學(xué)習(xí)者。歡迎關(guān)注我喲~
每周五12點(diǎn) 按時(shí)送達(dá)~
我的第「218」篇原創(chuàng)敬上
大家好,我是Z哥。
最近在項(xiàng)目中遇到了一個(gè)使用 RabbitMQ 時(shí)的問(wèn)題,這個(gè)問(wèn)題我覺(jué)得還是有一定普適性的,和大家分享一下,避免大家后續(xù)在同一個(gè)問(wèn)題上犯錯(cuò)。
消息隊(duì)列(MQ)是在軟件開(kāi)發(fā)中很常用的中間件,如果一個(gè)程序需要協(xié)調(diào)另一個(gè)程序進(jìn)行數(shù)據(jù)的“write”操作,并且不關(guān)心“write”的結(jié)果,則便會(huì)選擇它。它是一個(gè)保存消息(數(shù)據(jù))的容器,由它來(lái)確保消息一定被送達(dá)到目標(biāo)程序。
打個(gè)比喻來(lái)說(shuō),消息隊(duì)列就是一個(gè)郵差,它負(fù)責(zé)將信件(消息)從源頭送往目的地,并且根據(jù)信件重要性的不同,提供當(dāng)面簽收確認(rèn)或者直接投放兩種服務(wù)。
RabbitMQ 就是一個(gè)典型的消息隊(duì)列,以 AMQP 為標(biāo)準(zhǔn)。歷史也比較悠久,大概是從 2007年研發(fā)出來(lái)的,用的編程語(yǔ)言Erlang也同樣具有年代感。
需要簡(jiǎn)單介紹一下 Erlang 的特點(diǎn),它對(duì)我們理解 RabbitMQ 有很大的幫助。
Erlang 是一種運(yùn)行于“虛擬機(jī)”(類似 JVM)的解釋性語(yǔ)言。是一個(gè)結(jié)構(gòu)化,動(dòng)態(tài)類型編程語(yǔ)言,內(nèi)建并行計(jì)算支持。使用 Erlang 編寫(xiě)出的應(yīng)用運(yùn)行時(shí)通常由成千上萬(wàn)個(gè)輕量級(jí)“進(jìn)程”(并非傳統(tǒng)意義上的進(jìn)程)組成,并通過(guò)消息傳遞相互通訊。進(jìn)程間上下文切換對(duì)于 Erlang 來(lái)說(shuō)僅僅 只是一兩個(gè)環(huán)節(jié),比起 C 程序的線程切換要高效得多得多了。
——整理于百度百科的資料
不管是什么 MQ 中間件,作為消息的生產(chǎn)方和消費(fèi)方都需要和 MQ 的服務(wù)端建立連接進(jìn)行通訊。
?
一般這個(gè)連接都會(huì)使用 TCP 協(xié)議,在 RabbitMQ 里也不例外。大多數(shù) RabbitMQ 的 SDK 都會(huì)將連接封裝為一個(gè)「Connection」對(duì)象。
還沒(méi)完,大多數(shù)的 MQ 中間件還會(huì)在「Connection」的基礎(chǔ)上增加一個(gè)「Channel」的概念,以通過(guò)復(fù)用的方式提高 TCP 連接的利用率,因?yàn)榻⒑弯N毀 TCP 連接是非常昂貴的開(kāi)銷。在 RabbitMQ 中的復(fù)用 TCP 連接方式是「Non-blocking I/O」的模式。
關(guān)于NIO,「Non-blocking I/O」的概念,有感興趣的話可以跳轉(zhuǎn)去看之前寫(xiě)的這篇文章。(用最通俗的話講明白阻塞/非阻塞/異步/同步,到底啥區(qū)別?)
?
多說(shuō)一句,任何方案都不是“銀彈”。當(dāng)每個(gè) Channel 的流量不是很大時(shí),復(fù)用單一的 Connection 可以在產(chǎn)生性能瓶頸的情況下有效地節(jié)省 TCP 連接資源。但是 Channel 本身的流量很大時(shí),這時(shí)候多個(gè) Channel 復(fù)用一個(gè) Connection 就會(huì)產(chǎn)生性能瓶頸,進(jìn)而使整體的流量被限制了。此時(shí)就需要開(kāi)辟多個(gè) Connection,將這些 Channel 均攤到這些 Connection 中,至于哪些 Channel 使用那個(gè) Connection 以及Connection 與 Channel 之間的數(shù)量關(guān)系是多少,需要根據(jù)業(yè)務(wù)自身的實(shí)際情況進(jìn)行調(diào)節(jié)。
Channel 在 AMQP 中是一個(gè)很重要的概念,大多數(shù)操作都是在信道這個(gè)層面展開(kāi)的。比如, channel.exchangeDeclare、channel.queueDeclare、channel.basicPublish、channel.basicConsume 等方法。RabbitMQ 相關(guān)的 API 與 AMQP 緊密相連,比如 channel.basicPublish 對(duì)應(yīng) AMQP 的 Basic.Publish 命令。
可能你要問(wèn)了,Channel 是不是也能像 Connection 一樣被復(fù)用?這是個(gè)好問(wèn)題,也是我們這次遇到問(wèn)題的關(guān)鍵點(diǎn)。
結(jié)論是:可以,但是需要自己保證客戶端對(duì) Channel 訪問(wèn)的線程安全問(wèn)題,因?yàn)樵?Channel 的另一端,在 RabbitMQ 的服務(wù)端,每個(gè) Channel 由一個(gè)單獨(dú)的“進(jìn)程”所管理,如果由于多線程復(fù)用Channel 導(dǎo)致數(shù)據(jù)幀亂序了,RabbitMQ 的服務(wù)端會(huì)主動(dòng)關(guān)閉整個(gè) Connection 。
因此,我們這次犯的錯(cuò)誤就是多線程復(fù)用了同一個(gè) Channel 導(dǎo)致的問(wèn)題。所以,如果你也用到 streadway/amqp 這個(gè)庫(kù)的話,需要特別注意這點(diǎn)。
不過(guò),不同語(yǔ)言的SDK內(nèi)部實(shí)現(xiàn)不同,我們分別使用 Golang 的 AMQP 庫(kù) streadway/amqp,和 RabbitMQ 官方提供的 C# 版本的庫(kù)分別模擬過(guò)同樣的場(chǎng)景,前者出現(xiàn)問(wèn)題,后者卻沒(méi)有問(wèn)題。
受限于時(shí)間原因,沒(méi)有具體去核實(shí) C# 庫(kù)的源碼,主觀猜測(cè)是 C# 庫(kù)內(nèi)部多做了一些對(duì)于單個(gè) Channel 的線程安全處理。
最后,我整理了三點(diǎn)使用 streadway/amqp 庫(kù)的最佳實(shí)踐,你可以看看:
01
golang 中使用 streadway/amqp 時(shí),需要保證每一個(gè)線程單獨(dú)一個(gè) Channel。
streadway/amqp 庫(kù)中的獲取一個(gè) Channel 的方法「Connection.channel()」是線程安全的。但是內(nèi)部有一個(gè) defaultChannelMax 的參數(shù)對(duì) Channel 的數(shù)量進(jìn)行了限制,默認(rèn)是 (2 10) - 1,2047。這個(gè)需要注意:
?
02
我們可以通過(guò)調(diào)用 amqp.DialConfig(url string, config Config) 來(lái)調(diào)整個(gè)限制。
?
但是,并不是你調(diào)整了多少就是多少,還需要和 RabbitMQ 服務(wù)端的配置進(jìn)行 min() 函數(shù)的處理,最終為兩者的最小值。
Tips:特別是用云廠商的 MQ 產(chǎn)品,因?yàn)殡A梯收費(fèi)的原因會(huì)對(duì)很多性能參數(shù)做限制,需要格外關(guān)注這點(diǎn),比如某版本的阿里云 RabbitMQ 實(shí)例限制是單個(gè) Connection 最多 64 個(gè) Channel)
03
正如前面對(duì) Erlang 的簡(jiǎn)單介紹,Erlang 是一個(gè)天然支持多“進(jìn)程”設(shè)計(jì)的語(yǔ)言,所以在 RabbitMQ 的服務(wù)端設(shè)計(jì)中,每一個(gè) Queue,每一個(gè) Connection 都是單獨(dú)的一個(gè)“進(jìn)程”。因此如果你想盡可能地壓榨 RabbitMQ 性能,可以通過(guò)建立更多的 Connection 或者創(chuàng)建更多的 Queue 來(lái)實(shí)現(xiàn),當(dāng)然需要注意到 Connection 的創(chuàng)建和銷毀的性能開(kāi)銷問(wèn)題。
推薦閱讀:
減少聯(lián)調(diào)、高效集成,試試這個(gè)工具
golang使用3周總結(jié)
也可以「關(guān)注」我,帶你以技術(shù)思維看世界~
想更進(jìn)一步和我一起玩耍,歡迎「搜索微信公號(hào):跨界架構(gòu)師」。
內(nèi)容包括:架構(gòu)設(shè)計(jì)丨分布式系統(tǒng)丨產(chǎn)品丨運(yùn)營(yíng)丨個(gè)人深度思考。
很多朋友可能知道Go語(yǔ)言的優(yōu)勢(shì)在哪,卻不知道Go語(yǔ)言適合用于哪些地方。
1、 Go語(yǔ)言作為服務(wù)器編程語(yǔ)言,很適合處理日志、數(shù)據(jù)打包、虛擬機(jī)處理、文件系統(tǒng)、分布式系統(tǒng)、數(shù)據(jù)庫(kù)代理等;網(wǎng)絡(luò)編程方面。Go語(yǔ)言廣泛應(yīng)用于Web應(yīng)用、API應(yīng)用、下載應(yīng)用等;除此之外,Go語(yǔ)言還可用于內(nèi)存數(shù)據(jù)庫(kù)和云平臺(tái)領(lǐng)域,目前國(guó)外很多云平臺(tái)都是采用Go開(kāi)發(fā)。
2、 其實(shí)Go語(yǔ)言主要用作服務(wù)器端開(kāi)發(fā)。其定位是用來(lái)開(kāi)發(fā)"大型軟件"的,適合于很多程序員一起開(kāi)發(fā)大型軟件,并且開(kāi)發(fā)周期長(zhǎng),支持云計(jì)算的網(wǎng)絡(luò)服務(wù)。Go語(yǔ)言能夠讓程序員快速開(kāi)發(fā),并且在軟件不斷的增長(zhǎng)過(guò)程中,它能讓程序員更容易地進(jìn)行維護(hù)和修改。它融合了傳統(tǒng)編譯型語(yǔ)言的高效性和腳本語(yǔ)言的易用性和富于表達(dá)性。
3、 Go語(yǔ)言成功案例。Nsq:Nsq是由Go語(yǔ)言開(kāi)發(fā)的高性能、高可用消息隊(duì)列系統(tǒng),性能非常高,每天能處理數(shù)十億條的消息;
4、 Docker:基于lxc的一個(gè)虛擬打包工具,能夠?qū)崿F(xiàn)PAAS平臺(tái)的組建。
5、 Packer:用來(lái)生成不同平臺(tái)的鏡像文件,例如VM、vbox、AWS等,作者是vagrant的作者
6、 Skynet:分布式調(diào)度框架。
7、 Doozer:分布式同步工具,類似ZooKeeper。
8、 Heka:mazila開(kāi)源的日志處理系統(tǒng)。
9、 Cbfs:couchbase開(kāi)源的分布式文件系統(tǒng)。
10、 Tsuru:開(kāi)源的PAAS平臺(tái),和SAE實(shí)現(xiàn)的功能一模一樣。
11、 Groupcache:memcahe作者寫(xiě)的用于Google下載系統(tǒng)的緩存系統(tǒng)。
12、 God:類似redis的緩存系統(tǒng),但是支持分布式和擴(kuò)展性。
13、 Gor:網(wǎng)絡(luò)流量抓包和重放工具。
以上的就是關(guān)于go語(yǔ)言能做什么的內(nèi)容介紹了。
Go 語(yǔ)言被設(shè)計(jì)成一門(mén)應(yīng)用于搭載 Web 服務(wù)器,存儲(chǔ)集群或類似用途的巨型中央服務(wù)器的系統(tǒng)編程語(yǔ)言。對(duì)于高性能分布式系統(tǒng)領(lǐng)域而言,Go 語(yǔ)言無(wú)疑比大多數(shù)其它語(yǔ)言有著更高的開(kāi)發(fā)效率。學(xué)習(xí)Go語(yǔ)言,可以說(shuō)是很簡(jiǎn)單的,入門(mén)快,想學(xué)習(xí)Go語(yǔ)言,可以到黑馬程序員看看,有新出的教程。
1、服務(wù)器編程:以前你如果使用C或者C++做的那些事情,用Go來(lái)做很合適,例如處理日志、數(shù)據(jù)打包、虛擬機(jī)處理、文件系統(tǒng)等。
2、分布式系統(tǒng)、數(shù)據(jù)庫(kù)代理器、中間件:例如Etcd。
3、網(wǎng)絡(luò)編程:這一塊目前應(yīng)用最廣,包括Web應(yīng)用、API應(yīng)用、下載應(yīng)用,而且Go內(nèi)置的net/http包基本上把我們平常用到的網(wǎng)絡(luò)功能都實(shí)現(xiàn)了。
4、開(kāi)發(fā)云平臺(tái):目前國(guó)外很多云平臺(tái)在采用Go開(kāi)發(fā),我們所熟知的七牛云、華為云等等都有使用Go進(jìn)行開(kāi)發(fā)并且開(kāi)源的成型的產(chǎn)品。
5、區(qū)塊鏈:目前有一種說(shuō)法,技術(shù)從業(yè)人員把Go語(yǔ)言稱作為區(qū)塊鏈行業(yè)的開(kāi)發(fā)語(yǔ)言。如果大家學(xué)習(xí)區(qū)塊鏈技術(shù)的話,就會(huì)發(fā)現(xiàn)現(xiàn)在有很多很多的區(qū)塊鏈的系統(tǒng)和應(yīng)用都是采用Go進(jìn)行開(kāi)發(fā)的,比如ehtereum是目前知名度最大的公鏈,再比如fabric是目前最知名的聯(lián)盟鏈,兩者都有g(shù)o語(yǔ)言的版本,且go-ehtereum還是以太坊官方推薦的版本。
自1.0版發(fā)布以來(lái),go語(yǔ)言引起了眾多開(kāi)發(fā)者的關(guān)注,并得到了廣泛的應(yīng)用。go語(yǔ)言簡(jiǎn)單、高效、并發(fā)的特點(diǎn)吸引了許多傳統(tǒng)的語(yǔ)言開(kāi)發(fā)人員,其數(shù)量也在不斷增加。
使用 Go 語(yǔ)言開(kāi)發(fā)的開(kāi)源項(xiàng)目非常多。早期的 Go 語(yǔ)言開(kāi)源項(xiàng)目只是通過(guò) Go 語(yǔ)言與傳統(tǒng)項(xiàng)目進(jìn)行C語(yǔ)言庫(kù)綁定實(shí)現(xiàn),例如 Qt、Sqlite 等。
后期的很多項(xiàng)目都使用 Go 語(yǔ)言進(jìn)行重新原生實(shí)現(xiàn),這個(gè)過(guò)程相對(duì)于其他語(yǔ)言要簡(jiǎn)單一些,這也促成了大量使用 Go 語(yǔ)言原生開(kāi)發(fā)項(xiàng)目的出現(xiàn)。
本文題目:go語(yǔ)言消息隊(duì)列編程 go語(yǔ)言開(kāi)發(fā)分布式任務(wù)調(diào)度
分享鏈接:http://sd-ha.com/article48/doosoep.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站制作、軟件開(kāi)發(fā)、網(wǎng)站導(dǎo)航、服務(wù)器托管、外貿(mào)建站、微信小程序
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
網(wǎng)頁(yè)設(shè)計(jì)公司知識(shí)