我忆经放弃这个队列了。看不懂,缺少维护。该释放的没有释放,只很少的操作,几天就会占去大半的内存。
跟据VS生成的警告进行修改,改完之后,又莫名奇妙的丢失连接,丢失消息。。
一直以来, 都是用内存换时间. 现在突然只有一台 32G 的老破小, 还要在上面发布一堆服务, 搞的猝不及防.
应用程序还好说, 自己的代码, 自己可以控制. 依赖于第三方的服务, 却无可奈何.
在队列的选择上, 真是虚耗了许多美妙的时光.
一开始, 对比了 RabbitMQ
和 RocketMQ
, 终合比较了一下, 打算选择后者, 并且打算在老破小上用 Docker
安装 RocketMQ
, 但是配置搞了半天, 就是无法对外提供服务, 放弃了.
跳开 Docker
安装, 能对外提供服务了, 但是一启动, 内存就直接占了 9G
多. 这台32G 的老破小, 啥也没干, 一下就丢掉了 1/4 的活力, 后面铁定是无法干下去的. 搞了半天 JVM
的配置, 但是不得要领, 内存依然坚挺.没有办法, 只有放弃了.
最后选择了还算熟悉的, 汤雪华
, 汤老师开源的 EQueue
, .NET 的, 最新版本支持 .NET Core 3
, 但相对来说, 不是有点老, 是太老了. 汤老师已经两年没有维护了.
这个版本可以直接使用, 但是对于 .NET 6/7/8
就没有那么友好了, 因为它使用的 BinaryFormatter
做为二进制序列化器, 已经无法正常使用了:
中断性变更:BinaryFormatter 序列化方法已过时,并且已在 ASP.NET 应用中禁用 - .NET | Microsoft Learn
由于 BinaryFormatter 存在安全漏洞,因此,以下方法现已过时,并生成 ID 为
SYSLIB0011
的编译时警告。 此外,在 ASP.NET Core 5.0 及更高版本的应用中,除非 Web 应用已重新启用 BinaryFormatter 功能,否则它们会引发 NotSupportedException。
要解决这个问题, 只能换掉这个东西:
- 用
Bson
可行, 但是毕竟它只是Json
的二进制化而已, 对于网络传输而言Json
也太大了, 无端耗费宽带, 对这台老破小来说是不可接受的. - 用
ProtoBuf.net
, 应该是可行的, 但是要解决几个问题:- 对
IEnumerable
,IList
等的支持. - 对多构造函数的支持
- 类型继承有点麻烦, 需要在父类上加
ProtoInclude
, 这点真是不能接受.
- 对
-
MemoryPack
, 对比上面两个, 真是理想到家了,.NET
原生的, 据说各项指标都比ProtoBuf
好. 唯一要解决的是, 多构造函数的问题. 这个也容易解决,MemoryPack
提供了MemoryPackConstructor
, 区分好哪个是对外部开放, 哪个是对内部使用的就行了.//内部用于继承的, public Message() { } //虽然也对外提供, 但是可以和下面那个合并, 只保留一个. //public Message(string topic, int code, byte[] body, string tag = null) // : this(topic, code, body, DateTime.Now, tag) { } //对外提供 [MemoryPackConstructor] public Message(string topic, int code, byte[] body, DateTime? createdTime = null, string tag = null)
最后的成品:
gruan01/EQueue: EQueue for .net8 (github.com)
改是改完了, 但是毕竟不是原装的, 对内里的机制不大理解, 难免有纰漏之处. 还是期待汤老师的更新.
有一个问题不大理解:
按汤老师提供的示例代码配置 Broker
的 chunkSize = 256
, 会报错, 具体在 Chunk.cs
的606行。
if (writerWorkItem.WorkingStream.Position + _chunkConfig.ChunkDataUnitSize > ChunkHeader.Size + _chunkHeader.ChunkDataTotalSize)
{
return RecordWriteResult.NotEnoughSpace();
}
把这个值改大点, 比如 512 就没有这个问题。