Azure Service Bus主题订阅触发FilterException:string与System.DBNull无法比较
Azure Service Bus订阅FilterException问题排查与解决
问题现象
Azure Service Bus主题下的某订阅突然出现所有消息被送入死信队列的情况,触发FilterException,错误日志显示:
Operator '==' cannot be applied to operands of type 'string' and 'System.DBNull'
该订阅使用的SqlFilter表达式为:
TriggerEvent in ("A01", "A04", "A28", "A47") OR (TriggerEvent = "A31" AND EventReasonCode = "REG_MANUAL")
此配置已稳定运行数月无异常,且在另一生产环境中可正常工作。
根因分析
问题源于消息属性缺失:当消息未携带TriggerEvent或EventReasonCode属性时,对应的属性值会被识别为System.DBNull,而SqlFilter中的=、in运算符无法直接在字符串类型和DBNull类型之间进行比较,从而抛出异常,导致消息被直接转入死信队列。
之前未出现问题是因为所有消息都正确携带了这两个属性,近期有消息未按规范设置属性,才触发了这个隐藏的类型匹配问题。
解决方案
修改SqlFilter表达式,先判断属性是否非空,再执行条件匹配,避免类型不匹配的异常:
优化后的表达式:
(TriggerEvent IS NOT NULL AND TriggerEvent IN ("A01", "A04", "A28", "A47")) OR (TriggerEvent IS NOT NULL AND TriggerEvent = "A31" AND EventReasonCode IS NOT NULL AND EventReasonCode = "REG_MANUAL")
也可以利用逻辑短路特性简化写法:
TriggerEvent IS NOT NULL AND ( TriggerEvent IN ("A01", "A04", "A28", "A47") OR (TriggerEvent = "A31" AND EventReasonCode IS NOT NULL AND EventReasonCode = "REG_MANUAL") )
修改后,当消息缺失目标属性时,过滤器会直接跳过条件判断,不会抛出异常,消息也不会被误送入死信队列。
内容的提问来源于stack exchange,提问作者Eivind Gussiås Løkseth
相关产品推荐
相关产品推荐

