Azure 服务总线 - 减少往返时间
Azure Service Bus - Lowering round trip time
我们正在检查 Azure 服务总线以将其用作我们的本地服务总线。我们正在测试往返时间,它似乎在 10 毫秒到 2000 毫秒之间波动。平均约为 100-200 毫秒。预热时间似乎从 2 秒开始下降到 200 毫秒,负载更高。
有什么方法可以缩短平均往返时间?
使用高级层有帮助吗?
-->(编辑:没有帮助。对于 1 个消息单元,平均水平实际上更差于高级层)
我们的设置:
- 消费者 (PC#1)
生产者(PC#2)(注意:这两台电脑在同一个局域网)
Azure 服务总线(实际上在 azure 上)
Side note/fun 事实:距离微软数据中心 1500 公里。光速使用约 10 毫秒的往返时间。
测试 1:
- 消息数:每分钟 1000 条
- 最大并发呼叫数:1
- 操作:接收并删除消息
- 预取计数:0
- 开始平均。 1-2秒
- 结束平均。 100-200 毫秒
- 输出:Pastebin link
示例输出:
20; 2017-12-07T11:41:48.5134157+01:00; 2017-12-07T11:41:48.7781795+01:00; 264,7638
3; 2017-12-07T11:41:47.4827021+01:00; 2017-12-07T11:41:48.8378167+01:00; 1355,1146
14; 2017-12-07T11:41:48.1491488+01:00; 2017-12-07T11:41:48.8950421+01:00; 745,8933
0; 2017-12-07T11:41:47.2250519+01:00; 2017-12-07T11:41:48.9518713+01:00; 1726,8194
测试 2:
- 消息数:每分钟 1000 条
- 最大并发呼叫数:1000
- 操作:接收并删除消息
- 预取计数:0
- 开始平均。 1-2秒
- 结束平均。 100-200 毫秒(注意:尖峰长达 20 秒)
- 输出:Pastebin link
示例输出:
4; 2017-12-07T11:43:43.5735023+01:00; 2017-12-07T11:43:44.7905668+01:00; 1217,0645
8; 2017-12-07T11:43:43.8166842+01:00; 2017-12-07T11:43:44.8424773+01:00; 1025,7931
11; 2017-12-07T11:43:43.9990189+01:00; 2017-12-07T11:43:44.8989094+01:00; 899,8905
10; 2017-12-07T11:43:43.9383692+01:00; 2017-12-07T11:43:44.9553891+01:00; 1017,0199
测试 3:
- 消息数:每分钟 1000 条
- 最大并发呼叫数:1000
- 操作:接收并删除消息
- 预取计数:1000
- 开始平均。 1-2s(预热明显减少)
- 结束平均。 ~100 毫秒(注意:尖峰最长 4.5 秒,尖峰明显减少)
- 输出:Pastebin link
示例输出:
11; 2017-12-07T11:54:16.8149682+01:00; 2017-12-07T11:54:17.6029464+01:00; 787,9782
14; 2017-12-07T11:54:16.9967915+01:00; 2017-12-07T11:54:17.6709669+01:00; 674,1754
0; 2017-12-07T11:54:16.0599312+01:00; 2017-12-07T11:54:17.6720080+01:00; 1612,0768
15; 2017-12-07T11:54:17.0578415+01:00; 2017-12-07T11:54:17.6724941+01:00; 614,6526
===========================
客户:
using System;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.ServiceBus;
namespace Sticos.ServiceBus.Client
{
public class ServiceBusClient
{
private readonly string _connectionstring;
private readonly string _topic;
private readonly TopicClient _topicClient;
public ServiceBusClient(string connectionstring, string topic)
{
_connectionstring = connectionstring ?? throw new ArgumentNullException(nameof(connectionstring));
_topic = topic ?? throw new ArgumentNullException(nameof(topic));
_topicClient = new TopicClient(_connectionstring, _topic);
}
public async Task SendAsync(string message)
{
await _topicClient.SendAsync(
new Message()
{
Body = Encoding.UTF8.GetBytes(message + ";" + DateTime.Now.ToString())
});
}
}
}
制作人:
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Sticos.ServiceBus.Client.Test
{
[TestClass]
public class ServiceBusClientTest
{
[TestMethod]
public void Producer()
{
var serviceBus = new ServiceBusClient("[connectionstring]", "[topic]");
var producer = Task.Factory.StartNew(() =>
{
var tasks = new Task[1000];
for (int i = 0; i < 1000; i++)
{
tasks[i] = serviceBus.SendAsync($"{i};{DateTime.Now.ToString("o")}");
Thread.Sleep(60);
}
Task.WaitAll(tasks);
});
Task.WaitAll(producer);
}
}
}
高级服务总线层提供一致的性能,因为您的命名空间将拥有不受嘈杂邻居干扰的专用资源。在标准层上,性能会根据服务的总体负载而波动,因为您的 queues/topics 与其他客户的 queues/topics 共享资源。
关于消息从生产者到达消费者所花费的时间,我可以告诉您,服务总线中没有延迟或其他设置会引入延迟。服务总线尽可能快地传递消息。我真的不能谈论或帮助网络传输速度。
但我认为提高接收消息的吞吐量也会降低消息到达消费者的平均时间。顺便说一句,您没有在此处粘贴消费者代码。我建议您尝试一些改进。批量发送确实有助于提高性能。不是每次发送调用都发送一条消息,而是根据消息大小分批发送 10 或 100 条。同样在接收器上,如果 PEEKLOCK/COMPLETE 模式对您来说不那么重要,请尝试使用 RECEIVEANDDELETE 模式。使用过多的并发调用意味着使用过多的线程。尝试调整最大并发调用和预取计数值,看看吞吐量如何变化。
另外,AMQP 提供了比 NetMessaging 或 Http 更好的性能。检查正在使用的协议的客户端配置并将其更改为 AMQP。
正如其他答案所建议的那样,更多的连接肯定会提高吞吐量。只需使用更多的发送者和更多的接收者。
因此,如果您在本地使用服务总线,则可以完成一些操作。例如,您可以部署到离您自己的数据中心最近的 Azure 区域。
您可以检查从 DC 到 Azure DC 的往返时间并进行延迟测量。
您可以评估的另一件事是使用快速路由来最大程度地减少延迟。
您介意提出支持请求吗?我们可以查看后端,看看我们是否可以在该上下文中进一步帮助您。
我们正在检查 Azure 服务总线以将其用作我们的本地服务总线。我们正在测试往返时间,它似乎在 10 毫秒到 2000 毫秒之间波动。平均约为 100-200 毫秒。预热时间似乎从 2 秒开始下降到 200 毫秒,负载更高。
有什么方法可以缩短平均往返时间?
使用高级层有帮助吗? -->(编辑:没有帮助。对于 1 个消息单元,平均水平实际上更差于高级层)
我们的设置:
- 消费者 (PC#1)
生产者(PC#2)(注意:这两台电脑在同一个局域网)
Azure 服务总线(实际上在 azure 上)
Side note/fun 事实:距离微软数据中心 1500 公里。光速使用约 10 毫秒的往返时间。
测试 1:
- 消息数:每分钟 1000 条
- 最大并发呼叫数:1
- 操作:接收并删除消息
- 预取计数:0
- 开始平均。 1-2秒
- 结束平均。 100-200 毫秒
- 输出:Pastebin link
示例输出:
20; 2017-12-07T11:41:48.5134157+01:00; 2017-12-07T11:41:48.7781795+01:00; 264,7638
3; 2017-12-07T11:41:47.4827021+01:00; 2017-12-07T11:41:48.8378167+01:00; 1355,1146
14; 2017-12-07T11:41:48.1491488+01:00; 2017-12-07T11:41:48.8950421+01:00; 745,8933
0; 2017-12-07T11:41:47.2250519+01:00; 2017-12-07T11:41:48.9518713+01:00; 1726,8194
测试 2:
- 消息数:每分钟 1000 条
- 最大并发呼叫数:1000
- 操作:接收并删除消息
- 预取计数:0
- 开始平均。 1-2秒
- 结束平均。 100-200 毫秒(注意:尖峰长达 20 秒)
- 输出:Pastebin link
示例输出:
4; 2017-12-07T11:43:43.5735023+01:00; 2017-12-07T11:43:44.7905668+01:00; 1217,0645
8; 2017-12-07T11:43:43.8166842+01:00; 2017-12-07T11:43:44.8424773+01:00; 1025,7931
11; 2017-12-07T11:43:43.9990189+01:00; 2017-12-07T11:43:44.8989094+01:00; 899,8905
10; 2017-12-07T11:43:43.9383692+01:00; 2017-12-07T11:43:44.9553891+01:00; 1017,0199
测试 3:
- 消息数:每分钟 1000 条
- 最大并发呼叫数:1000
- 操作:接收并删除消息
- 预取计数:1000
- 开始平均。 1-2s(预热明显减少)
- 结束平均。 ~100 毫秒(注意:尖峰最长 4.5 秒,尖峰明显减少)
- 输出:Pastebin link
示例输出:
11; 2017-12-07T11:54:16.8149682+01:00; 2017-12-07T11:54:17.6029464+01:00; 787,9782
14; 2017-12-07T11:54:16.9967915+01:00; 2017-12-07T11:54:17.6709669+01:00; 674,1754
0; 2017-12-07T11:54:16.0599312+01:00; 2017-12-07T11:54:17.6720080+01:00; 1612,0768
15; 2017-12-07T11:54:17.0578415+01:00; 2017-12-07T11:54:17.6724941+01:00; 614,6526
===========================
客户:
using System;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.ServiceBus;
namespace Sticos.ServiceBus.Client
{
public class ServiceBusClient
{
private readonly string _connectionstring;
private readonly string _topic;
private readonly TopicClient _topicClient;
public ServiceBusClient(string connectionstring, string topic)
{
_connectionstring = connectionstring ?? throw new ArgumentNullException(nameof(connectionstring));
_topic = topic ?? throw new ArgumentNullException(nameof(topic));
_topicClient = new TopicClient(_connectionstring, _topic);
}
public async Task SendAsync(string message)
{
await _topicClient.SendAsync(
new Message()
{
Body = Encoding.UTF8.GetBytes(message + ";" + DateTime.Now.ToString())
});
}
}
}
制作人:
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Sticos.ServiceBus.Client.Test
{
[TestClass]
public class ServiceBusClientTest
{
[TestMethod]
public void Producer()
{
var serviceBus = new ServiceBusClient("[connectionstring]", "[topic]");
var producer = Task.Factory.StartNew(() =>
{
var tasks = new Task[1000];
for (int i = 0; i < 1000; i++)
{
tasks[i] = serviceBus.SendAsync($"{i};{DateTime.Now.ToString("o")}");
Thread.Sleep(60);
}
Task.WaitAll(tasks);
});
Task.WaitAll(producer);
}
}
}
高级服务总线层提供一致的性能,因为您的命名空间将拥有不受嘈杂邻居干扰的专用资源。在标准层上,性能会根据服务的总体负载而波动,因为您的 queues/topics 与其他客户的 queues/topics 共享资源。
关于消息从生产者到达消费者所花费的时间,我可以告诉您,服务总线中没有延迟或其他设置会引入延迟。服务总线尽可能快地传递消息。我真的不能谈论或帮助网络传输速度。
但我认为提高接收消息的吞吐量也会降低消息到达消费者的平均时间。顺便说一句,您没有在此处粘贴消费者代码。我建议您尝试一些改进。批量发送确实有助于提高性能。不是每次发送调用都发送一条消息,而是根据消息大小分批发送 10 或 100 条。同样在接收器上,如果 PEEKLOCK/COMPLETE 模式对您来说不那么重要,请尝试使用 RECEIVEANDDELETE 模式。使用过多的并发调用意味着使用过多的线程。尝试调整最大并发调用和预取计数值,看看吞吐量如何变化。
另外,AMQP 提供了比 NetMessaging 或 Http 更好的性能。检查正在使用的协议的客户端配置并将其更改为 AMQP。
正如其他答案所建议的那样,更多的连接肯定会提高吞吐量。只需使用更多的发送者和更多的接收者。
因此,如果您在本地使用服务总线,则可以完成一些操作。例如,您可以部署到离您自己的数据中心最近的 Azure 区域。 您可以检查从 DC 到 Azure DC 的往返时间并进行延迟测量。 您可以评估的另一件事是使用快速路由来最大程度地减少延迟。 您介意提出支持请求吗?我们可以查看后端,看看我们是否可以在该上下文中进一步帮助您。