RabbitMq連接池化設計


概述

為何要池化RabbitMq的連接?這就涉及到了兩個基本的RabbitMq概念:ConnectionChannel

Connection

Connection對象,就是一個TCP連接對象。

Channel

虛擬連接。虛擬連接建立在上面Connection對象的TCP連接中。數據流動都是在Channel中進行的。每個Connection對象的虛擬連接也是有限的,如果單個Connnection的Channel對象超出指定范圍了,也會有性能問題,另外一個TCP連接上的多個虛擬連接,實際在傳輸數據時,傳輸數據的虛擬連接還是獨占了TCP連接,其它虛擬連接在排隊等待。

池化設計

參考線程池、DB連接池的設計,同樣抽象一個池化對象來管理Connection以及Channel兩個對象,回收復用連接。

實現落地

ObjectPool實現

其實是基於微軟官方實現的池擴展庫來做的,描述請見 ObjectPool對象池設計模式

具體實現見 Publishing RabbitMQ Message In ASP.NET Core

代碼請見 https://github.com/anehir/PooledRabbitClient

 

ABP中的IConnectionPool

在ABP的Volo.Abp.RabbitMQ庫中也實現了IConnection以及IChannel兩者的池化管理。

 

 

在ABP中,通過一個簡單的並發字典來緩存已有的RabbitMq連接,如果連接有的話,就直接返回否則就創建。

GetOrAdd方法並不是線程安全的,但如果是基於lazy來實現則是線程安全。

var lazyConnection = Connections.GetOrAdd(

connectionName, () => new Lazy<IConnection>(() =>

{

var connection = Options.Connections.GetOrDefault(connectionName);

var hostnames = connection.HostName.TrimEnd(';').Split(';');

// Handle Rabbit MQ Cluster.

return hostnames.Length == 1 ? connection.CreateConnection() : connection.CreateConnection(hostnames);

 

})

);

return lazyConnection.Value;
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM