使用 JAX-RPC 时如何将错误请求放入死信队列?
我使用 JAX-RPC 1.1 为在 WAS 6.0 上运行的一组应用程序生成服务,并通过 Websphere MQ 进行通信。大型机将向服务发送消息,因此如果由于某种原因消息无法转换为对象(可能是由于 EBCDIC 到 ASCII 的怪异),则需要将消息放置在死信队列中进行检查。
有谁知道是否有标准方法可以做到这一点(即通过提供带有 DLQ 名称的 jms:/ 地址),或者是否需要以某种方式手动执行 DLQ 转发?
I'm using JAX-RPC 1.1 to generate services for a set of applications running on WAS 6.0, communicating via Websphere MQ. A mainframe will be sending messages to the services, so if for some reason the message can't be converted to objects (likely due to EBCDIC-to-ASCII weirdness), the message needs to be placed on the dead-letter queue for examination.
Does anyone know if there's a standard way to do this (i.e. by providing the jms:/ address with a DLQ name), or if DLQ-forwarding would need to be performed manually somehow?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,我建议您不要依赖 DLQ 来实现此目的。 DLQ是QMgr级别的资源,用于存储通道无法解析的消息。因为它是一个潜在的攻击媒介,所以大多数具有安全意识的商店不会授予对应用程序的访问权限,或者即使他们这样做,也只是 put-only 访问权限。
执行此操作的最佳方法是创建特定于应用程序的异常队列。如果应用程序有多个输入队列,它们都可以使用相同的异常队列,然后应用程序支持团队可以管理到达那里的任何消息,而不会出现安全问题。
无论您采取哪种方式,让应用程序遵守这一点都非常容易。例如,假设您的应用程序正在读取 JAX.SVC.REQUEST。您定义异常队列并将 BOQ* 字段指向它:
DEF QL(JAX.SVC.EXCEPTION)
ALTER QL(JAX.SVC.REQUEST) BOQNAME(JAX.SVC.EXCEPTION) BOQTHRESH(5)
JMS 类将在打开队列时查询队列的 BOQ* 属性,并检查读取的每条消息的回退计数。在您的程序中使用事务处理会话,如果您无法处理消息,请调用 session.backout() 方法。该消息将被读取和回退不超过 BOTHRESH 次,然后重新排队到 BOQNAME 中指定的队列。如果该队列已满或不可用,将尝试 DLQ。如果失败,类将抛出异常。
我们选择 BOTHRESH > 1 允许在 QMgr 关闭等情况下取消可处理消息的可能性。
我通常会触发异常队列,以便在有东西落在其中时它可以发出警报或发送电子邮件。如果您有监控工具,您可以检查深度> 0 代替。
如果由于某种原因您不想使用 JMS 功能自动重新排队消息,则应用程序将需要逻辑来重新排队消息。如果您要将消息放在 DLQ 上,您将需要在前面添加 DLQ 标头。如果不这样做,可能会破坏 DLQ 处理程序或监视该队列的任何其他工具。
First, let me recommend that you do not rely on the DLQ for this. The DLQ is a QMgr-level resource that is used to store messages that the channel cannot resolve. Because it is a potential attack vector, most security-conscious shops will not grant access to applications, or if they do it is put-only access.
The best way to do this is to create an app-specific exception queue. If the app has several input queues, they can all use the same exception queue and then the application support team can manage any messages that land there without the security issues.
Whichever way you go, getting the app to honor this is extremely easy. For example, suppose your app is reading from JAX.SVC.REQUEST. You define the exception queue and point the BOQ* fields at it:
DEF QL(JAX.SVC.EXCEPTION)
ALTER QL(JAX.SVC.REQUEST) BOQNAME(JAX.SVC.EXCEPTION) BOQTHRESH(5)
The JMS classes will inquire on the BOQ* attributes of the queue when it is opened and check the backout count of each message read. In your program use a transacted session and if you can't process the message, call the session.backout() method. The message will be read and backed out no more than BOTHRESH times, then requeued to the queue named in BOQNAME. If that queue is full or unavailable the DLQ will be tried. If that fails, the classes will throw an exception.
We pick a BOTHRESH > 1 to allow for the possibility that a processable message will be backed out if, for example, the QMgr is shut down.
I usually trigger the exception queue so that it can raise an alarm or send an email if something lands on it. If you have a monitoring tool you can check for depth > 0 instead.
If for some reason yo don't want to use the JMS functionality to automatically requeue the message, the application would need logic to requeue it. If you were to place the message on the DLQ you will want to prepend a DLQ header. Failure to do so will probably break the DLQ handler or any other instrumentation watching that queue.