Skip to the content.

契约名与消息路由键

问题

应用注册消息契约时,原来只检查契约名不超过 200 个 .NET 字符。SelfManaged 可以据此把消息写入 Outbox;等后台发布时,RabbitMQ 才检查完整路由键 {契约名}.v{版本号} 的 UTF-8 字节数必须小于 255。Wolverine 也使用同一别名建立发布端点。注册成功不代表消息一定能通过当前传输发送。

例如,84 个汉字加 .v1 恰好是 255 个 UTF-8 字节;81 个汉字加 .v2147483647 也是 255 字节。两者原本都能注册,但发送失败。含孤立 UTF-16 代理字符的名称也能注册,之后在严格 UTF-8 编码时抛出 EncoderFallbackException。

规则与位置

注册的契约名仍需非空、至多 200 个 .NET 字符,版本号仍需为正数。新增检查要求完整路由键能够无损编码为 UTF-8,且编码后小于 255 字节。版本号使用不受当前区域设置影响的十进制文本。

MessageRoutingKey 提供相同的格式化和检查规则。注册时立即拒绝不可发布的契约;RabbitMQ 对绕过注册直接提供的 SerializedMessage 也在编码时检查,对外部信封在解码时检查。队列绑定、SelfManaged 发送及 Wolverine 的消息别名使用相同的格式。Inbox/Outbox 的契约名列继续限制为 200 个字符,并引用共享常量。

本次没有修改名称的点分段或通配符语义。通配符能否作为契约名是独立的路由规则问题,不由长度校验决定。

验证与取舍

修改前,边界回归测试确认 84 个汉字的 v1 名称、81 个汉字的最大版本名称、孤立代理字符都能错误地注册;发送孤立代理字符时抛的是编码异常。修改后,这些名称在注册时被拒绝,直接发送的非法信封得到永久错误;83 个汉字的 v1 名称、80 个汉字的最大版本名称、200 个 ASCII 字符的名称仍通过。测试还检查 RabbitMQ 接收、点分段名称及 Wolverine 的合法 Unicode 别名。

这条规则目前放在两个 Provider 共用的注册表中,因为仓库中的 SelfManaged 和 Wolverine 都通过 RabbitMQ 使用该路由键。若以后增加不使用此路由格式的 Provider,需要重新确定共享契约是否仍应承载传输字节限制。此次没有更改已有 Outbox 数据;历史超限名称仍需人工处理,注册校验无法修复已持久化的行。