Sunday, June 13, 2010

OSB and Coherence, a real life scenario with performance data

Here you have a sample project that you can explore and play with. I also log if the cache was hit or missed.

Make sure you enable Caching in OSB: "Operations/Global Settings/Enable Result Caching".

You can configure caching only at Business Service level:

and make sure you extract the Cache Token (a unique ID for the request) from the payload.

Make sure you read this:

in order to test result caching, do not invoke the business service directly from the test console

You should then create a PS with a routing node pointing to the BS, and using inbound operation for outbound.

The configuration is:

GeoOsbServicePS is the actual service
GeoOsbServiceBS is the BS with caching enabled, and pointing to GeoOsbServicePS
GeoOsbServiceWithCachePS is simply a facade to expose the GeoOsbServiceBS

Test with cache:

Test without cache:

Using SoapUI I am injecting a 5 Threads load, first on the GeoOsbServicePS Proxy Service (no cache) and then on the GeoOsbServiceWithCachePS. These are the average response times measured:

GeoOsbServicePS : 47 ms
GeoOsbServiceWithCachePS : 13 ms

I was requesting over and over the same data.... for a more realistic test we should try requesting a variety of data.... the improvement of course will heavily depend on the hit/miss ratio.... if the overhead introduced by the extra PS and the caching layer is not justified by the percentage of hits, then performance will be deteriorated...

It is particurarly fascinating to observe the outbound message to the BS:

cache token in this case is the unique identifier extracted from the payload, and the TTL in cache is set to 30 minutes

<tran:cache-token xmlns:tran="">2</tran:cache-token>
<tran:cache-ttl xmlns:tran="">PT30M</tran:cache-ttl>

the outbound response contains:

<tran:cache-originated xmlns:tran="">false</tran:cache-originated>

the first time, and for subsequent invocations it becomes true.

Which Cache Token Expression are you allowed to use? Not any user defined expression, but only one dependent on:
$body, $header, $operation or $metadata.

otherwise you will get a OSB Kernel BEA-398311 error
Cache Token expression is using invalid variable variableName.

The good thing is that you can use a single BS to cache the result of multiple operations on an external service, since the actual token used in Coherence will be made by your Cache Token + Operation + BS Identifier, so there is no chance that two different operations conflict with each other because they provide the same token.

When you start your OSB server, you should find this:

<13-06-2010 16:05:25 CEST> <Info> <Coherence> <BEA-000000> <Oracle Coherence 3.5.3/465p2 (member=n/a): Loaded operational configuration from resource "zip:C:/bea11/coherence_3.5/lib/coherence.jar!/tangosol-coherence.xml">

<13-06-2010 16:05:25 CEST> <Info> <Coherence> <BEA-000000> <Oracle Coherence 3.5.3/465p2 (member=n/a): Loaded operational overrides from resource "zip:C:/bea11/coherence_3.5/lib/coherence.jar!/tangosol-coherence-override-dev.xml">

<13-06-2010 16:05:25 CEST> <Info> <Coherence> <BEA-000000> <Oracle Coherence 3.5.3/465p2 (member=n/a): Loaded operational overrides from resource "zip:C:/bea11/user_projects/domains/osbdomain/servers/AdminServer/tmp/_WL_user/ALSB Coherence Cache Provider/sm027g/APP-INF/lib/com.bea.alsb.coherence-impl.jar!/tangosol-coherence-override.xml">

<13-06-2010 16:05:25 CEST> <Info> <Coherence> <BEA-000000> <Oracle Coherence 3.5.3/465p2 (member=n/a): Loaded operational overrides from resource "file:/C:/bea11/user_projects/domains/osbdomain/config/osb/coherence/osb-coherence-override.xml">

<13-06-2010 16:05:26 CEST> <Warning> <Coherence> <BEA-000000> <Oracle Coherence 3.5.3/465p2 (member=n/a): Local address "
" is a loopback address; this cluster node will not connect to nodes located on different machines>

<13-06-2010 16:05:29 CEST> <Info> <Coherence> <BEA-000000> <Oracle Coherence 3.5.3/465p2 (member=n/a): Created a new cluster "OSB-
cluster" with Member(Id=1, Timestamp=2010-06-13 16:05:26.258, Address=, MachineId=50080, Location=machine:localhost,
process:4468, Role=OSB-node, Edition=Grid Edition, Mode=Development, CpuCount=2, SocketCount=2) UID=0x7F0000010000012931A11172C3A0
<13-06-2010 16:05:30 CEST> <Info> <OSB Coherence WebLogic> <BEA-2032482> <The OSB Coherence Cache Provider has been initialized wi
th com.bea.alsb.coherence.impl.CoherenceProvider: SafeCluster: Name=OSB-cluster

WKA{Address=, Port=7890}

ThisMember=Member(Id=1, Timestamp=2010-06-13 16:05:26.258, Address=, MachineId=50080, Location=machine:localhost,p
rocess:4468, Role=OSB-node)
OldestMember=Member(Id=1, Timestamp=2010-06-13 16:05:26.258, Address=, MachineId=50080, Location=machine:localhost
,process:4468, Role=OSB-node)
ActualMemberSet=MemberSet(Size=1, BitSetCount=2
Member(Id=1, Timestamp=2010-06-13 16:05:26.258, Address=, MachineId=50080, Location=machine:localhost,process:44
68, Role=OSB-node)
RecycleSet=MemberSet(Size=0, BitSetCount=0

TcpRing{TcpSocketAccepter{State=STATE_OPEN, ServerSocket=}, Connections=[]}
ClusterService{Name=Cluster, State=(SERVICE_STARTED, STATE_JOINED), Id=0, Version=3.5, OldestMemberId=1}
InvocationService{Name=Management, State=(SERVICE_STARTED), Id=1, Version=3.1, OldestMemberId=1}


Narasimha Dasari said...

Excample is simple and very descriptive to explian how cache works.thanks for that.

it would be nice if you can post similar example how to use cahe in java callout with sample java class and the setup.

Yuan Meng said...
This comment has been removed by the author.
Yuan Meng said...

My cache test works. I use coherence command console to list all entries in the cache ( This is what i see with your example:
Map (/osb/service/ResultCache): list
PipelineResultCacheKey[BusinessService cachingTests/CachingBS,NewOperation1, foo) = owner=BusinessService cachingTests/CachingBS,value=[B@8497904

Do you know in this case, what's the key for the cache entry?

Oracle document is blury on what the key is exactly: "Each cached result is uniquely identified by a cache key that is made up of the
ServiceRef (the unique identifier for the service which is the fully qualified path name
of the service), the operation being invoked, and a cache token String."

I have tried a couple of combinations, they don't work. The reason I look for the key is to remove the entry from the cache.