【发布时间】:2010-12-09 22:37:01
【问题描述】:
我们的其中一款产品实现了以下单向网络服务结构:
Server <--------------------- Middleware <---------------- Client
SOAP over JMS (queue) SOAP over HTTP
在此模型中,客户端通过 HTTP 将 SOAP 消息发送到我们的中间件(Progress SonicMQ)。消息被 SonicMQ 推送到 JMS 队列中,我们的服务器从那里获取它们。但是,如您所见,服务器不会向客户端发送响应(异步 JMS)。
我们想为此模型实现一个响应通道。通常建议的解决方案是在中间件中创建一个临时的replyTo-queue(即时),允许服务器向该队列发送响应。然后,客户端可以获取响应并关闭replyTo-queue。这听起来很方便,但不幸的是,我们的客户端通过普通 HTTP 而不是 JMS 进行操作,因此他们的客户端无法轻松设置回复队列。
在这种混合 HTTP/JMS SOAP 模型中实现响应通道的一种方法是将中间件配置为在每次成功的 SOAP 接收时打开 replyTo 队列,将 replyTo-queue 和发送者信息附加到 SOAP 消息并推送消息发送到队列,服务器将在队列中获取消息。服务器收到并处理完消息后,可以向中间件中指定的replyTo-queue 发送响应。最后,中间件将通过 HTTP 使用来自 SOAP 消息的数据(首次接收到请求时在中间件过程中插入的数据)将响应 (SOAP) 发送回原始客户端。
虽然有可能,但这听起来有点老套。所以问题是:在我们的案例中实现这种请求/响应模型的任何更清洁的方法?服务端已经用Java实现。
解决办法:
Progress SonicMQ 支持“内容回复发送”HTTP Acceptor,它允许轻松发送 JMS 回复。内容回复发送接受器的工作方式如下:
- Acceptor 接收客户端发送的 HTTP 消息
- Acceptor 创建一个临时 JMS 队列
- Acceptor 构建一个包含 HTTP 正文的 JMS 消息,并将临时队列的标识添加到新创建的 JMS 消息中
- Acceptor 将 JMS 消息推送到其目标队列(不是临时队列)
- Acceptor 开始使用临时回复队列
- 当客户端从原始目标队列获取消息时,它包含设置的回复队列标识
- 客户端消费消息
- 客户端向回复队列发送回复
- 接受者从队列中接收消息
- Acceptor 将消息作为 HTTP 发送给最初发送 HTTP 消息的客户端
如果消费者(在我们的例子中是“服务器”)失败并且没有发送导致超时的回复,Sonic 的 HTTP 接受器会向客户端发送一条 HTTP 消息,指示超时。这是 SonicMQ 中非常标准的功能。我想它也存在于其他产品中。
这允许在“服务器”端使用标准 SOAP over JMS(参见 skaffman 的回答),避免在中间件中进行任何自定义编程。
虽然我仍然看到 JMS 模型中存在一些问题,但这绝对是一种改进。
2009-11-05 更新:
在进一步研究了这个问题之后,事实证明我对 HTTP中间件JMS 的怀疑与此有关。
此模型存在一些关键问题。带有中间件的同步异步模型根本不方便。要么让两端都实现 JMS 连接(应该摇滚),要么在两端都使用 HTTP。混合它们只会导致头痛。在这两者中,SOAP-over-HTTP 比 SOAP-over-JMS 更简单且支持更好。
再说一遍:如果您正在设计这种系统......不要这样做。
【问题讨论】:
标签: java web-services soap jms soa