Caching Strategies for Oracle Service Bus 11g

by William Markito Oliveira

The right caching strategy can make a big difference in application performance.

Published July 2011

Oracle Service Bus 11g provides built-in cache functionality that utilizes Oracle Coherence, offering first-class support for many caching strategies. This article describes how to use this functionality and explore a fail-over scenario with an example of how caching strategies can speed up your Web services and even prevent production outages.

Requirements

  • Oracle Service Bus 11.1.1.4
  • Oracle Coherence 3.6
  • Oracle WebLogic Server 10.3.4
  • Linux or Windows
  • Oracle Enterprise Pack for Eclipse (OEPE) 3.6

This article is written with the assumption of knowledge in the following areas:

  • Java and Web services
  • Basic Oracle Service Bus knowledge
  • Basic Oracle WebLogic Server administration
 

Our Problematic Web Service

 

In our case study, we have a simple Web Service called CustomerService that is currently with some performance problems and for every request, it is spending nine seconds to respond. Here are the steps to create and simulate this “problematic” Web service:

 

1. Start Oracle Enterprise Pack Eclipse.

2. In the New Project window, select Web Service Project and click Next.

Figure 1 New Web Service Project

3. In the New Web Service Project window:

  • Set the project name to Customer
  • Set Target Runtime to Oracle WebLogic  Server 11gR1 PatchSet 3
  • Click Finish.

4. Right-click in the Customer project and create a new folder called schemas.

5. Create a new XML Schema CustomerType.xsd

Figure 2  New XML Schema

This schema will have the data structure the Web Service will use.

6. Copy and paste the following schema definition into the CustomerType.xsd file:



<schema xmlns="http://www.w3.org/2001/XMLSchema"

                  targetNamespace="http://www.example.org/Customer"

                  xmlns:tns="http://www.example.org/Customer"

                  elementFormDefault="qualified">


                 <element name="customer" type="tns:CustomerType"></element>

                <complexType name="CustomerType">

  <sequence>

  <element name="id" type="int"></element>

  <element name="firstname" type="string"></element>

  <element name="lastname" type="string"></element>

  <element name="address" type="tns:AddressType"></element>

  </sequence>

  </complexType>

  
  <complexType name="AddressType">

  <sequence>

  <element name="street" type="string"></element>

  <element name="country" type="string"></element>

  <element name="city" type="string"></element>

  </sequence>

  </complexType>

  </schema>

  • 7. After pasting the content into CustomerType.xsd, right-click this file and select Generate > JAXB Classes.
  • 8. Set Package field to com.oracle.examples.entities and click Finish.

    Figure 3 Generate Java Classes from XML Schema using JAXB


     
  • 9. The console will output the following results: 


compiling a schema...

com/oracle/examples/entities/AddressType.java

com/oracle/examples/entities/CustomerType.java

com/oracle/examples/entities/ObjectFactory.java

com/oracle/examples/entities/package-info.java

com/oracle/examples/entities/jaxb.properties

  • 10. Select Java Resources under Project Explorer tab and click in WebLogic Web Service to create a new Web Service class.
  • 11. In the New Web Service window set:

    Package: com.oracle.examples.service
    Name: Customer

  • 12. Copy the following code into the Customer.java class created.


import javax.jws.WebMethod;

  import javax.jws.WebService;

  import com.oracle.examples.entities.AddressType;

  import com.oracle.examples.entities.CustomerType;

  import com.oracle.examples.entities.ObjectFactory;
@WebService

  public class Customer {
                 @WebMethod

  public CustomerType getCustomer(int id) {
                                 ObjectFactory factory = new ObjectFactory();
                                    AddressType addressType = factory.createAddressType();

  CustomerType customerType = factory.createCustomerType();
                                   switch (id) {

  case 1:

  addressType.setCity("São Paulo");

  addressType.setCountry("BRA");

  addressType.setStreet("Marginal Pinheiros");
                                                     customerType.setId(1);

  customerType.setFirstname("João");

  customerType.setLastname("Silva");

  customerType.setAddress(addressType);

  break;

  case 2:

  addressType.setCity("San Francisco");

  addressType.setCountry("USA");

  addressType.setStreet("Some address");
                                                     customerType.setId(2);

  customerType.setFirstname("John");

  customerType.setLastname("Lock");

  customerType.setAddress(addressType);

  break;                     

  default:

  break;

  }

  // forcing slow down

  try {

  Thread.currentThread().sleep(9000);

  } catch (InterruptedException e) {

  // TODO Auto-generated catch block

  e.printStackTrace();

  }
                                    return customerType;

  }

  }


This Web service will return fixed values but of course you should do a real Customer search in a database using JPA and/or Oracle TopLink. Also, to simulate the slowness on our Web service there is a Thread.sleep() call that will cause our service to return only after nine seconds.

13. Deploy this project to a running instance of WebLogic Server and hit the URLs below to see the WSDL and test using WebLogic Test Client.

WSDL: http://localhost:7001/Customer/CustomerService?WSDL

TEST URL: http://localhost:7001/wls_utc/?wsdlUrl=http://localhost:7001/Customer/CustomerService?WSDL

Note: You can deploy this project to same server you will be running Oracle Service Bus.

 
 

14. When you invoke the service method getCustomer, you'll notice that it does indeed take nine seconds to execute.

Figure 4 Problematic Web Service Response

In the next section we will import the service into Oracle Service Bus and then learn how service caching can reduce the impact of this performance problem.

Import Web Service Resources

1. Open Oracle Service Bus Console: http://localhost:7001/sbconsole

2. Click in Project Explorer, start a Session and create a new project. Name it Customer for example.

3. Click in the Customer project and look for the Create Resource combo box. Select Resources from URL under Bulk.

4.Fill the form with the following information:

Figure 5 Import WSDL Resource into Oracle Service BUS

5. Click Next and then Import.

Create Proxy and Business Services

  • 1. Click in the Customer project and look for Create Resource combo box. Select Business Service.
    • Service Name: CustomerBS
    • Service Type: WSDL Web Service
  • 2. In the Select WSDL window, select CustomerWSDL.
  • 3. Select CustomerPortBinding and click Submit.
  • 4. Keep the protocol as HTTP and in the Endpoint URI set http://localhost:7001/Customer/CustomerService , which is the URL of the Web service we created in the previous section.

    Figure 6 Business Service Creation

  • 5. Click Last and then Save.
  • 6. Back to the Customer project, Create Resource combo box and now select Proxy Service
    • Service Name: CustomerPS
    • Service Type: Create From Existing Service
  • 7. Select Business Service and point to CustomerBS.
  • 8. We don’t need to modify any settings in the Proxy Service, so you can click Last and then Save.

Activate and Test

  • 1. Click Activate to save the changes done in this session and Submit.
  • 2. Back to the Customer project, click Launch Test Console under Actions column.
  • 3. Now you can execute the Proxy Service and this will call our problematic Web Service. Since we hardcoded only two IDs, you can input only 1 or 2 to get some data in response. Other values will return an empty response document.

    Figure 7 Request with performance problems


    Figure 8 Web Service RESPONSE after nine seconds

Note that all service calls are really taking around nine seconds to execute. Sometimes it can take a little bit longer with an additional one or two seconds, but never less than nine seconds since this is the “response time” of our backend Web service.

In the next section we will demonstrate how Oracle Service Bus and Oracle Coherence are integrated and how you can escalate the solution using an out-of-process caching strategy.

Oracle Coherence Integration

Oracle Service Bus always had some mechanics of caching in order to provide XQuery and XML beans caching, in addition to object caching for Proxy and Business Services classes. But from 11g Release 1 onward, Oracle Service Bus offered an integrated solution for result caching with Oracle Coherence.

The result caching in Oracle Service Bus is available for Business Services. When you enable result caching, the Business Service will not reach the backend service and the response will come from the cache entry. This entry can expire and if the entry is expired, the next service call will indeed reach the backend service and update the cache entry.

Figure 9 How result caching works

Activating Cache for Business Service

To enable result caching for our Business Service follow these steps: 

  • 1. Click Create at Change Center to create a new change session in Oracle Service Bus console.
  • 2. Navigate to Customer project and click CustomerBS Business Service.
  • 3. Click Edit under Message Handling Configuration section.

    Figure 10 Enable Business Service Result Cache

  • 4. Expand Advanced Settings and in Result Caching select Supported.
  • 5. Set the Cache Token Expression: fn:data($body/ser:getCustomer/arg0)

    Figure 11 Business Service Caching Settings

    This will use the customer ID as our unique token for the cache entry. Also, set the Expiration Time for 10 minutes.

  • 6. Click Last >> and Save to confirm the Business Service modifications. You can activate the change session.
  • 7. Now click Launch Test Console for CustomerPS proxy service and let’s test our configurations.

The first time you execute the service, it will take nine seconds to execute and it will populate our cache entry. Click Back in the Test Console and try to execute again; it will show the results immediately, directly from a cache entry in the embedded Oracle Coherence Server running within Oracle Service Bus.  The cache Expiration Time (Time-to-Live) was set to 10 minutes in Step 5, so during this period your calls will not hit the backend Web service.

We have now provided one solution for our problematic service. But what if you want to see what’s going on with you cache, or want to know many entries you have in your cache server?

Coherence Console Integration with Service Bus Cache

Oracle Coherence offers good APIs for JMX and Reports about cache servers, and that’s definitely the way to go for monitoring production environments with huge loads. But for development environments and other critical monitoring situations, you can use the Coherence Console. 

Coherence Console is a self-contained command line utility that connects to specific Coherence Servers. It is a good tool to check which servers are participating in the cluster and for browsing the cache data. That’s the tool we will be using in the example to monitor our cache entries and Coherence servers. 

In order to integrate Coherence Console and Oracle Service Cache you need to specify a few things:

  • 1. Create a file named consoleOSB.sh and paste the following text: 


#!/bin/sh # Middleware home

MDW=/opt/oracle/osb11114


# Service Bus installation folder

OSB=$MDW/Oracle_OSB


# Domain home

DM=/opt/oracle/domains/osb11gR1

# ----------------------------------------------------------------------------

if [ -f $JAVA_HOME/bin/java ]; then

  JAVAEXEC=$JAVA_HOME/bin/java

  else

  JAVAEXEC=java

  fi

  
  OPTS="-Xms64m -Xmx64m

  -Dtangosol.coherence.override=$DM/config/osb/coherence/osb-coherence-override.xml

  -Dtangosol.coherence.cacheconfig=$DM/config/osb/coherence/osb-coherence-cache-config.xml

  -Dtangosol.coherence.distributed.localstorage=false

  -Dtangosol.coherence.cluster=OSB-cluster

  -Dtangosol.coherence.localhost=localhost

  -DOSB.coherence.cluster=OSB-cluster"

CP="$MDW/oracle_common/modules/oracle.coherence_3.6/coherence.jar"

  CP=$CP:"$MDW/modules/features/weblogic.server.modules.coherence.server_10.3.4.0.jar"

  CP=$CP:"$OSB/lib/osb-coherence-client.jar"

  $JAVAEXEC -server -showversion $OPTS -cp $CP com.tangosol.net.CacheFactory $1

  • Note: You do not have to worry about the file location, you can place it anywhere.

  • 2. Modify the script variables according to your installation settings. The variables are:
    • Middleware home - MDW
    • Oracle Service Bus installation directory - OSB
    • Domain Home - DM
  • 3. Give the file execution permission and execute the script in a terminal. You should see an output similar to the following:


markito@anakin:~/Projects/PTS$ ./consoleOSB.sh 
…
2011-06-17 16:14:35.612/0.240 Oracle Coherence 3.6.0.4  (thread=main, member=n/a): Loaded operational configuration from "jar:file:/opt/oracle/osb11114/oracle_common/modules/oracle.coherence_3.6/coherence.jar!/tangosol-coherence.xml"
2011-06-17 16:14:35.621/0.249 Oracle Coherence 3.6.0.4  (thread=main, member=n/a): Loaded operational overrides from 
"file:/opt/oracle/domains/osb11gR1/config/osb/coherence/osb-coherence-override.xml"
2011-06-17 16:14:35.629/0.257 Oracle Coherence 3.6.0.4  (thread=main, member=n/a): Optional configuration override "/custom-mbeans.xml" is not specified

Oracle Coherence Version 3.6.0.4 Build 19111
Grid Edition: Development mode
Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.

2011-06-17 16:14:36.127/0.755 Oracle Coherence GE 3.6.0.4  (thread=main, member=n/a): Local address "127.0.0.1" is a loopback address; 
this cluster node will not connect to nodes located on different machines
2011-06-17 16:14:36.136/0.764 Oracle Coherence GE 3.6.0.4  (thread=main, member=n/a): TCMP bound to /127.0.0.1:7892 using SystemSocketProvider
2011-06-17 16:14:36.445/1.073 Oracle Coherence GE 3.6.0.4  (thread=Cluster, member=n/a): This Member(Id=4, Timestamp=2011-06-17 16:14:36.262, 
Address=127.0.0.1:7892, MachineId=26733, Location=site:localdomain,machine:localhost,process:13130, Role=CoherenceConsole, 
Edition=Grid Edition, Mode=Development, CpuCount=4, SocketCount=2) joined cluster "OSB-cluster" with senior Member(Id=1, Timestamp=2011-06-17 11:00:46.772, 
Address=127.0.0.1:7890, MachineId=26733, Location=site:localdomain,machine:localhost,
process:5603, Role=OSB-node, Edition=Grid Edition, Mode=Development, CpuCount=4, SocketCount=2)
2011-06-17 16:14:36.454/1.082 Oracle Coherence GE 3.6.0.4  (thread=Cluster, member=n/a): Member 1 joined Service Cluster with senior member 1
2011-06-17 16:14:36.454/1.082 Oracle Coherence GE 3.6.0.4  (thread=Cluster, member=n/a): Member 1 joined Service Management with senior member 1
2011-06-17 16:14:36.454/1.082 Oracle Coherence GE 3.6.0.4  (thread=Cluster, member=n/a): Member 1 joined Service ORA-OSB-deployments with senior member 1
2011-06-17 16:14:36.457/1.085 Oracle Coherence GE 3.6.0.4  (thread=main, member=n/a): Started cluster Name=OSB-cluster

WellKnownAddressList(Size=2,
  WKA{Address=127.0.0.1, Port=9999}
  WKA{Address=127.0.0.1, Port=7890}
  )

MasterMemberSet
  (
  ThisMember=Member(Id=4, Timestamp=2011-06-17 16:14:36.262, Address=127.0.0.1:7892, MachineId=26733, 
Location=site:localdomain,machine:localhost,process:13130, Role=CoherenceConsole)
  OldestMember=Member(Id=1, Timestamp=2011-06-17 11:00:46.772, Address=127.0.0.1:7890, 
MachineId=26733, Location=site:localdomain,machine:localhost,process:5603, Role=OSB-node)
  ActualMemberSet=MemberSet(Size=2, BitSetCount=2
    Member(Id=1, Timestamp=2011-06-17 11:00:46.772, Address=127.0.0.1:7890, MachineId=26733, 
Location=site:localdomain,machine:localhost,process:5603, Role=OSB-node)
    Member(Id=4, Timestamp=2011-06-17 16:14:36.262, Address=127.0.0.1:7892, MachineId=26733,
Location=site:localdomain,machine:localhost,process:13130, Role=CoherenceConsole)
    )
  RecycleMillis=1200000
  RecycleSet=MemberSet(Size=0, BitSetCount=0
    )
  )

TcpRing{Connections=[1]}
IpMonitor{AddressListSize=0}

2011-06-17 16:14:36.500/1.128 Oracle Coherence GE 3.6.0.4  (thread=Invocation:Management, member=4): 
Service Management joined the cluster with senior service member 1

Map (?):
  • Now you are connected to the same Oracle Coherence cluster with Oracle Service Bus. There are various commands available for Coherence Console, please check the documentation for a complete list.
  • 4. Let’s check our cache entries. Type cache /osb/service/ResultCache and hit enter: 


Map (?): cache /osb/service/ResultCache

2011-06-17 16:27:25.807/770.435 Oracle Coherence GE 3.6.0.4 <Info> (thread=main, member=4): Loaded cache configuration from "file:/opt/oracle/domains/osb11gR1/config/osb/coherence/osb-coherence-cache-config.xml"

2011-06-17 16:27:26.352/770.980 Oracle Coherence GE 3.6.0.4 <D5> (thread=DistributedCache:ORA-OSB-deployments, member=4): Service ORA-OSB-deployments joined the cluster with senior service member 1

<distributed-scheme>

  <scheme-name>expiring-distributed</scheme-name>

  <service-name>ORA-OSB-deployments</service-name>

  <backing-map-scheme>

    <local-scheme>

      <scheme-ref>expiring-backing-map</scheme-ref>

    </local-scheme>

  </backing-map-scheme>

  <autostart>true</autostart>

</distributed-scheme> 
  • 5. Type list or size commands and you should see no results if you are following our example. That’s because our entries expired (10 minutes, remember?) and we now must execute the Proxy Service CustomerPS again to populate our cache server entries. If your cache is still valid (not expired) you will get different results and of course your entry will be already there.
  • 6. Get back to the Service Bus console, launch the Test Client again and execute CustomerPS.
  • 7. Go to the Coherence Console and type list or size commands. You should see the following output (before and after testing):


Map (/osb/service/ResultCache): size

  0
Map (/osb/service/ResultCache): size

  1
Map (/osb/service/ResultCache): list

  PipelineResultCacheKey[BusinessService Customer/CustomerBS,getCustomer,1) = owner=BusinessService Customer/CustomerBS,value=[B@58c16b18

  • 8. Go back to the Service Bus Test client and try to execute with a different Customer ID that you used in the previous execution. You should see two entries and after 10 minutes, they will expire.

Creating a New External Coherence Server from WebLogic Console

Now that we already have our service cache enabled, we will have a better throughput performance and can attend many more users in our system. However, remember that we are still using an in-process strategy, and that means we are using the same JVM memory for cache entries, WebLogic services like JDBC or JMS, and Oracle Service Bus objects, like transformations, Proxy Services and Business Services. If we increase our cache usage to a high volume, we can potentially run out of memory easily and compromise all other services in the Enterprise Service Bus, even the ones that are not using cache features. 

To solve this situation you can use an external Coherence Server -- that is, a dedicated JVM with its own Coherence Server. This solution can increase the scalability of our overall architecture and a more complex Coherence Cluster infrastructure can take in place.  It is out of the scope of this article discuss the configuration of Coherence Clusters, but it will give an idea of what can be achieved and then adjusted for your situation.

These are the steps to add a new Coherence Server using WebLogic Console:

  • 1. Log into WebLogic console:  http://localhost:7001/console
  • 2. If you are running a domain without a Machine associated in WebLogic, you have to add a machine and associate the Coherence Server with this Machine. Expand Environment in the left menu and select Machines.
  • 3. Fill up the New Machine form with the following information:
    • Name: anakin [replace with your machine name]
    • Machine OS: Unix [replace with your OS]
    • Click Next.

Figure 12 Adding a new machine

  • 4. In the Node Manager Properties form use the following information:
    • Type: Plain [change it to SSL or SSH for production environments]
    • Listen Address: localhost
    • Listen Port: 5556
  • 5. Click Finish.

Figure 13 Node Manager properties

  • Later we will setup the node manager scripts to complete this step.

  • 6. Expand Environment, select Coherence Servers in the left menu and click New.
  • 7. Fill up this form with the following information:
    • Name: server1
    • Machine: anakin [or replace with the machine name used in step 3]
    • Unicast Listen Address: localhost
    • Unicast Listen Port: 9999
    • Click Finish.

Figure 14 Creating a New Coherence Server

  • 8. In the Coherence servers screen, click server1. We need to adjust the class path of this server to integrate with Oracle Service Bus.
  • 9. In the Settings for server1 screen, click the Server Start tab and fill the following fields:
     
    • a. java Home: /opt/oracle/jrockit-jdk1.6.0_20-R28.1.0-4.0.1  
      [set to your java home location]
    • b. OSB Home: /opt/oracle/osb11114/ 
      [set to your Oracle Service Bus installation directory]
    • c. Class Path:  
      
      			
      			/opt/oracle/osb11114/modules/features/weblogic.server.modules.coherence.server_10.3.4.0.jar:/opt/oracle/osb11114/coherence_3.6/lib/coherence.jar:/opt/oracle/osb11114/Oracle_OSB/lib/osb-coherence-client.jar
      			
      [replace /opt/oracle/osb11114/ with your Oracle Service Bus installation directory]
    • d. Arguments:
      
      
            -Dtangosol.coherence.override=/opt/oracle/domains/osb11gR1/config/osb/coherence/osb-coherence-override.xml
      
            -Dtangosol.coherence.cacheconfig=/opt/oracle/domains/osb11gR1/config/osb/coherence/osb-coherence-cache-config.xml
      
            -Dtangosol.coherence.distributed.localstorage=true
      
            -Dtangosol.coherence.cluster=OSB-cluster
      
            -Dtangosol.coherence.localhost=localhost
      
            -DOSB.coherence.cluster=OSB-cluster
      
      
      [replace /opt/domains/osb11gR1/ with your Oracle Service Bus  domain directory]
      Note: 
      In order to use this Coherence server as storage node the tangosol.coherence.distributed.localstorage property needs to be true.
    • e. Click Save.

      Figure 15 Coherence Server settings

  • 10. Now we need to add our new server to the WKA (Well Known Address) list of Coherence Servers in the Oracle Service Bus configuration:
    • In the command terminal, browse to /opt/oracle/domains/osb11gR1/config/osb/coherence
    • Edit the osb-coherence-override.xml file and update according the following snippet: 


<!DOCTYPE coherence SYSTEM "coherence.dtd">

<coherence>

    <cluster-config>

        <!--

            By specifying a well-known-address we disable the mutlicast listener.

            This ensures that the Coherence cluster for OSB will be isolated to this machine only.

        -->

              <unicast-listener>

                      <well-known-addresses>

              <socket-address id="1">

                    <address system-property="OSB.coherence.wka1">127.0.0.1</address>

                    <port system-property="OSB.coherence.wka1.port">7890</port>

                </socket-address>

                <socket-address id="2">

                      <address system-property="OSB.coherence.wka2">127.0.0.1</address>

                      <port system-property="OSB.coherence.wka2.port">9999</port>

                  </socket-address>
                       </well-known-addresses>

  <address system-property="OSB.coherence.localhost">127.0.0.1</address>

  <port system-property="OSB.coherence.localport">7890</port>

  </unicast-listener>

  <multicast-listener>

  <time-to-live system-property="OSB.coherence.ttl">0</time-to-live>

  </multicast-listener>

  </cluster-config>

  </coherence> 
  • Here we are adding a new socket address to the Oracle Coherence cluster. For security and performance reasons, Oracle Coherence server that is bundled with Oracle Service Bus uses WKA and Unicast, so for every new node you add to the cluster this file needs to be updated or make sure that at least one of the nodes specified here is running when trying to start other nodes unlisted. In this case, we are specifying a new server listening in the localhost address (127.0.0.1) and port 9999.

  • Save and close osb-coherence-override.xml. Note: You can also perform the same configuration shown in this step (step 9) through adding two more properties in the Coherence server configuration in WebLogic Console:


  -DOSB.coherence.wka2=localhost

 -DOSB.coherence.wka2.port=9999
  • 11. Now it is time to test all we have done so far, please do the following:
    • Shut down the Oracle Service Bus domain.
    • In a command terminal, browse to /opt/oracle/osb11114/wlserver_10.3/server/bin where /opt/oracle/osb11114/ is your Oracle Service Bus installation directory.
    • Execute the script to start the node manager:

      ./startNodeManager.sh
    • Start your Oracle Service Bus domain.
    • Go to the WebLogic Server console: http://localhost:7001/console
    • Expand Environment in the menu on the left and click Coherence Servers.
    • Click in Control tab, mark server1 and click in Start.
    • Note that the State column value changed to Starting and after a few seconds to Running.

Congratulations, you have a new Coherence Server up and running integrated with Oracle Service Bus, and can manage your server through WebLogic Console with the help of a Node Manager. In the next sections we will test this integration and play with our cache server.

Out-of-process Caching with External Coherence Server

Now it is time to test our out-of-process strategy and execute our problematic Web service again.  Remember that both servers -- the internal server bundled with Oracle Service Bus and the external server1 -- can still store cached data, because they have tangosol.coherence.distributed.localstorage property set to true.

To test your out-of-process cache you can do the following:

  • 1. Open a command terminal and browse to the consoleOSB.sh script that we created before. Execute. You should see the following output: 


………

…

WellKnownAddressList(Size=2,

  WKA{Address=127.0.0.1, Port=7890}

  WKA{Address=127.0.0.1, Port=9999}

  )

MasterMemberSet

  (

  ThisMember=Member(Id=3, Timestamp=2011-06-20 15:03:22.947, Address=127.0.0.1:7894, MachineId=8417, Location=site:localdomain,machine:localhost,process:11912, Role=CoherenceConsole)

  OldestMember=Member(Id=1, Timestamp=2011-06-20 14:34:49.401, Address=127.0.0.1:7890, MachineId=8417, Location=site:localdomain,machine:localhost,process:10716, Role=OSB-node)

  ActualMemberSet=MemberSet(Size=3, BitSetCount=2

  Member(Id=1, Timestamp=2011-06-20 14:34:49.401, Address=127.0.0.1:7890, MachineId=8417, Location=site:localdomain,machine:localhost,process:10716, Role=OSB-node)

      Member(Id=2, Timestamp=2011-06-20 14:47:55.749, Address=127.0.0.1:7892, MachineId=8417, Location=site:localdomain,machine:localhost,process:11562,member:server1, Role=WebLogicWebLogicCacheServer)

  Member(Id=3, Timestamp=2011-06-20 15:03:22.947, Address=127.0.0.1:7894, MachineId=8417, Location=site:localdomain,machine:localhost,process:11912, Role=CoherenceConsole)

  )

  RecycleMillis=1200000

  RecycleSet=MemberSet(Size=0, BitSetCount=0

  )

  )
TcpRing{Connections=[2]}

  IpMonitor{AddressListSize=0}

Note that you now have two address in the Well Know Address List and three members in the Coherence cluster: OSB-node (internal), server1 (external) and CoherenceConsole (which is the console we are using).

  • 2. In the Oracle Coherence Console, enter in Oracle Service Bus ResultCache:  


Map (?): cache /osb/service/ResultCache
  • 3. In the Web browser, login to Oracle Service Bus console: http://localhost:7001/sbconsole.
  • 4. Click Project Explorer, browse to Customer project and Launch Test Console for CustomerPS proxy service.
  • 5. Execute the service and you should experience the nine seconds execution time for the first call. Click Back, execute again, and your result should be immediate, just like previously.
  • 6. Type size or list in the Coherence console and you will see one entry.
  • 7. To validate our external cache server and check if it is working, shut down the Oracle Service Bus domain.
  • 8. Type size or list again in the Coherence console and you should still see one entry. That’s it! The external Coherence Server is now holding our data for 10 minutes.
  • 9. Start Oracle Service Bus domain, login into sbconsole and re-execute CustomerPS proxy service. You will see an immediate response because the data is still coming from the cache and not the backend service. (Note: Remember to use the same customer ID attempted in Step 5, otherwise your call will hit the backend service. )

Set Internal Coherence Server Storage to False

As we can see in the previous section, the external Coherence server (server1) is already taking care of cached data storage. But we are still doing cache in both Coherence servers, internal and external, and for a production environment it may be a good idea to disable the storage of internal Coherence server and free some JVM memory that can be used for other services like JDBC, JMS, or service processing. With this change all cached data will be stored only in the external Coherence server (server1).

To execute these settings follow the steps below:

  • 1. Make sure you have the external Oracle Coherence (server1) already running with storage enabled. Otherwise you will see many exceptions in Oracle Service Bus logs complaining that “Service Result Caching functionality is disabled.” This happens because there will be no cache servers with storage enabled in the Coherence Cluster and because of that caching will not be possible.
  • 2. Open a command terminal and browse to the Oracle Service Bus domain directory.
  • 3. Open /opt/oracle/domains/osb11gR1/bin/startDomainEnv.sh in a text editor and look for the following text:


"${JAVA_OPTIONS} ${JAVA_PROPERTIES} 

-Dwlw.iterativeDev=${iterativeDevFlag}  -Dwlw.testConsole=${testConsoleFlag} 

-Dwlw.logErrorsToConsole=${logErrorsToConsoleFlag} " 
  • 4. Modify this text to look like so:


JAVA_OPTIONS="${JAVA_OPTIONS} ${JAVA_PROPERTIES}  -Dwlw.iterativeDev=${iterativeDevFlag}  -Dwlw.testConsole=${testConsoleFlag} 

-Dwlw.logErrorsToConsole=${logErrorsToConsoleFlag}  -Dtangosol.coherence.distributed.localstorage=false "
  • 5. Save and close the startDomainEnv.sh file.
  • 6. Restart your Oracle Service Bus domain to apply the changes.
  • 7. Once your server is starting, look for the line we modified in step 3 in the starting information that WebLogic outputs. 


/opt/oracle/jrockit-jdk1.6.0_20-R28.1.0-4.0.1/bin/java -jrockit -Xdebug -Xnoagent - 

Xrunjdwp:transport=dt_socket,address=8453, server=y,suspend=n -Djava.compiler=NONE  -Xms648m -Xmx768m - 
Dweblogic.Name=AdminServer -Djava.security.policy=/opt/oracle/osb11114/wlserver_10.3/server/lib/weblogic.policy  - 
Xverify:none -da:org.apache.xmlbeans...   -ea -da:com.bea... -da:javelin... -da:weblogic... -ea:com.bea.wli... - 
ea:com.bea.broker... -ea:com.bea.sbconsole... -Dplatform.home=/opt/oracle/osb11114/wlserver_10.3 - 
Dwls.home=/opt/oracle/osb11114/wlserver_10.3/server -Dweblogic.home=/opt/oracle/osb11114/wlserver_10.3/server  - 
Dcommon.components.home=/opt/oracle/osb11114/oracle_common -Djrf.version=11.1.1 - 
Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.Jdk14Logger -Ddomain.home=/opt/oracle/domains/osb11gR1 - 
Djrockit.optfile=/opt/oracle/osb11114/oracle_common/modules/oracle.jrf_11.1.1/jrocket_optfile.txt - 
Doracle.server.config.dir=/opt/oracle/domains/osb11gR1/config/fmwconfig/servers/AdminServer - 
Doracle.domain.config.dir=/opt/oracle/domains/osb11gR1/config/fmwconfig  - 
Digf.arisidbeans.carmlloc=/opt/oracle/domains/osb11gR1/config/fmwconfig/carml  - 
Digf.arisidstack.home=/opt/oracle/domains/osb11gR1/config/fmwconfig/arisidprovider - 
Doracle.security.jps.config=/opt/oracle/domains/osb11gR1/config/fmwconfig/jps-config.xml - 
Doracle.deployed.app.dir=/opt/oracle/domains/osb11gR1/servers/AdminServer/tmp/_WL_user -Doracle.deployed.app.ext=/- - 
Dweblogic.alternateTypesDirectory=/opt/oracle/osb11114/oracle_common/modules/oracle.ossoiap_11.1.1,/opt/oracle/osb11114/oracle_common/modules/oracle.oamprovider_11.1.1 

-Djava.protocol.handler.pkgs=oracle.mds.net.protocol  -Dweblogic.jdbc.remoteEnabled=false  - 
Dem.oracle.home=/opt/oracle/osb11114/oracle_common -Djava.awt.headless=true -Dweblogic.management.discover=true  - 
Dwlw.iterativeDev= -Dwlw.testConsole= -Dwlw.logErrorsToConsole= -Dtangosol.coherence.distributed.localstorage=false  - 
Dweblogic.ext.dirs=/opt/oracle/osb11114/patch_wls1034/profiles/default/sysext_manifest_classpath:/opt/oracle/osb11114/patch_ocp360/profiles/default/sysext_manifest_classpath  weblogic.Server
  • 8. Now execute the CustomerPS proxy service.
  • 9. Back to the command terminal, execute the consoleOSB.sh(Coherence Console)and type size or list commands. You should still see one entry in the cache but now it is stored only in the external Coherence server (server1) and the Oracle Service Bus internal Coherence server is now acting as client node only.

Conclusion

In this article was presented two different cache strategies and the benefits of using out-of-process caching with Oracle Coherence and Oracle Service Bus. There was an example of a Web service with performance problems exposed in Oracle Service Bus and through the use of result caching the response time improvement is clear. Also, the Oracle Coherence Console integration with Oracle Service Bus is an alternative for development and troubleshooting of service-caching solutions that shows the running servers and cached data information.

Out-of-process caching can drastically reduce the JVM memory footprint of an Oracle Service Bus domain and increase the scalability and fail-over of the architecture, and it is a recommended approach for projects that needs to scale safely.


William Markito Oliveira is a Senior Technologist at Oracle Platform Technology Solutions team in Brazil where he focuses in Middleware, SOA and Java technologies. He is also as contributor to the official Java EE 6 Tutorial providing write-ups and code examples about CDI, EJB 3.1 and JAX-RS.