cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache CXF > Scalable CXF consumer and producer using JMS transport
Date Sun, 02 Oct 2011 12:32:00 GMT
<html>
<head>
    <base href="https://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/2042/9/15/_/styles/combined.css?spaceKey=CXF&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://cwiki.apache.org/confluence/display/CXF/Scalable+CXF+consumer+and+producer+using+JMS+transport">Scalable
CXF consumer and producer using JMS transport</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~ashakirin">Andrei
Shakirin</a>
    </h4>
        <br/>
                         <h4>Changes (6)</h4>
                                 
    
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
    
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >{code} <br>CXF client and server
implemented in java or using Spring configuration magically work for this WSDL (under the
hood CXF selects correct JMS Conduit and Destination based on address URL).  <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">Details
are described in http://cxf.apache.org/docs/jms-transport.html. <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">Details
are described in http://cxf.apache.org/docs/jms-transport.html.</span> CXF also delivers
jms_pubsub and jms_pubsub examples illustrating using JMS transport with default settings
for ActiveMQ. <br></td></tr>
            <tr><td class="diff-unchanged" > <br>h2. Scalability problems
<br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" > <br>h2. CXF Features <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">As
far as CXF JMS implementation is Spring based, user can benefit from described Spring JMS
functionality. <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">As
far as</span> CXF <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">JMS
implementation is Spring based, user can benefit from described Spring JMS functionality.
CXF</span> provides a possibility to configure different Spring aspects in JMS transport
using Features. A Feature is something that is able to customize a Server, Client, or Bus,
typically adding capabilities. In our case we will add Feature in ws:endpoint and ws:client
to tune JMS transport. <br></td></tr>
            <tr><td class="diff-unchanged" > <br>h3. Server configuration
<br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >{code} <br> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">You
can see that endpoint configuration containing JMSConfigFeature feature that has a JMSConfiguration
property. <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">You
can see that endpoint configuration containing JMSConfigFeature feature that has a</span>
JMSConfiguration <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">property.
JMSConfiguration</span> supports all settings that we have seen in Spring DefaultMessageListenerContainer:
cached connection factory with session pool size, number of concurrent consumers, cache level.
All settings of JMSConfiguration are described in details in http://cxf.apache.org/docs/using-the-jmsconfigfeature.html.
<br></td></tr>
            <tr><td class="diff-unchanged" >Using this configuration server application
can be tuned to achieve optimal performance in target environment. <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <p>Java Message Service (JMS) is wide spread and popular messaging java interface.
As far as JMS is standardized in JEE, the same application code can successfully work with
different JMS implementations: WS MQ, Active MQ, Tibco, Joram, BEA WebLogic, OpenJMS.<br/>
CXF provides a transport that enables endpoints to use JMS queues and topics. </p>

<h2><a name="ScalableCXFconsumerandproducerusingJMStransport-DefaultCXFconsumerandprocuderusingJMS"></a>Default
CXF consumer and procuder using JMS</h2>
<p>Implementing CXF client and service using JMS transport is trivial.<br/>
Basically, it is enough to configure two things in WSDL: <br/>
a) specify jms transport URI in binding element;<br/>
b) define jms address in port element.<br/>
WSDL binding and port should look like:</p>

<div class="code panel" style="border-style: solid;border-width: 1px;"><div class="codeContent
panelContent">
<pre class="code-java">
&lt;wsdl:binding name=<span class="code-quote">"Greeter_SOAPBinding"</span>
type=<span class="code-quote">"tns:Greeter"</span>&gt;
        &lt;soap:binding style=<span class="code-quote">"document"</span>
transport=<span class="code-quote">"http:<span class="code-comment">//cxf.apache.org/transports/jms"</span>/&gt;
</span>…
&lt;/wsdl:binding&gt;

&lt;wsdl:service name=<span class="code-quote">"JMSGreeterService"</span>&gt;
        &lt;wsdl:port binding=<span class="code-quote">"tns:JMSGreeterPortBinding"</span>
name=<span class="code-quote">"GreeterPort"</span>&gt;
            &lt;jms:address
                destinationStyle=<span class="code-quote">"queue"</span>
                jndiConnectionFactoryName=<span class="code-quote">"ConnectionFactory"</span>

jndiDestinationName=<span class="code-quote">"dynamicQueues/test.cxf.jmstransport.queue"</span>&gt;
               &lt;jms:JMSNamingProperty name=<span class="code-quote">"java.naming.factory.initial"</span>
value=<span class="code-quote">"org.apache.activemq.jndi.ActiveMQInitialContextFactory"</span>/&gt;
                  &lt;jms:JMSNamingProperty name=<span class="code-quote">"java.naming.provider.url"</span>
value=<span class="code-quote">"tcp:<span class="code-comment">//localhost:61616"</span>/&gt;
</span>           &lt;/jms:address&gt;
        &lt;/wsdl:port&gt;
 &lt;/wsdl:service&gt;
</pre>
</div></div>
<p>CXF client and server implemented in java or using Spring configuration magically
work for this WSDL (under the hood CXF selects correct JMS Conduit and Destination based on
address URL). <br/>
Details are described in <a href="http://cxf.apache.org/docs/jms-transport.html" class="external-link"
rel="nofollow">http://cxf.apache.org/docs/jms-transport.html</a>.<br/>
CXF also delivers jms_pubsub and jms_pubsub examples illustrating using JMS transport with
default settings for ActiveMQ.</p>

<h2><a name="ScalableCXFconsumerandproducerusingJMStransport-Scalabilityproblems"></a>Scalability
problems</h2>
<p>Unfortunately there are two main scalability drawbacks in default JMS configuration:</p>
<ol>
	<li>It doesn't provide sessions pooling and consumers/producers cache.</li>
	<li>Default JMS message consumer is single threaded. It means that only one thread
will get messages from the queue or topic and pass them to further processing.</li>
</ol>


<p>Both aspects are critical for enterprise application and their implementation is
not easy task. Is there any solution? Yes: Spring JMS functionality and CXF Features. Let
discuss them in detail.</p>

<h2><a name="ScalableCXFconsumerandproducerusingJMStransport-SpringJMSfunctionality"></a>Spring
JMS functionality</h2>
<p>Spring provides a number of useful classes that helps to implement scalable JMS application.
Important for us are: org.springframework.jms.connection.CachingConnectionFactory<br/>
org.springframework.jms.listener.DefaultMessageListenerContainer</p>

<h3><a name="ScalableCXFconsumerandproducerusingJMStransport-CachingConnectionFactory"></a>CachingConnectionFactory
</h3>
<p>CachingConnectionFactory provides sessions pool, consumers and producers cache. Bellow
is a sample configuration of CachingConnectionFactory:</p>

<div class="code panel" style="border-style: solid;border-width: 1px;"><div class="codeContent
panelContent">
<pre class="code-java">
&lt;bean id=<span class="code-quote">"cachingConnectionFactory"</span> class=<span
class="code-quote">"org.springframework.jms.connection.CachingConnectionFactory"</span>&gt;
	&lt;property name=<span class="code-quote">"targetConnectionFactory"</span>&gt;
		&lt;bean class=<span class="code-quote">"org.apache.activemq.ActiveMQConnectionFactory"</span>&gt;
			&lt;property name=<span class="code-quote">"brokerURL"</span> value=<span
class="code-quote">"tcp:<span class="code-comment">//localhost:61616"</span>
/&gt;
</span>		&lt;/bean&gt;
	&lt;/property&gt;
	&lt;property name=<span class="code-quote">"sessionCacheSize"</span> value=<span
class="code-quote">"20"</span>/&gt;
	&lt;property name=<span class="code-quote">"cacheProducers"</span> value=<span
class="code-quote">"<span class="code-keyword">true</span>"</span>/&gt;
	&lt;property name=<span class="code-quote">"cacheConsumers"</span> value=<span
class="code-quote">"<span class="code-keyword">true</span>"</span>/&gt;
&lt;/bean&gt;
</pre>
</div></div>

<p>As you can see it is possible to set size of session pool and switch on producers
and consumers caching.</p>

<h3><a name="ScalableCXFconsumerandproducerusingJMStransport-DefaultMessageListenerContainer"></a>DefaultMessageListenerContainer</h3>
<p>DefaultMessageListenerContainer enables getting messages from the destination in
parallel, using multiple threads.<br/>
Configuration of DefaultMessageListenerContainer looks like:</p>
<div class="code panel" style="border-style: solid;border-width: 1px;"><div class="codeContent
panelContent">
<pre class="code-java">
&lt;bean id=<span class="code-quote">"queueContainerListener"</span>
	class=<span class="code-quote">"org.springframework.jms.listener.DefaultMessageListenerContainer"</span>&gt;
		&lt;property name=<span class="code-quote">"connectionFactory"</span> ref=<span
class="code-quote">"connectionFactory"</span> /&gt;
		&lt;property name=<span class="code-quote">"destinationName"</span> value=<span
class="code-quote">"Q_WM_OUT"</span> /&gt;
		&lt;property name=<span class="code-quote">"messageListener"</span> ref=<span
class="code-quote">"simpleListener"</span> /&gt;
		&lt;property name=<span class="code-quote">"cacheLevel"</span> value=<span
class="code-quote">"3"</span> /&gt;
		&lt;property name=<span class="code-quote">"concurrentConsumers"</span>
value=<span class="code-quote">"10"</span> /&gt;
		&lt;property name=<span class="code-quote">"maxConcurrentConsumers"</span>
value=<span class="code-quote">"50"</span> /&gt;
&lt;/bean&gt;	
</pre>
</div></div>
<p>It is possible to define initial and maximal number of concurrent message consumer
threads, cache level (3- cache consumers, 2 – cache session, 1 – no caching), specify
message listener class (implementing MessageListener interface) and connection factory.<br/>
You can see that Spring provides solution for both mentioned scalability aspects. But how
we can use it in CXF? </p>

<h2><a name="ScalableCXFconsumerandproducerusingJMStransport-CXFFeatures"></a>CXF
Features</h2>
<p>As far as CXF JMS implementation is Spring based, user can benefit from described
Spring JMS functionality.<br/>
CXF provides a possibility to configure different Spring aspects in JMS transport using Features.
A Feature is something that is able to customize a Server, Client, or Bus, typically adding
capabilities. In our case we will add Feature in ws:endpoint and ws:client to tune JMS transport.</p>

<h3><a name="ScalableCXFconsumerandproducerusingJMStransport-Serverconfiguration"></a>Server
configuration</h3>

<div class="code panel" style="border-style: solid;border-width: 1px;"><div class="codeContent
panelContent">
<pre class="code-java">
&lt;bean id=<span class="code-quote">"cachingConnectionFactory"</span> class=<span
class="code-quote">"org.springframework.jms.connection.CachingConnectionFactory"</span>&gt;
	&lt;property name=<span class="code-quote">"targetConnectionFactory"</span>&gt;
		&lt;bean class=<span class="code-quote">"org.apache.activemq.ActiveMQConnectionFactory"</span>&gt;
			&lt;property name=<span class="code-quote">"brokerURL"</span> value=<span
class="code-quote">"tcp:<span class="code-comment">//localhost:61616"</span>
/&gt;
</span>		&lt;/bean&gt;
	&lt;/property&gt;
	&lt;property name=<span class="code-quote">"sessionCacheSize"</span> value=<span
class="code-quote">"20"</span>/&gt;
	&lt;property name=<span class="code-quote">"cacheConsumers"</span> value=<span
class="code-quote">"<span class="code-keyword">true</span>"</span>/&gt;
&lt;/bean&gt;

&lt;bean id=<span class="code-quote">"jmsConfig"</span> class=<span class="code-quote">"org.apache.cxf.transport.jms.JMSConfiguration"</span>
		p:connectionFactory-ref=<span class="code-quote">"cachingConnectionFactory"</span>
		p:cacheLevel=<span class="code-quote">"3"</span> 
		p:concurrentConsumers=<span class="code-quote">"16"</span>
		p:maxConcurrentConsumers=<span class="code-quote">"16"</span>
		p:targetDestination=<span class="code-quote">"Q_HSC"</span>
		p:wrapInSingleConnectionFactory=<span class="code-quote">"<span class="code-keyword">false</span>"</span>
	/&gt;

&lt;jaxws:endpoint id=<span class="code-quote">" JMSGreeterService"</span>
address=<span class="code-quote">"jms:<span class="code-comment">//"</span>
</span>		implementor=<span class="code-quote">"#JMSGreeterServiceImpl"</span>&gt;
		&lt;jaxws:features&gt;
			&lt;bean class=<span class="code-quote">"org.apache.cxf.transport.jms.JMSConfigFeature"</span>&gt;
				&lt;p:jmsConfig-ref=<span class="code-quote">"jmsConfig"</span>&gt;
			&lt;/bean&gt;
		&lt;/jaxws:features&gt;
&lt;/jaxws:endpoint&gt;
</pre>
</div></div>

<p>You can see that endpoint configuration containing JMSConfigFeature feature that
has a JMSConfiguration property.<br/>
JMSConfiguration supports all settings that we have seen in Spring DefaultMessageListenerContainer:
cached connection factory with session pool size, number of concurrent consumers, cache level.
All settings of JMSConfiguration are described in details in <a href="http://cxf.apache.org/docs/using-the-jmsconfigfeature.html"
class="external-link" rel="nofollow">http://cxf.apache.org/docs/using-the-jmsconfigfeature.html</a>.<br/>
Using this configuration server application can be tuned to achieve optimal performance in
target environment.</p>

<h3><a name="ScalableCXFconsumerandproducerusingJMStransport-Clientconfiguration"></a>Client
configuration</h3>

<div class="code panel" style="border-style: solid;border-width: 1px;"><div class="codeContent
panelContent">
<pre class="code-java">
&lt;bean id=<span class="code-quote">"cachingConnectionFactory"</span> class=<span
class="code-quote">"org.springframework.jms.connection.CachingConnectionFactory"</span>&gt;
	&lt;property name=<span class="code-quote">"targetConnectionFactory"</span>&gt;
		&lt;bean class=<span class="code-quote">"org.apache.activemq.ActiveMQConnectionFactory"</span>&gt;
			&lt;property name=<span class="code-quote">"brokerURL"</span> value=<span
class="code-quote">"tcp:<span class="code-comment">//localhost:61616"</span>
/&gt;
</span>		&lt;/bean&gt;
	&lt;/property&gt;
	&lt;property name=<span class="code-quote">"sessionCacheSize"</span> value=<span
class="code-quote">"20"</span>/&gt;
	&lt;property name=<span class="code-quote">"cacheProducers"</span> value=<span
class="code-quote">"<span class="code-keyword">true</span>"</span>/&gt;
&lt;/bean&gt;

&lt;bean id=<span class="code-quote">"jmsConfig"</span> class=<span class="code-quote">"org.apache.cxf.transport.jms.JMSConfiguration"</span>
p:connectionFactory-ref=<span class="code-quote">"connectionFactory"</span> p:targetDestination=<span
class="code-quote">"Q_HSC"</span>
		p:wrapInSingleConnectionFactory=<span class="code-quote">"<span class="code-keyword">false</span>"</span>
/&gt; 

&lt;jaxws:client id=<span class="code-quote">"JMSGreeterService"</span> address=<span
class="code-quote">"jms:<span class="code-comment">//"</span>
</span>	serviceClass="com.sopera.services.tpoc.eventgenerator.EventGenerator”&gt;
		&lt;jaxws:features&gt;
			&lt;bean class=<span class="code-quote">"org.apache.cxf.transport.jms.JMSConfigFeature"</span>&gt;
				&lt;property name=<span class="code-quote">"jmsConfig"</span> ref=<span
class="code-quote">"jmsConfig"</span>/&gt;
			&lt;/bean&gt;
		&lt;/jaxws:features&gt;
	&lt;/jaxws:client&gt;
</pre>
</div></div>

<p>Client configuration looks very similar to the server one except two things:</p>
<ol>
	<li>CachingConnectionFactory  activates producers caching instead consumers caching;</li>
	<li>JMSConfiguration hasn’t concurrent consumers settings: client concurrency is
under application control and can be implemented using standard Java concurrency API.</li>
</ol>



<p>h2 Conclusion<br/>
It is possible to achieve scalability of CXF client and service using Spring JMS functionality
and CXF JMS Configuration Feature. <br/>
It is not necessary to write any line of code, just configure and leverage already existing
stuff.</p>

<h2><a name="ScalableCXFconsumerandproducerusingJMStransport-References"></a>References</h2>
<ol>
	<li>CXF JMS Transport: <a href="http://cxf.apache.org/docs/jms-transport.html" class="external-link"
rel="nofollow">http://cxf.apache.org/docs/jms-transport.html</a></li>
	<li>CXF Features: <a href="http://cxf.apache.org/docs/features.html" class="external-link"
rel="nofollow">http://cxf.apache.org/docs/features.html</a></li>
	<li>Spring JMS functionality: <a href="http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/jms.html"
class="external-link" rel="nofollow">http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/jms.html</a></li>
</ol>

    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href="https://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
        </div>
        <a href="https://cwiki.apache.org/confluence/display/CXF/Scalable+CXF+consumer+and+producer+using+JMS+transport">View
Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=27828015&revisedVersion=6&originalVersion=5">View
Changes</a>
                |
        <a href="https://cwiki.apache.org/confluence/display/CXF/Scalable+CXF+consumer+and+producer+using+JMS+transport?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message