您现在的位置是:Instagram刷粉絲, Ins買粉絲自助下單平台, Ins買贊網站可微信支付寶付款 > 

04 redis消息推送跟訂閱應用場景(大型的 PHP應用 通常使用什么應用做 消息隊列 的)

Instagram刷粉絲, Ins買粉絲自助下單平台, Ins買贊網站可微信支付寶付款2024-05-13 18:31:52【】0人已围观

简介跳或者等待response無法響應,最好通過一個任務池,和一組常駐協程,來消耗,處理結果,通過channel再傳回調用方。使用任務池還有額外的好處,可以對請求進行打包處理,提高吞吐量,并且可以加入控量

跳或者等待response無法響應,最好通過一個任務池,和一組常駐協程,來消耗,處理結果,通過channel再傳回調用方。使用任務池還有額外的好處,可以對請求進行打包處理,提高吞吐量,并且可以加入控量策略.

2.網絡環境不好引起激增

go協程相比較以往高并發程序,如果做不好流控,會引起協程數量激增。早期的時候也會發現,時不時有部分主機內存會遠遠大于其他服務器,但發現時候,所有主要profiling參數都正常了。

后來發現,通信較多系統中,網絡抖動阻塞是不可免的(即使是內網),對外不停accept接受新請求,但執行過程中,由于對內通信阻塞,大量協程被 創建,業務協程等待通信結果沒有釋放,往往瞬時會迎來協程暴漲。但這些內存在系統穩定后,virt和res都并沒能徹底釋放,下降后,維持高位。

處理這種情況,需要增加一些流控策略,流控策略可以選擇在rpc庫來做,或者上面說的任務池來做,其實我感覺放在任務池里做更合理些,畢竟rpc通信庫可以做讀寫數據的限流,但它并不清楚具體的限流策略,到底是重試還是日志還是緩存到指定隊列。任務池本身就是業務邏輯相關的,它清楚針對不同的接口需要的流控限制策略。

3.低效和開銷大的rpc框架

早期rpc通信框架比較簡單,對內通信時候使用的也是短連接。這本來短連接開銷和性能瓶頸超出我們預期,短連接io效率是低一些,但端口資源夠,本身吞吐可以滿足需要,用是沒問題的,很多分層的系統,也有買粉絲短連接對內進行請求的

但早期go版本,這樣寫程序,在一定量級情況,是支撐不住的。短連接大量臨時對象和臨時buffer創建,在本已經百萬協程的程序中,是無法承受的。所以后續我們對我們的rpc框架作了兩次調整。

第二版的rpc框架,使用了連接池,通過長連接對內進行通信(復用的資源包括client和server的:編解碼Buffer、Request/response),大大改善了性能。

但這種在一次request和response還是占用連接的,如果網絡狀況ok情況下,這不是問題,足夠滿足需要了,但試想一個room實例要與后面的數百個的register,買粉絲ordinator,saver,center,keeper實例進行通信,需要建立大量的常駐連接,每個目標機幾十個連接,也有數千個連接被占用。

非持續抖動時候(持續逗開多少無解),或者有延遲較高的請求時候,如果針對目標ip連接開少了,會有瞬時大量請求阻塞,連接無法得到充分利用。第三版增加了Pipeline操作,Pipeline會帶來一些額外的開銷,利用tcp的全雙特性,以盡量少的連接完成對各個服務集群的rpc調用。

4.Gc時間過長

改善方式,一種是多實例的拆分,如果公司沒有端口限制,可以很快部署大量實例,減少gc時長,最直接方法。不過對于360來說,外網通常只能使用80和433。因此常規上只能開啟兩個實例。當然很多人給我建議能否使用SO_REUSEPORT,不過我們內核版本確實比較低,并沒有實踐過。

另外能否模仿nginx,fork多個進程監控同樣端口,至少我們目前沒有這樣做,主要對于我們目前進程管理上,還是獨立的運行的,對外監聽不同端口程序,還有配套的內部通信和管理端口,實例管理和升級上要做調整。

解決gc的另兩個手段,是內存池和對象池,不過最好做仔細評估和測試,內存池、對象池使用,也需要對于代碼可讀性與整體效率進行權衡。

上圖左邊的數組實際上是一個列表,這個列表按大小將內存分塊,然后使用atomic操作進行CAS。但實際要看測試數據了,池技術可以明顯減少臨時對象和內存的申請和釋放,gc時間會減少,但加鎖帶來的并行度的降低,是否能給一段時間內的整體吞吐量帶來提升,要做測試和權衡…

但對于rpc庫或者買粉絲dec庫,任務池內部,這些開定量協程,集中處理數據的區域,可以嘗試改造~

對于有些固定對象復用,比如固定的心跳包什么的,可以考慮使用全局一些對象,進行復用,針對應用層數據,具體設計對象池,在部分環節去復用,可能比這種無差別的設計一個通用池更能進行效果評估.

消息系統的運維及測試

下面介紹消息系統的架構迭代和一些迭代經驗,由于之前在其他地方有過分享,后面的會給出相關鏈接,下面實際做個簡單介紹,感興趣可以去鏈接里面看

架構迭代~根據業務和集群的拆分,能解決部分灰度部署上線測試,減少點對點通信和廣播通信不同產品的相互影響,針對特定的功能做獨立的優化.

消息系統架構和集群拆分,最基本的是拆分多實例,其次是按照業務類型對資源占用情況分類,按用戶接入網絡和對idc布點要求分類(目前沒有條件,所有的產品都部署到全部idc)

系統的測試go語言在并發測試上有獨特優勢。

對于壓力測試,目前主要針對指定的服務器,選定線上空閑的服務器做長連接壓測。然后結合可視化,分析壓測過程中的系統狀態。但壓測早期用的比較多,但實現的統計報表功能和我理想有一定差距。我覺得最近出的golang開源產品都符合這種場景,go寫網絡并發程序給大家帶來的便利,讓大家把以往為了降低復雜度,拆解或者分層協作的組件,又組合在了一起。

Q&A

Q1:協議棧大小,超時時間定制原則?

移動網絡下超時時間按產品需求通常2g,3G情況下是5分鐘,wifi情況下5~8分鐘。但對于個別場景,要求響應非常迅速的場景,如果連接idle超過1分鐘,都會有ping,pong,來校驗是否斷線檢測,盡快做到重新連接。

Q2:消息是否持久化?

消息持久化,通常是先存后發,存儲用的redis,但落地用的mysql。mysql只做故障恢復使用。

Q3:消息風暴怎么解決的?

如果是發送情況下,普通產品是不需要限速的,對于較大產品是有發送隊列做控速度,按人數,按秒進行控速度發放,發送成功再發送下一條。

Q4:golang的工具鏈支持怎么樣?我自己寫過一些小程序千把行之內,確實很不錯,但不知道代碼量上去之后,配套的debug工具和profiling工具如何,我看上邊有分享說golang自帶的profiling工具還不錯,那debug呢怎么樣呢,官方一直沒有出debug工具,gdb支持也不完善,不知你們用的什么?

是這樣的,我們正常就是println,我感覺基本上可以定位我所有問題,但也不排除由于并行性通過println無法復現的問題,目前來看只能靠經驗了。只要常見并發嘗試,經過分析是可以找到的。go很快會推出調試工具的~

Q5:協議棧是基于tcp嗎?

是否有協議拓展功能?協議棧是tcp,整個系統tcp長連接,沒有考慮擴展其功能~如果有好的經驗,可以分享~

Q6:問個問題,這個系統是接收上行數據的吧,系統接收上行數據后是轉發給相應系統做處理么,是怎么轉發呢,如果需要給客戶端返回調用結果又是怎么處理呢?

系統上行數據是根據協議頭進行轉發,協議頭里面標記了產品和轉發類型,在買粉絲ordinator里面跟進產品和轉發類型,回調用戶,如果用戶需要阻塞等待回復才能后續操作,那通過再發送消息,路由回用戶。因為整個系統是全異步的。

Q7:問個pushsdk的問題。pushsdk的單連接,多app復用方式,這樣的情況下以下幾個問題是如何解決的:1)系統流量統計會把所有流量都算到啟動連接的應用吧?而啟動應用的連接是不固定的吧?2)同一個pushsdk在不同的應用中的版本號可能不一樣,這樣暴露出來的接口可能有版本問題,如果用單連接模式怎么解決?

流量只能算在啟動的app上了,但一般這種安裝率很高的app承擔可能性大,常用app本身被檢測和殺死可能性較少,另外消息下發量是有嚴格控制 的。整體上用戶還是省電和省流量的。我們pushsdk盡量向上兼容,出于這個目的,push sdk本身做的工作非常有限,抽象出來一些常見的功能,純推的系統,客戶端策略目前做的很少,也有這個原因。

Q8:生產系統的profiling是一直打開的么?

不是一直打開,每個集群都有采樣,但需要開啟哪個可以后臺控制。這個profling是通過接口調用。

Q9:面前系統中的消息消費者可不可以分組?類似于Kafka。

客戶端可以訂閱不同產品的消息,接受不同的分組。接入的時候進行bind或者unbind操作

Q10:為什么放棄erlang,而選擇go,有什么特別原因嗎?我們現在用的erlang?

erlang沒有問題,原因是我們上線后,其他團隊才做出來,經過qa一個部門對比測試,在沒有顯著性能提升下,選擇繼續使用go版本的push,作為公司基礎服務。

Q11:流控問題有排查過網卡配置導致的idle問題嗎?

流控是業務級別的流控,我們上線前對于內網的極限通信量做了測試,后續將請求在rpc庫內,控制在小于內部通信開銷的上限以下.在到達上限前作流控。

Q12:服務的協調調度為什么選擇zk有考慮過raft實現嗎?golang的raft實現很多啊,比如Consul和ectd之類的。

3年前,還沒有后兩者或者后兩者沒聽過應該。zk當時公司內部成熟方案,不過目前來看,我們不準備用zk作結合系統的定制開發,準備用自己寫的keeper代替zk,完成配置文件自動轉數據結構,數據結構自動同步指定進程,同時里面可以完成很多自定義的發現和控制策略,客戶端包含keeper的sdk就可以實現以上的所有監控數據,profling數據收集,配置文件更新,啟動關閉等回調。完全抽象成語keeper通信sdk,keeper之間考慮用raft。

Q13:負載策略是否同時在服務側與CLIENT側同時做的 (DISPATCHER 會返回一組IP)?另外,ROOM SERVER/REGISTER SERVER連接狀態的一致性|可用性如何保證? 服務側保活有無特別關注的地方? 安全性方面是基于TLS再加上應用層加密?

會在server端做,比如重啟操作前,會下發指令類型消息,讓客戶端進行主動行為。部分消息使用了加密策略,自定義的rsa+des,另外滿足我們安全公司的需要,也定制開發很多安全加密策略。一致性是通過冷備解決的,早期考慮雙寫,但實時狀態雙寫同步代價太高而且容易有臟數據,比如register掛了,調用所有room,通過重新刷入指定register來解決。

Q14:這個keeper有開源打算嗎?

還在寫,如果沒耦合我們系統太多功能,一定會開源的,主要這意味著,我們所有的bind在sdk的庫也需要開源~

Q15:比較好奇lisence是哪個如果開源?

很赞哦!(9598)

Instagram刷粉絲, Ins買粉絲自助下單平台, Ins買贊網站可微信支付寶付款的名片

职业:程序员,设计师

现居:陕西商洛商州区

工作室:小组

Email:[email protected]