استفاده از چند Hostname در RabbitMQ در حالت Cluster
یکی از کتابخانه هایی که برای انتقال پیام بین سیستم های مختلف وجود دارد، Rabbitmq هست.
یکی از قابلیت های مفید این Message Broker قابلیت Clustering هست که در زمان هایی که یکی از سرورهای شما دچار مشکل میشود، میتواند این بصورت خودکار پیام ها را به یک سرور دیگر ارسال کند.
برای اینکه در سمت فرستنده پیام، چند Host را برای ارسال پیام معرفی کنید، میتوانید بصورت زیر عمل کنید:
var factory = new ConnectionFactory
{
//HostName = hostNames.First(),
UserName = username,
Password = password,
Port = port,
AutomaticRecoveryEnabled = automaticRecoveryEnabled
};
var endpoints = hostNames
.Select(item => new AmqpTcpEndpoint(new Uri(item)))
.ToList();
var connection = factory.CreateConnection(endpoints);
_channel = connection.CreateModel();
_properties = _channel.CreateBasicProperties();
تفاوت کد بالا با حالتی که فقط یک هاست دارید، در خط کامنت شده و endpoints میباشد.
در حالتی که فقط یک هاست دارید میتوانید آن را در قسمت کامنت شده معرفی کنید، اما در زمانهایی که تعداد آنها بیشتر است باید آنها را در CreateConnection معرفی کنید.
این کلاس دارای Constructor های مختلفی است که یکی از آنها یک List
بطور مثال اگر هاست های شما بصورت زیر باشد:
private static List<string> Hosts = new()
{
"192.168.99.100:30000",
"192.168.99.100:30002",
"192.168.99.100:30004"
};
در صورتی که همین لیست را به کلاس گفته شده پاس بدهید با خطا مواجه میشوید و حتما باید آن را بصورت AmqpTcpEndpoint
دربیاورید.
البته اگر از آدرسها بصورت uri
استفاده میکنید، حتما http را قبل از آدرس ها قرار دهید.
private static List<string> Hosts = new()
{
"http://192.168.99.100:30000",
"https://192.168.99.100:30002"
};
اگر ورودی ها را بصورت زیر قرار بدهید، در مرحله تبدیل به AmqpTcpEndpoint با مشکل مواجه میشوید و مقدار خالی به عنوان آدرس که به معنی localhost
است قرار داده میشود:
private static List<string> Hosts = new()
{
"s-mysystem-t1:30000",
"s-mysystem-t2:30002"
};
اگر ورودیها بصورت بالا باشد خروجی endpoints بصورت زیر میشود که اشتباه است:
amqp://:30000
amqp://:30002
راه دیگر استفاده از کد زیر است که هردو حالت ip و نام سیستم را پشتیبانی میکند:
var hostNames = new List<string>();
var hosts = "my-r1:5672,my-r2:5672,192.168.1.1:5066";
if (hosts.Contains(","))
{
hostNames.AddRange(hosts.Split(','));
}
else
{
hostNames.Add(hosts);
}
var endpoints = new List<AmqpTcpEndpoint>();
foreach (var hostName in hostNames)
{
var temp = hostName.Split(':');
var url = temp[0];
var port = Convert.ToInt32(temp[1]);
endpoints.Add(new AmqpTcpEndpoint(url, port));
}
var connection = factory.CreateConnection(endpoints);
همچنین برای بهبود عملکرد میتوانید در کانفیگ مقدار AutomaticRecoveryEnabled
را برابر True
قرار بدهید.
اطلاعات بیشتر:
قوانین آدرس ها در ربیت:
url