2011年6月1日星期三

OSB_011:OSB 11g 开发指南之一:如何提高服务的高可用性?

本实验可以看做是实验《SOA Suite 11g 开发指南之十六:与 OSB(Oracle Service Bus)集成 》的继续。

POProcessing上线以后,客户迅猛增加,一些客户开始抱怨访问有时被拒绝。
仔细查看日之后,发现是Validate Credit Card服务不稳定,因为Validate Credit Card服务由第三方提供,并且已经挂接到服务总线上,所以问题不是出现在POProcessing中,那么该如何解决这个问题呢?

1. 手段一:增加多个服务提供者。
考虑到很多家银行都提供信用卡验证服务,我们决定在服务总线上多接入一些信用卡验证服务,这样哪个可以用就用哪个,提高服务的可用性。
而客户依然像平时一样访问POProcessing,无需知道调用的是哪个Validate Credit Card服务,也不需要修改客户端代码。

设计只需做一个小小的改动,如下:



重要步骤说明:

1.1 只需要在OSB上修改Business Service:Transport Configuration



1.2 增加多个Endpoint URI*



1.3 如果一切正常,运行一段时间后,应该能看到多个ValidateForCC服务,平均分配了请求。



2. 手段二:缓存结果到Coherence。
验证信用卡服务需要访问数据库,相对比较耗时,于是一个念头很自然的冒了出来:如果能把那些经常下大订单的VIP用户的信用卡返回信息缓存起来就好了,这样就可以从内存中读取。
OSB提供了这种能力:缓存结果。应用设计如下:



重要步骤说明:
2.1 修改Business Service 配置:
Result Caching:Supported
Cache Token Expression: $body/po:PO_ID
Expiration Time: 1 min


2.2 在Proxy Service的Message Flow中,设计如下:


在Request Pipeline中什么也不做,直接路由到Business Service,拿回响应后,在Response Pipeline中使用Replace Actity替换Header中的内容:
<caching-metadata>
<cache-originated>{$outbound/ctx:transport/ctx:response/tp:cache-originated/text()}</cache-originated>
<cache-token>{$outbound/ctx:transport/ctx:response/tp:cache-token/text()}</cache-token>
</caching-metadata>

2.3 使用另外一个Proxy Service:Test Service 来模拟Business Service最终调用的服务。Message Flow设计如下:
这给我们一个启示:如果Business Service无法访问,我们可以使用一个Proxy Service来模拟该Business Service。



在Request Pipeline中使用Java Call Activity调用一个Java类的sleep()方法,休眠5秒钟。
Java代码如下:

package oracle.osb.timer;

public class TimerImpl {

/**
* Sleep for the specified time (in seconds)
* @param time in seconds to sleep
*/
public static void sleep()
{
try
{
int time = 5;
System.out.println("+++++++++++++++TimerImpl.sleep: START SLEEP FOR " + time + " SECONDS");
Thread.sleep(time * 1000);
System.out.println("+++++++++++++++TimerImpl.sleep: COMPLETED SLEEPING FOR " + time + " SECONDS");
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}

在Response Pipeline中把如下SOAP消息返回:

<soap-env:Body>
<ns1:PurchaseOrder xmlns:ns1="http://xmlns.oracle.com/schemas/PO/">
<ns1:CustID>1111</ns1:CustID>
<ns1:ID>{$body/po:PO_ID/text()}</ns1:ID>
<ns1:productName>Bluetooth Headset</ns1:productName>
<ns1:itemType>Electronics</ns1:itemType>
<ns1:price>49.99</ns1:price>
<ns1:quantity>1</ns1:quantity>
<ns1:status>APPROVED</ns1:status>
<ns1:ccType>Mastercard</ns1:ccType>
<ns1:ccNumber>8765-8765-8765-8765</ns1:ccNumber>
</ns1:PurchaseOrder>
</soap-env:Body>

2.4 测试
使用同一个PO_ID,先后测试两次(两次间隔不超过1分钟),我们会发现第一次5秒钟才返回结果,第2次马上就返回了。这说明Result Cache起作用了。
如果超过一分钟后,再测试,会发现又是5秒钟后才返回结果。
你可以在返回的SOAP Header中看到是否使用了Cache,以及Token值。

没有评论: