JBoss application server tutorials

  • Full Screen
  • Wide Screen
  • Narrow Screen
  • Increase font size
  • Default font size
  • Decrease font size

JBoss performance tuning part 2

 

This Performance tuning tutorial is updated to the release 4.x of the application server. If you want to learn all about JBoss 4.x-5.x-6.x Performance tuning, Optimal data Persistence, Clustering tuning, Web application tuning and much more you should not miss the JBoss Performance Tuning book.

 

Read more about the book here

 

 

JBoss Performance Tuning Part 2

Tip 15: Lots of EJB requests ? switch to the PoolInvoker

JBoss uses RMI for EJB communication and by default creates a single thread for every incoming request.

When the number of requests is very large this could be a bottleneck. However you can switch from the standard jrmp service invoker to the pool invoker.


How to do it ? open standardjboss.xml and find the following fragment:

 <invoker-mbean>jboss:service=invoker,type=jrmp</invoker-mbean>


 On JBoss 4.x you should find 4 occurrences of it: stateless-rmi-invoker, clustered-stateless-rmi-invoker, stateful-rmi-invoker,entity-rmi-invoker. Now replace this fragment with :

 <invoker-mbean>jboss:service=invoker,type=pooled</invoker-mbean>

Notice you can even have a mixed environment: that is stateless invocation managed by the pool and all others by jrmp.

If you want to change the default attributes of your pool then open jboss-service.xml

 

 <mbean code="org.jboss.invocation.pooled.server.PooledInvoker"
 name="jboss:service=invoker,type=pooled">
  <attribute name="NumAcceptThreads">1</attribute>
  <attribute name="MaxPoolSize">300</attribute>
  <attribute name="ClientMaxPoolSize">300</attribute>
  <attribute name="SocketTimeout">60000</attribute>
  <attribute name="ServerBindAddress">${jboss.bind.address}</attribute>
  <attribute name="ServerBindPort">4445</attribute>
  <attribute name="ClientConnectAddress">${jboss.bind.address}</attribute>
  <attribute name="ClientConnectPort">0</attribute>
  <attribute name="ClientRetryCount">1</attribute>
  <attribute name="EnableTcpNoDelay">false</attribute>
 </mbean>

 

There are two key attributes for the PooledInvoker in regards to how many threads are used in processing requests.  The first is the NumAcceptThreads attribute.  The value for this attribute will determine how many threads are created to listen for incoming requests. These threads will be the ones that call the accept() method of the server socket (which is a blocking call and will wait there till data is received on the network interface for the server socket).

The MaxPoolSize is the other key factor: it's the size of the pool containing the ServerThreads .
How can MaxPoolSize become a bottleneck ?  if the accept thread can not get a worker thread from the pool and the pool size has reached the MaxPoolSize value, it will wait for one to become available (instead of creating a new one).

 

Tip 16: Have you got readonly Entity Beans ? tell it to JBoss

 

JBoss offers a way to handle this situation by defining either an entire EJB as being "read-only" or simply as a subset of its methods. When accessing a read-only method (or EJB), while JBoss still prevents concurrent access to the same bean instance, the bean will not be enrolled in the transaction and will not be locked during the whole transaction lifetime. Consequently, other transactions can directly use it for their own work.

 

 <enterprise-beans>
 <entity>
 <ejb-name>MyEntity</ejb-name>
 <method-attributes>
 <method>
 <method-name>get*</method-name>
 <read-only>true</read-only>
 </method>
 <method-attributes>
 </entity>
 </enterprise-beans> 

Tip 17: Disable the hot deployer in production


See this tip:
Disable hot deployment on JBoss

 

Tip 18: Configure the EJB container to use cache, when possible.

 

If the EJB container has exclusive access to the persistent store, it doesn’t need to synchronize the in-memory bean state from the persistent store at the beginning of each transaction.
So you could activate the so-called Commit-A option that caches entity bean state between transactions. In order to activate this option :

 

<jboss>
 <enterprise-beans>

 <container-configurations>
 <container-configuration extends=
 "Standard CMP 2.x EntityBean">
 <container-name>CMP 2.x and Cache</container-name>
 <commit-option>A</commit-option>
 </container-configuration>
 </container-configurations>
 
 <entity>
 <ejb-name>MyEntity</ejb-name>
 <configuration-name
 CMP 2.x and Cache</configuration-name>
 <method-attributes>
 <method>
 <method-name>get*</method-name>
 <read-only>true</read-only>
 </method>
 <method-attributes>
 </entity>
</jboss> 

 

Tip 19: Use Cache invalidation in a Cluster for Commit Option A


Commit option A can boost your Entity Bean but what happens when running in a cluster ? in a cluster configuration more than one JBoss node will access the same database. Furthermore, they will not only read data, but may also update the db store.Consequently, we now have as many points of write access to the database as we have JBoss instances in the cluster.

For these scenarios, JBoss incorporates a handy tool: the cache invalidation framework. It provides automatic invalidation of cache entries in a single node or across a cluster of JBoss instances. As soon as an entity bean is modified on a node, an invalidation message is automatically sent to all related containers in the cluster and the related entry is removed from the cache. The next time the data is required by a node, it will not be found in cache, and will be reloaded from the database.

In order to activate it, add to your Entity Bean the cache-invalidation tag.

 

 <entity>
 <ejb-name>MyEntity</ejb-name>
 <configuration-name>
 Standard CMP 2.x with cache invalidation
 </configuration-name>
 <method-attributes>
 <method>
 <method-name>get*</method-name>
 <read-only>true</read-only>
 </method>
 <method-attributes>
 <cache-invalidation>True</cache-invalidation>
 </entity>

 

Tip 20: Synchronize at commit time when possible.


The sync-on-commit-only element configures a performance optimization that will cause entity bean state to be synchronized with the database only at commit time. Normally the state of all the beans in a transaction would need to be synchronized when an finder method is called or when an remove method is called :

 <container-configuration>
 <container-name>Standard Pessimistic CMP 2.x EntityBean</container-name>
 <call-logging>false</call-logging>
 <invoker-proxy-binding-name>entity-pooled-invoker</invoker-proxy-binding-name>
 <sync-on-commit-only>true</sync-on-commit-only>
 ....   
 </container-configuration> 

 

Tip 21: Use Prepared Statement Cache:

 

In JBoss, by default,prepared statements are not cached. To improve performance one can configure a prepared statement cache of an arbitrary size. You can use in your -ds.xml file the <prepared-statement-cache-size> : this is the number of prepared statements per connection to be kept open and reused in subsequent requests.

Tip 22: Remove services you don't need

 

JBoss ships with lots of services, however you'll seldom need to use them all. The service is usually deployed as *-service.xml under the deploy directory. Sometimes it's also deployed as .sar/.rar archive.
In order to remove the service, remove the file in the "Server/deploy" column. If needed remove also the relative libs stated under "Server/lib

Servizio
Server/deploy
Server/lib
Mail service
mail-service.xml
mail-plugin.jar, mail.jar,activation.jar
Cache invalidation service
cache-invalidation-service.xml
 
J2EE client deployer service
client-deployer-service.xml
 
Hibernate HAR support
hibernate-deployer-service.xml
jboss-hibernate.jar, hibernate2.jar, cglib-full-2.0.1.jar, odmg-3.0.jar
HSQL DB
hsqldb-ds.xml
hsqldb-plugin.jar, hsqldb.jar
Default JMS Service
jms folder
jbossmq.jar
HTTP Invoker (tunnels RMI through HTTP)
http-invoker.sar
 
XA Datasources
jboss-xa-jdbc.rar
 
JMX Console
jmx-console.war
 
Web Console
management/web-console.war
 
JSR-77
management/console-mgr.sar
 
Monitoring mail alerts
monitoring-service.xml
jboss-monitoring.jar
Schedule Manager
schedule-manager-service.xml
scheduler-plugin.jar, scheduler-plugin-example.jar
Sample Schedule service
scheduler-service.xml
 


If you are removing a core JBoss service like JMS or EAR Deployer then you need to remove it also from the jboss-service.xml :

 <mbean code="org.jboss.management.j2ee.LocalJBossServerDomain"
 name="jboss.management.local:j2eeType=J2EEDomain,name=Manager">
 <attribute name="MainDeployer">jboss.system:service=MainDeployer</attribute>
 <attribute name="SARDeployer">jboss.system:service=ServiceDeployer</attribute>
 <attribute name="EARDeployer">jboss.j2ee:service=EARDeployer</attribute>
 <attribute name="EJBDeployer">jboss.ejb:service=EJBDeployer</attribute>
 <attribute name="RARDeployer">jboss.jca:service=RARDeployer</attribute>
 <attribute name="CMDeployer">jboss.jca:service=ConnectionFactoryDeployer</attribute>
 <attribute name="WARDeployer">jboss.web:service=WebServer</attribute>
 <attribute name="CARDeployer">jboss.j2ee:service=ClientDeployer</attribute>
 <attribute name="MailService">jboss:service=Mail</attribute>
 <attribute name="JMSService">jboss.mq:service=DestinationManager</attribute>
 <attribute name="JNDIService">jboss:service=Naming</attribute>
 <attribute name="JTAService">jboss:service=TransactionManager</attribute>
 <attribute name="UserTransactionService">jboss:service=ClientUserTransaction</attribute>
 <attribute name="RMI_IIOPService">jboss:service=CorbaORB</attribute>
 </mbean>

Simply comment the attribute relative to the unwanted service

Tip 22: Tell log4j to shut up !

Wel not really anyway Log4j uses a valuable amount of time/CPU so you had better remove unnecessary logs, for example :

  • Remove logs from Console

Comment the following line in log4j.xml in order to remove logs on the Console:

<root> 
  <!-- <appender-ref ref=CONSOLE"></appender-ref>  -->
   <appender-ref ref="FILE"></appender-ref> 
 </root>

remove also the relative appender:

<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender"> 
 ....
</appender>

  • Raise log priority

Consider raising the log level to the highest level possible in production. Here only error logs are written:

<root> 
   <priority value="ERROR" ></priority> 
   <!--<appender-ref ref="CONSOLE"></appender-ref> --> 
   <appender-ref ref="FILE"></appender-ref> 
 </root>

Read more about Performance tuning book here

{fcomment}<
Advertisement

JBoss performance tuning part 2
Francesco Google+
Top Programming Sites
You are here Home