这里,您可以选择一些参数:异步调用类型和调用是否跨越模块边界。
在调用JSP文件以后,JSP页面上选择的参数被传递给Caller组件的Java实现(请参见清单4)。该实现将根据参数发出特定的异步调用。
清单4. Caller组件的实现
public void makeAsyncCall(Boolean isCrossModuleInvocation,
Integer asyncInvocationType) {
System.out.println(“=========> into caller’s makeAsyncCall method,
parameters are: isCrossModule:” + isCrossModuleInvocation +
” asyncInvocationType:” + asyncInvocationType);
Service callee = null;
if (isCrossModuleInvocation) {
//cross module invocation.
callee = this.locateService_HelloSCAIntfPartner1();
} else {
callee = this.locateService_HelloSCAIntfPartner();
}
switch(asyncInvocationType) {
case 1:
callee.invokeAsync(“oneWayCall”, “hello”);
break;
case 2:
AsyncTicket ticket = (AsyncTicket)callee.invokeAsync(“twoWayCall”, “hello”);
System.out.println(“===========>Invocation Type is two way deferred response,
ticket:” + ticket.getId());
try {
Thread.currentThread().sleep(2*1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
DataObject result = (DataObject) callee.invokeResponse(ticket, Service.WAIT);
System.out.println(result.get(“output”));
break;
case 3:
ticket = (AsyncTicket)callee.invokeAsyncWithCallback(“twoWayCall”, “hello”);
System.out.println(“===========> Invocation Type is two way call back, ticket:”
+ ticket.getId());
break;
default:
System.out.println(“wrong type:” + asyncInvocationType);
}
}
总共存在六种组合,接下来的几个部分将对此进行详细的介绍。
单模块异步调用:单向
·在JSP页面上,确保选择SingleModuleInvocation和asyncOneWay,然后单击Submit按钮。
·在调用完成以后,打开SystemOut日志文件。您应该看到已生成了如清单5所示的信息。
清单5. 单模块中的单向异步调用的SystemOut日志
[6/2/08 13:37:02:093 CST] 00000067 SystemOut O =====> destination name:
sca/Caller/component/Callee
[6/2/08 13:37:02:124 CST] 00000067 SystemOut O =====> destination name:sca/Caller
可以看到,此调用中涉及到两个目的地:sca/Caller/component/Callee和sca/Caller。正如目的地名称所指示的,sca/Caller/component/Callee表示Callee组件,sca/Caller表示该模块本身。关键配置:在将消息路由到sca/Caller/component/Callee以后,消息会自动重新路由到sca/Caller目的地。这是通过在目的地sca/Caller/component/Callee上定义缺省转发路由路径来实现的,如图9所示。
图9. 缺省转发路由路径
基于SystemOut日志文件中生成的日志,您可以创建消息流序列关系图,如图10所示。Caller组件发出异步调用,然后请求将由SCA运行时进行处理。SCA运行时将请求和目标服务信息放入消息中,然后SCA运行时将消息放入sca/Caller/component/Callee目的地中。下一步,根据缺省转发路由路径,消息将路由到sca/Caller目的地。MDB被触发以处理该消息;它只是拾取该消息,从消息正文中获取请求数据,从消息标头中获取目标服务信息,然后将信息发送给SCA运行时。基于此信息,SCA运行时可以知道应该将请求路由到哪一个组件。
图10. 单模块异步调用的消息流序列关系图:单向
单模块异步调用:延迟响应
第二种场景是异步延迟响应。在清单6中,您可以看到您首先发出了一个异步请求。在调用完成以后,您可以获取一个票据(ticket)对象。稍后您可以使用此票据来查询结果。
清单6. 延迟响应调用
AsyncTicket ticket = (AsyncTicket)callee.invokeAsync(“twoWayCall”, “hello”);
//do something
//query result
DataObject result = (DataObject) callee.invokeResponse(ticket, Service.WAIT);
·在JSP页面上,确保选择SingleModuleInvocation和asyncDeferredResponse,然后单击Submit按钮。
·在调用完成以后,打开SystemOut日志文件。您应该看到已生成了如清单7所示的信息。
清单7. 单模块中的延迟响应异步调用的SystemOut日志
[6/2/08 13:38:30:942 CST] 00000067 SystemOut O =====>
destination name:sca/Caller/component/Callee
[6/2/08 13:38:30:942 CST] 00000067 SystemOut O =====> destination name:sca/Caller
[6/2/08 13:38:31:036 CST] 00000067 SystemOut O =====>
destination name:sca/Caller/component/Callee
[6/2/08 13:38:31:083 CST] 00000067 SystemOut O =====> destination name:sca/Caller
在SystemOut日志中,您可以看到除了sca/Caller/component/Callee和sca/Caller以外,还使用了另一个目的地sca/Caller/component/Caller。SCA运行时使用此目的地来传送响应消息。其机制如下:在调用目标服务并生成响应以后,SCA运行时知道该消息是响应消息。然后SCA运行时将消息放入此目的地中(SCA运行时维护有每个调用的消息标头,因此它知道请求来自于何处,以及应该将响应发送到何处)。同样,sca/Caller/component/Caller中定义了缺省的转发路由路径,然后消息将路由到sca/Caller模块目的地。消息一直保留在此目的地中,直到您发出invokeResponse请求来使用它为止。
图11. 单模块异步调用的消息流序列关系图:延迟响应
单模块异步调用:回调
此场景与延迟响应场景相同,只不过结果将由SCA运行时自动发回给调用者。幕后的“魔法”在于,caller类具有一个接收响应的方法。因此如清单8所示,当SCA运行时取回响应消息时,它将调用Caller的特定方法来将响应传递给Caller。
清单8. 回调调用
public void onTwoWayCallResponse(Ticket __ticket, String returnValue,
Exception exception) {
//proces response message.
}
清单9显示了在使用SingleModuleInvocation和asyncDeferredResponse参数提交请求之后,SystemOut日志文件中生成的日志信息。
清单9. 单模块中的回调异步调用的SystemOut日志
[6/2/08 13:39:59:385 CST] 00000067 SystemOut O =====>
destination name:sca/Caller/component/Callee
[6/2/08 13:39:59:416 CST] 0000006f SystemOut O =====> destination name:sca/Caller
[6/2/08 13:39:59:588 CST] 00000067 SystemOut O =====>
destination name:sca/Caller/component/Caller
[6/2/08 13:39:59:603 CST] 0000006f SystemOut O =====> destination name:sca/Caller
图12. 单模块异步调用的消息流序列关系图:回调
跨模块异步调用:单向
转向跨模块的场景时,情况变得稍微有点复杂,因为必须正确地将请求消息和响应消息传递到正确的目的地,而这些目的地位于不同的模块中。
·在JSP页面上,确保选择IsCrossModuleInvocation和asyncDeferredResponse。然后单击Submit按钮。
·在调用完成以后,打开SystemOut日志文件。您应该看到已生成了如清单10所示的信息。
清单10. 跨模块单向异步调用的SystemOut日志
[6/2/08 13:55:31:782 CST] 0000006f SystemOut O =====>
destination name:sca/Caller/importlink/CalleeImport
[6/2/08 13:55:31:829 CST] 0000006f SystemOut O =====>
destination name:sca/Callee/exportlink/CalleeExport
[6/2/08 13:55:31:876 CST] 0000006f SystemOut O =====> destination name:sca/Callee
根据生成的日志,您可以绘制消息路由序列关系图(如图13所示)。
图13. 跨模块异步调用的消息流序列关系图:单向
这里的要点在于,在部署期间,将会在sca/Caller/importlink/CalleeImport上创建缺省转发路由路径。然后在消息到达此目的地时,消息将被自动转发到sca/Callee/exportlink/CalleeExport,后者驻留在Callee模块中。同样,sca/Callee/exportlink/CalleeExport上定义了缺省转发路由路径,因此在消息到达此目的地时,消息将被转发到sca/Callee目的地。正如前面所讨论的,生成的MDB将发挥作用以使用该请求消息。
跨模块异步调用:延迟响应
清单11显示了为延迟响应调用生成的日志。
清单11. 跨模块延迟响应异步调用的SystemOut日志
[6/2/08 13:57:08:491 CST] 0000006f SystemOut O =====>
destination name:sca/Caller/importlink/CalleeImport
[6/2/08 13:57:08:506 CST] 0000006f SystemOut O =====>
destination name:sca/Callee/exportlink/CalleeExport
[6/2/08 13:57:08:506 CST] 0000006f SystemOut O =====> destination name:sca/Callee
[6/2/08 13:57:08:569 CST] 0000006f SystemOut O =====>
destination name:sca/Caller/import/CalleeImport
[6/2/08 13:57:08:569 CST] 0000006f SystemOut O =====> destination name:sca/Caller
在消息路由序列关系图中,可以看到在结果可用之后,SCA运行时可以直接将响应消息发回到Caller模块的目的地。其基本原理在于,当在Caller的模块中发出延迟响应调用时,SCA知道该调用是跨模块调用,并将响应目的地名称放入请求消息标头中。然后在目标端,当服务调用返回时,SCA运行时将向从请求消息标头中检索到的目的地发送响应。
您可以使用清单12中的示例代码来从消息标头中获取响应目的地名称。消息路由序列关系图如图14所示。
清单12. 用于获取响应目的地的示例代码
SIMessageContext ctx =(SIMessageContext)context;
String responseDestination = ctx.getSIMessage().getUserProperty (“scaTargetDestination”));
图14. 跨模块异步调用的消息流序列关系图:延迟响应
跨模块异步调用:回调
回调调用类似于延迟响应调用,只不过结果将自动传递给调用者。清单13显示了所生成的日志。
清单13. 跨模块回调异步调用的SystemOut日志
[6/2/08 14:01:07:143 CST] 0000006f SystemOut O =====>
destination name:sca/Caller/importlink/CalleeImport
[6/2/08 14:01:07:159 CST] 0000006f SystemOut O =====>
destination name:sca/Callee/exportlink/CalleeExport
[6/2/08 14:01:07:581 CST] 00000077 SystemOut O =====> destination name:sca/Callee
[6/2/08 14:01:07:659 CST] 0000006f SystemOut O =====>
destination name:sca/Caller/component/Caller
[6/2/08 14:01:07:690 CST] 00000077 SystemOut O =====> destination name:sca/Caller
消息路由序列关系图如图15所示。
图15. 跨模块异步调用的消息流序列关系图:回调
结束语
在本文中,您了解了SCA运行时如何处理异步调用,以及SCA运行时如何利用基础的消息系统(WebSphere Process Server)来实现异步调用。架构师可以使用此信息作为参考,从而设计大规模、基于消息的面向服务的体系结构(Service-Oriented Architecture,SOA)。
作者简介
Yu Zhang是IBM中国软件开发实验室的一名软件工程师,他在那里从事IBM WebSphere Process Server方面的工作已超过四年时间。他拥有系统验证测试和客户案例合作项目方面的丰富经验。现在他是负责产品交付的WebSphere Process Server组件技术负责人。
Xiao Li Yu是IBM中国软件开发实验室的一名软件工程师,她在那里从事IBM WebSphere产品方面的工作已超过四年时间。她的工作重点是测试,包括功能验证测试、系统验证测试、压力测试和持久性测试。现在她是WebSphere Process Server的运行时工具测试负责人。
我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。
我原创,你原创,我们的内容世界才会更加精彩!
【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】
微信公众号
TechTarget
官方微博
TechTarget中国
相关推荐
-
事件驱动框架和SOA在空军的应用
空军正在利用SOA来改善数据共享,并实时跟踪战机,美国空军机动司令部的Michael Marek解释了企业可从中学习的经验。
-
揭秘New Relic APM技术细节
New Relic应性能管理(APM)套件主要用于Web软件开发。它允许用户在面向服务的架构(SOA)上跟踪关键事务性能,并且支持代码级别的可见性来评估特定代码段和SQL语句对性能的影响
-
仅凭SOA和云无法解决业务数据管理风险问题
SOA和云可以是某些恼人问题高效的解决方案;这一点我们已经知道了。但是也要记住它们并不是所有事情的直接答案,特别是当你的问题是业务数据管理风险,而不是技术问题时。
-
如何避免云计算与SOA冲突