CAP 7.0 版本发布通告 - 支持延迟消息,性能炸了?
前言
今天,我们很高兴宣布 CAP 发布 7.0 版本正式版,我们在这个版本中带来了大批新特性以及对性能的优化和改进。
自从今年 1月份发布 6.0 版本以来,已经过去了快1年的时间。在过去的将近1年的时间里,我们也发布了几个次要版本和小版本(6.0.1, 6.1.0, 6.2.0, 6.2.1),在这里要感谢这些版本的使用者以及向我们报告 Bug 和反馈问题的用户。
同时,还要感谢一些我们的贡献者,是他们在帮助 CAP 变得更加完善和易用,以下是我们的所有贡献者。
好了,废话不多说,接下来我们具体看一下 7.0 带来的新变化吧。
总览
项目地址:https://github.com/dotnetcore/CAP
开源协议:MIT
本次在 CAP 7.0 版本中我们主要带来了以下新特性:
- 性能改进
- 支持发布延迟消息
- Dashboard 支持对延迟消息查看和操作
- 添加支持度量(Metric)的可观测性指标
- Dashboard 添加新图表支持 Metric 实时查看
- 支持手动 Start/Stop CAP 进程
- 其他改进
- 新增 EnableConsumerPrefetch 配置项
- RabbitMQ 新增 PublishConfirms 配置项
- 更改框架目标从 netstandard 到 net6
- 更新 NuGet 到最新版
- 破坏性改变
- 过滤器接口方法由同步更改为异步
- IConsumerClient 的 event 改为 delegate
性能改进
这个必须放在第一章。
在 .NET 7 中,官方做了大量对于性能的改进,是迄今为止最快的 .NET。
在 CAP 7 中,我们也做了大量对性能优化的改进,是迄今为止最快的 CAP。
在新版本我们内部做了大量对性能的调整,我们建议有条件的用户(项目框架为net6+)尽量升级,废话不多说直接压测看数据。
我们以使用量最高的 SQL Server + RabbitMQ 组合作为我们的测试基准。
这里是测试服务器配置:
实例: AWS EC2(c5.4xlarge, io1卷)
操作系统: Windows Server 2019
CPU:Intel Xeon Platinum 8275CL CPU@3.0Ghz
核心:16 cores
内存:32G
硬盘: SSD IOPS 3000
数据库:SQL Server 2019
消息队列:RabbitMQ 3.11.3
压力测试工具: Apache AB : 2.4.54-win64
压测命令:ab.exe -c 16 -n 50000 http://localhost:5000/xxx
压测数据:
await _cap.PublishAsync("topic", new {
Id = Guid.NewGuid(),
Name = "Hello World"
});
测试结果(TPS):
发布线程数 | .NET6 + CAP6 | .NET7 + CAP7 | CPU使用率 |
---|---|---|---|
1个线程 | 746/s | 1257/s | 7% |
4个线程 | 2288/s | 3124/s | 15% |
8个线程 | 4732/s | 6847/s | 30% |
下图蓝色为 CAP 7 , 绿色为 CAP 6.2版本。
说实话,看到这个数据我都被震惊了,我只能说4个字:“性能爆炸”。
为了大家有个概念,给大家个参考,一个不写任何代码的空接口大概是 9500/s,而 CAP 每次调用操作了 2 次数据库及 1 次 MQ,还能到 6847/s。以后再有人说性能先看看你的数据库和硬盘吧。
可能有人会说可能是 .NET 7 平台的性能提升的影响,所以这里也有一个 CAP 7 在 .net6 和 .net7 的对比:
发布线程 | .NET6 + CAP7 | .NET7 + CAP7 |
---|---|---|
1个线程 | 1196 | 1257 |
4个线程 | 3079 | 3124 |
8个线程 | 6733 | 6847 |
支持发布延迟消息
一直以来,我们都有用户反馈希望我们对延迟消息的支持,提出这些想法的主要出发点是系统中有相关需求,而他们了解到 RabbitMQ 提供了相关插件来做到发送延迟消息,所以很多用户在自己的项目中也是利用这一点来发送延迟消息。
在过去,我们一直没有对延迟消息提供支持主要是因为只有 RabbitMQ 才支持这一特性,而 RabbitMQ 中又需要开启相关的第三方延迟插件才能实现,而 CAP 的目标是对 Broker 提供上层抽象,所以我们需要提供一致的使用体验,这样用户不需要关心他使用的 Broker 是否能够发送延迟消息,所以在过去我们一直都没有支持。
现在,在 CAP 7.0 版本中,我们内置实现了一套轻量级的调度器,从而可以做到直接支持发送延迟消息而不需要关心 Broker 是否支持。新版本的延迟消息做到了不对目前数据结构做调整的情况下实现的,也就是说目前的数据库表结构不会发生任何变化也不会添加新的表,所以这不会存在任何升级兼容性问题,还是原来的配方和味道。
在 7.0 新版本中,我们的 ICapPublisher
接口新增加了两个新方法以支持直接发送延迟消息,分别是同步的 PublishDelay
和异步的 PublishDelayAsync
,同步只是对异步的包装,推荐大家使用异步接口。
下面是一个示例用于展示如何使用:
public class PublishController : Controller
{
[HttpGet]
public async Task PublishDelay([FromServices] ICapPublisher _capPubliser)
{
await _capPublisher.PublishDelayAsync(TimeSpan.FromSeconds(100), "topic", DateTime.Now);
}
}
在内部,延迟消息的状态为 Delayed,实际执行发送时间会被会存储在 ExpiresAt 字段中,内部实现为 CAP 的进程会每隔一分钟扫描数据库中要发送的下一分钟延迟消息,然后放置到内存中调度。异常场景的处理和规则的实现就不在这里展开讲了,感兴趣的朋友可以直接查看代码。
另外,我们同样在新版本中更新了我们的 Dashboard 以支持对延迟消息的查看,向下看。
Dashboard 支持对延迟消息查看和操作
在 7.0 中,我们更新了我们的 Dashboard 以支持对新增加延迟消息的查看功能,并且我们对我们的界面做出了一些调整,现在有更大的可视区域。
新版本的Dashboard 在底部增加了查看当前配置使用的 Broker种类或者 Storage 种类。
对于延迟消息,现在你可以在发送菜单的延迟选项卡界面上表格的最后一列看到“预计发送时间”,或者你可以点击“立即发布”按钮来立即触发消息发布而无需等待延迟结束。
添加支持度量(Metric)可观测性指标
我们知道OpenTelemetry主要有三部分组成,分别是Tracing,Mertics,Logging 。过去主要是对 Tracing(跟踪)和 Logging (日志)的支持,
其中我们在 2.6 版本中开始提供了Tracing的支持,我们在 SkyAPM.Diagnostics.CAP 包中提供了对 Skywalking 的支持以用于做分布式跟踪,并且在过去的 6.0 版本中,我们提供了 DotNetCore.CAP.OpenTelemerty 包对 OpenTelemetry 标准的直接支持。
上述更多的是对 Tracing 跟踪部分的支持,那么从 7.0 开始我们将更进一步。
在7.0 版本中,我们进一步提升了对可观测性的支持,我们添加了对 Metrics 的支持,现在你可以利用官方提供的 dotnet-counters 工具来查看我们对外提供的Metric指标。
使用 dotnet-counters ps
命令列出 CAP 所属的进程Id,然后使用 monitor 以查看收集的实时数据(每秒刷新一次)。
dotnet-counters ps
dotnet-counters monitor --process-id=25496 --counters=DotNetCore.CAP.EventCounter
CAP 7.0 提供了以下几个度量指标:
- 每秒发布速度
- 每秒消费速度
- 每秒调用订阅者速度
- 每秒执行订阅者平均耗时
同时,我们也在我们的Dashboard 中提供了对度量指标的直接观测,你可以直接以图表的形式查看更为直观,向下看。
Dashboard 支持 Metric 实时查看
在 CAP 7.0 中,我们改进了我们的Dashbaord,新增加了对实时度量(Metric)指标的查看。
同时我们也改进了我们的图表组件,从 ECharts 切换到了 uPlot,uPlot提供了更小体积的同时,也带来了更好的性能和渲染速度,还有嗯~ 附和我们的风格… :)
现在,你可以在CAP 中配置上 x.UseDashbaord() 来感受 Metric 的魅力吧。
从上图可以看到,在 Realtime Metric Graph 中,时间轴会随着时间实时滚动从而可以清晰的看出发布和消费每秒的速率,同时我们对消费者执行耗时以“打点”的方式体现到了 Y1 轴上(Y0轴为速率,Y1轴为执行耗时)。
值得提醒的是,Y1轴不代表消费执行次数,而是每秒钟内消费者的执行平均耗时。
支持手动 Start/Stop CAP 进程
在过去,默认情况下 CAP 随 ASP.NET Core 宿主进程启动,你无法(很难) 做到控制默认的停止或启动行为,只能按下 Ctrl+C 来停止宿主进行同时触发停止CAP。
现在,你可以通过 IBootstrapper
接口来动态控制 CAP 启动或停止。例如,在一个 Action 中添加如下两个方法来控制。
[Route("~/control/start")]
public async Task<IActionResult> Start([FromServices]IBootstrapper bootstrapper)
{
await bootstrapper.BootstrapAsync();
return Ok();
}
[Route("~/control/stop")]
public async Task<IActionResult> Stop([FromServices] IBootstrapper bootstrapper)
{
await bootstrapper.DisposeAsync();
return Ok();
}
注意:如果你停止了CAP进程,则无法进行发布或订阅消息。
通过这个特性,可以延申出来的应用场景有很多,比如在系统在某个时候开始发送/消费消息等。
其他改进
新增 EnableConsumerPrefetch 配置项
在过去,我们默认会在消费端预取一部分消息到内存队列,然后再分发给调度器执行,这在提高性能的同时也会产生一些问题。
例如,当订阅方法执行过慢耗时太久时,会导致重试线程拾取到还未执行的的消息。重试线程默认拾取4分钟前的消息,也就是说如果消费端积压了超过4分钟的消息就会被重新拾取到再次执行,会产生重复,虽然我们要求消费者保持幂等,但这不太友好。
在 7.0 版本中,我们改变了这个行为,现在默认情况只会从消息队列读取一条,然后执行订阅方法,执行完成后才会读取下一条来执行。我们新增了 EnableConsumerPrefetch 来使用以前的行为,默认为 false,通过设置 EnableConsumerPrefetch = true
来回到过去的行为。
如果想提高速度,你可以通过设置 ConsumerThreadCount 来并行执行。
RabbitMQ 新增 PublishConfirms 配置项
过去,在 RabbitMQ 发布端默认启用了发布确认,无法进行设置,对于一些要求高性能的场景中会限制发布速度,所以在新版本中我们提供了配置项来让用户可以手动配置。
考虑到大多数场景失败的概率很小,我们将默认值为 false,如果你需要考虑极端场景请将其设置为 true,这会降低吞吐量。
现在你可以通过设置 rabbitmqOption.PublishConfirms = true
来开启发布确认,你可以在这里查看更多关于发布确认的信息。
更改框架目标从 netstandard 到 net6
在CAP 7.0中,我们将所有的包目标框架由 netstandard 2.1 更改到了 net6 , 对于不需要支持 netframework 或者 Xamarin 之类的目标平台来说,支持 netstandard意义不大,这也是根据官方对库作者的建议,所以我们遵循最佳实践。
.NET 7 拥有向下兼容性,并且我们没有使用到 .NET 7 特有的东西,所以我们只需将net6 作为目标平台即可,这样 net6, net7 都可以使用。
更新NuGet到最新版
这个不用多说了,国际惯例在进行大版本发布时,都会升级依赖NuGet包到最新版。
值得一提的是,我们 DotNetCore.CAP.SqlServer 的 SqlClient 升级到了最新的版本,你的SQL Server连接字符串可能需要添加 TrustServerCertificate=True
信任一下证书,否则可能会报错。
破坏性改变
过滤器接口方法由同步更改为异步
考虑到现在大部分代码都是异步写法,所以我们将订阅过滤器接口提供的三个方法由同步改为了异步,这个是我们做出的破坏性改变,如果你使用到了过滤器特性,升级后可能需要调整一下你的代码。
分别是:
OnSubscribeExecuting
更改为OnSubscribeExecutingAsync
OnSubscribeExecuted
更改为OnSubscribeExecutedAsync
OnSubscribeException
更改为OnSubscribeExceptionAsync
IConsumerClient 的 event 改为 Action/Func
这个对一般用户没有影响,主要影响到的是我们的社区第三方 Broker 扩展。
在新版本 IConsumerClient
接口中,OnReceiveMessage 和 OnLog 回调由 event
改为下面两种形式,用法不变。因为 event 不支持异步。
public Func<TransportMessage, object?, Task>? OnMessageCallback { get; set; }
public Action<LogMessageEventArgs>? OnLogCallback { get; set; }
总结
以上,就是本版本我们做出的一些新特性和改动,感谢大家的支持,我们很开心能够帮助到大家 。
大家在使用的过程中遇到问题希望也能够积极的反馈,帮助CAP变得越来越好。
如果你喜欢这个项目,可以通过下面的连接点击 Star 给我们支持。
如果你觉得本篇文章对您有帮助的话,感谢您的【推荐】。
本文地址:http://www.cnblogs.com/savorboard/p/cap-7-0.html
作者博客:Savorboard
本文原创授权为:署名 - 非商业性使用 - 禁止演绎,协议普通文本 | 协议法律文本
CAP 7.0 版本发布通告 - 支持延迟消息,性能炸了?的更多相关文章
- CAP 6.0 版本发布通告 - 支持 OpenTelemetry
前言 今天,我们很高兴宣布 CAP 发布 6.0 版本正式版,在这个版本中,我们主要致力于对 OpenTelemetry 提供支持,以及更好的适配 .NET 6. 那么,接下来我们具体看一下吧. 总览 ...
- CAP 3.0 版本发布通告
前言 大家好,我们很高兴宣布 CAP 发布了 3.0 版本正式版. 自从上次 CAP 2.6 版本发布 以来,已经过去了几个月的时间,关注的朋友可能知道,在这几个月的时间里,也发布了几个预览版的 3. ...
- CAP 5.0 版本发布通告
前言 今天,我们很高兴宣布 CAP 发布 5.0 版本正式版.同时我们也很高兴的告诉你 CAP 已经有越来越多的用户并且变得越来越流行. 在 5.0 版本中,我们主要致力于更好的支持 .NET 5 以 ...
- CAP 3.1 版本发布通告
前言 今天,我们很高兴宣布 CAP 发布 3.1 版本正式版.同时我们也很高兴的告诉你 CAP 在 GitHub 已经突破了 4000 Star. CAP 3000 Star 还是去年8月份的时候,最 ...
- CAP 5.1 版本发布通告 - 你期待的 Redis 来了
前言 今天,我们很高兴宣布 CAP 发布 5.1 版本正式版,在这个版本里我们同样引入了更多令人激动的新特性和改进,同时也得到越来越多人的喜爱. 得益于社区的反馈和贡献者的支持,在过去的两个月里,我们 ...
- CAP 2.4版本发布,支持版本隔离特性
前言 自从上次 CAP 2.3 版本发布 以来,已经过去了几个月的时间,这几个月比较忙,所以也没有怎么写博客,趁着2019年到来之际(现在应该是2019年开始的时候),CAP也发布了2018年的最后一 ...
- CAP 2.6 版本发布通告
前言 今天,我们很高兴宣布 CAP 发布 2.6 版本正式版.同时我们也很高兴的告诉你 CAP 在 GitHub 已经突破了3000 Star. 自从上次 CAP 2.5 版本发布 以来,已经过去了几 ...
- CAP 6.1 版本发布通告
前言 今天,我们很高兴宣布 CAP 发布 6.1 版本正式版,在这个版本中我们主要针对目前已经发现的几个BUG进行了修复了以及添加了一些小特性. 那么,接下来我们具体看一下吧. 总览 可能有些人还不知 ...
- CAP 5.2 版本发布通告
前言 今天,我们很高兴宣布 CAP 发布 5.2 版本正式版,在这个版本中,我们主要致力于更好的优化使用体验以及支持新的 Transport,同时在该版本也进行了一些 bug 修复的工作. 自从 5. ...
- CAP 6.2 版本发布通告
前言 今天,我们很高兴宣布 CAP 发布 6.2 版本正式版,在这个版本中我们主要做了一些功能优化,以及针对目前已经发现的几个 BUG 进行了修复了. 那么,接下来我们具体看一下吧. 总览 可能有些人 ...
随机推荐
- docker学习笔记一-docker安装与卸载
环境查看 # 1 查询当前centOS的版本,官方要求版本为7以上 uname -r 查询系统内核 cat /etc/os-release 系统版本 安装 # 1.卸载旧版本 yum remove d ...
- 开源即时通讯GGTalk 8.0发布,增加Linux客户端,支持在统信UOS、银河麒麟上运行!
GGTalk在2021年推出7.0后,经过一年多时间的开发,终于推出8.0版本,实现了Linux客户端. 这几年,信创国产化的势头越来越猛,政府事企业单位都在逐步转向使用国产OS.国产CPU.国产数据 ...
- uniapp路由守卫
项目地址:https://hhyang.cn/v2/start/quickstart.html 按照他的方法安装,创建相应的js即可,有点基础的自己捣鼓一下就可以了.我的应用场景是:没有登录痕迹- ...
- Ubuntu20.04和Docker环境下安装Redash中文版
创建Ubunt20.04虚拟机,请参考:https://www.linuxidc.com/Linux/2020-03/162547.htm 一.安装基础环境: # 1.更换APT国内源 sudo se ...
- NSIS V3.08 简体中文增强版
说明: 该3.08版本属本人业余时间集成修改制作,首发博客园,欢迎反馈安装与使用中出现的BUG,转载请注明出处! 本版本母版源自NSIS(Nullsoft Scriptable Install Sys ...
- SpringBoot实战派读书笔记---响应式编程
1.什么是WebFlux? WebFlux不需要Servlet API,在完全异步且无阻塞,并通过Reactor项目实现了Reactor Streams规范. WebFlux可以在资源有限的情况下提高 ...
- Linux-->vi和vim编辑器的基本操作
vim编辑器介绍 vi或者vim就是对linux下的文本进行编辑的一种编辑器比如说a.cpp文件这种 Linux会内置vi文本编辑器 Vim可以简单的认为vi的增强版 Linux是区分大小写的! 用法 ...
- 集合元素的遍历操作,使用迭代器Iterator接口
1.内部的方法:hasNext() 和 next() 推荐的方式: //hasNext():判断是否还有下一个元素while(iterator.hasNext()){ //next():①指针下移 ② ...
- IDEA插件MyBatisCodeHelper-Pro的破解与使用
0.前言 本文中的IDEA版本是2020.3,使用的插件版本是MyBatisCodeHelper-Pro 2.8.9,3.0+版本目前没找到激活的方式 和本文插件类似的还有mybatisX,但我不喜欢 ...
- 成功 解决 @keyup.enter=“search()“ 在el-input 组件中不生效的问题
1.问题描述 在输入框中.输入内容.点击回车.没有效果 问题代码 2.问题解决思路 查看官网的解释说明: 要使用.native修饰符 3.问题解决 修改后的代码 修改后的效果