锘??xml version="1.0" encoding="utf-8" standalone="yes"?>
This advice is primarily on how to tune and/or slim JBossAS. The two concepts are orthogonal in most cases. While reducing idle service threads through slimming won't have a large impact on performance, using less memory and resources may allow you to tune other performance aspects. Of course this does reduce startup time. Furthermore, as a general security concept -- remove services you don't use. We will separate the two categories: slimming and tuning. We start by using the default configuration and trimming from there (for clustering that will be the topic of a later wiki page ;-) ). This advice does not involve areas of tuning that crosscut developer and administrative roles (application tuning such as cache sizes). This is primarily advice for administrative tuning.
Note for those concerned that this advice will make a technically non-J2EE-compliant instance of JBoss (3.2.6 is not compliant anyhow) as removing key J2EE services would cause JBoss to fail the TCK. Most performance tuning/administrative tasks done in real-world installations technically fall in this category.
Assume that you have copied the server/default directory and its subdirectories to server/slim.
If you are running JBoss AS on a Linux server, you should read this article written by Andrew Oliver, one of JBoss, a division of Red Hat, consultants on how tune JBoss/Java in a Linux server
<Connector port="8080" address="${jboss.bind.address}" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" redirectPort="8443" acceptCount="100" connectionTimeout="20000" disableUploadTimeout="true"/>
minSpareThreadsmeans "on start up, always keep at least this many threads waiting idle"
maxSpareThreadsmeans "if we ever go above minSpareThreads then always keep maxSpareThreads waiting idle"
By default, JBoss creates a new thread for every RMI request that comes in. This is not generally efficient on a large system. Secondly, it can be dangerous to allow unrestrained connections in the case of performance or traffic spikes or run-away connection creating clients. To remedy this you should consider switching to the pooled invoker.
<invoker-mbean>jboss:service=invoker,type=jrmp</invoker-mbean>
to
<invoker-mbean>jboss:service=invoker,type=pooled</invoker-mbean>
JBoss also has a mostly undocumented PooledInvokerHA you may try.
Logging has a profound effect on performance. Changing the logging level to TRACE can bring the JBossAS to a crawl. Changing it to ERROR (or WARN) can speed things up dramatically.
To turn off console logging:
<root> <appender-ref ref=CONSOLE"/> <appender-ref ref="FILE"/> </root>
make it read
<root> <appender-ref ref="FILE"/> </root>
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender"> <errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/> <param name="Target" value="System.out"/> <param name="Threshold" value="INFO"/> <layout class="org.apache.log4j.PatternLayout"> <!-- The default pattern: Date Priority [Category] Message\n --> <param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}] %m%n"/> </layout> </appender>
To change the log level:
<category name="org.apache"> <priority value="INFO"/> </category> <!-- Limit org.jgroups category to INFO --> <category name="org.jgroups"> <priority value="INFO"/> </category>
<root> <appender-ref ref="CONSOLE"/> <!-- you may have removed this earlier --> <appender-ref ref="FILE"/> </root>
to look like this
<root> <priority value="ERROR" /> <appender-ref ref="CONSOLE"/> <!-- you may have removed this earlier --> <appender-ref ref="FILE"/> </root>
And finally, probably the most important thing in log4j, make sure you limit the logging level on your own class hierarchy. This assumes that you are using log4j as it was intended and not writing everything to System.out. This will significantly reduce the overhead of log4j and allow you to fully enjoy the benefits of calls like
if (log.isDebugEnabled())...
. If you don't do this then all the logging in your code will get formatted and passed to the appender, and the threshold on the appender will weed out the log messages. This can generate a significant amount of garbage. Assuming your java package starts with "a.b", add something like this to log4j.xml:
<!-- Limit a.b category to INFO --> <category name="a.b"> <priority value="INFO"/> </category>
This can be added in the same area where you find the category filters for org.apache and org.jboss (see above).
edit
server/slim/conf/standardjboss.xml
, scroll down to:
<container-configuration> <container-name>Standard Stateless SessionBean</container-name> <call-logging>false</call-logging> <invoker-proxy-binding-name>stateless-rmi-invoker</invoker-proxy-binding-name> <container-interceptors>
and find:
<container-pool-conf> <MaximumSize>100</MaximumSize> </container-pool-conf> </container-configuration>
change it to read:
<container-pool-conf> <MinimumSize>100</MinimumSize> <MaximumSize>100</MaximumSize> <strictMaximumSize/> <strictTimeout>30000</strictTimeout> </container-pool-conf> </container-configuration>
For the most part a server environment doesn't want these pools growing and shrinking (because it causes memory-fragmentation and thats worse than latent heap usage). From a performance standpoint, the nuber should be big enough to serve all your requests with no blocking.
Note that JBossMQ as deployed in the default configuration uses DefaultDS with mappings for Hypersonic. See JBoss MQ Persistence Wiki pages for more information on configuring other alternatives.
<!-- A AJP 1.3 Connector on port 8009 --> <Connector port="8009" address="${jboss.bind.address}" enableLookups="false" redirectPort="8443" debug="0" protocol="AJP/1.3"/>
<!-- A HTTP/1.1 Connector on port 8080 --> <Connector port="8080" address="${jboss.bind.address}" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" redirectPort="8443" acceptCount="100" connectionTimeout="20000" disableUploadTimeout="true"/>
from under the
<mbean code="org.jboss.management.j2ee.LocalJBossServerDomain"
MBean
<attribute name="EARDeployer">jboss.j2ee:service=EARDeployer</attribute>
and
<!-- EAR deployer, remove if you are not using Web layers --> <mbean code="org.jboss.deployment.EARDeployer" name="jboss.j2ee:service=EARDeployer"> </mbean>
from under the
<mbean code="org.jboss.management.j2ee.LocalJBossServerDomain"
MBean
<attribute name="JMSService">jboss.mq:service=DestinationManager</attribute>
from under the
<mbean code="org.jboss.management.j2ee.LocalJBossServerDomain"
MBean
<attribute name="RMI_IIOPService">jboss:service=CorbaORB</attribute>
from under the
<mbean code="org.jboss.management.j2ee.LocalJBossServerDomain"
MBean
<attribute name="UserTransactionService">jboss:service=ClientUserTransaction</attribute>
<!-- ==================================================================== --> <!-- JSR-77 Single JBoss Server Management Domain --> <!-- ==================================================================== --> <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="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>
<!-- | UserTransaction support. --> <mbean code="org.jboss.tm.usertx.server.ClientUserTransactionService" name="jboss:service=ClientUserTransaction" xmbean-dd="resource:xmdesc/ClientUserTransaction-xmbean.xml"> <depends> <mbean code="org.jboss.invocation.jrmp.server.JRMPProxyFactory" name="jboss:service=proxyFactory,target=ClientUserTransactionFactory"> <attribute name="InvokerName">jboss:service=invoker,type=jrmp</attribute> <attribute name="TargetName">jboss:service=ClientUserTransaction</attribute> <attribute name="JndiName">UserTransactionSessionFactory</attribute> <attribute name="ExportedInterface"> org.jboss.tm.usertx.interfaces.UserTransactionSessionFactory </attribute> <attribute name="ClientInterceptors"> <interceptors> <interceptor>org.jboss.proxy.ClientMethodInterceptor</interceptor> <interceptor>org.jboss.invocation.InvokerInterceptor</interceptor> </interceptors> </attribute> <depends>jboss:service=invoker,type=jrmp</depends> </mbean> </depends> <depends optional-attribute-name="TxProxyName"> <mbean code="org.jboss.invocation.jrmp.server.JRMPProxyFactory" name="jboss:service=proxyFactory,target=ClientUserTransaction"> <attribute name="InvokerName">jboss:service=invoker,type=jrmp</attribute> <attribute name="TargetName">jboss:service=ClientUserTransaction</attribute> <attribute name="JndiName"></attribute> <attribute name="ExportedInterface"> org.jboss.tm.usertx.interfaces.UserTransactionSession </attribute> <attribute name="ClientInterceptors"> <interceptors> <interceptor>org.jboss.proxy.ClientMethodInterceptor</interceptor> <interceptor>org.jboss.invocation.InvokerInterceptor</interceptor> </interceptors> </attribute> <depends>jboss:service=invoker,type=jrmp</depends> </mbean> </depends> </mbean>
<!-- ==================================================================== --> <!-- XMBean Persistence --> <!-- ==================================================================== --> <mbean code="org.jboss.system.pm.AttributePersistenceService" name="jboss:service=AttributePersistenceService" xmbean-dd="resource:xmdesc/AttributePersistenceService-xmbean.xml"> <attribute name="AttributePersistenceManagerClass"> org.jboss.system.pm.XMLAttributePersistenceManager </attribute> <attribute name="AttributePersistenceManagerConfig"> <data-directory>data/xmbean-attrs</data-directory> </attribute> <attribute name="ApmDestroyOnServiceStop">false</attribute> <attribute name="VersionTag"></attribute> </mbean>
<!-- ==================================================================== --> <!-- JBoss RMI Classloader - only install when available --> <!-- ==================================================================== --> <mbean code="org.jboss.util.property.jmx.SystemPropertyClassValue" name="jboss.rmi:type=RMIClassLoader"> <attribute name="Property">java.rmi.server.RMIClassLoaderSpi</attribute> <attribute name="ClassName">org.jboss.system.JBossRMIClassLoader</attribute> </mbean>
and
<!-- ==================================================================== --> <!-- Class Loading --> <!-- ==================================================================== --> <mbean code="org.jboss.web.WebService" name="jboss:service=WebService"> <attribute name="Port">8083</attribute> <!-- Should resources and non-EJB classes be downloadable --> <attribute name="DownloadServerClasses">true</attribute> <attribute name="Host">${jboss.bind.address}</attribute> <attribute name="BindAddress">${jboss.bind.address}</attribute> </mbean>
<!-- EJB deployer, remove to disable EJB behavior--> <mbean code="org.jboss.ejb.EJBDeployer" name="jboss.ejb:service=EJBDeployer"> <attribute name="VerifyDeployments">true</attribute> ... <depends optional-attribute-name="WebServiceName">jboss:service=WebService</depends> </mbean>
to read like this:
<!-- EJB deployer, remove to disable EJB behavior--> <mbean code="org.jboss.ejb.EJBDeployer" name="jboss.ejb:service=EJBDeployer"> <attribute name="VerifyDeployments">true</attribute> ... <!-- <depends optional-attribute-name="WebServiceName">jboss:service=WebService</depends> --> </mbean>
or alternatively remove the WebServiceName? depends/attribute.
<!-- ==================================================================== --> <!-- JNDI --> <!-- ==================================================================== --> <mbean code="org.jboss.naming.NamingService" name="jboss:service=Naming" xmbean-dd="resource:xmdesc/NamingService-xmbean.xml"> ... <!-- The listening port for the bootstrap JNP service. Set this to -1 to run the NamingService without the JNP invoker listening port. --> <attribute name="Port">1099</attribute> ... <!-- The port of the RMI naming service, 0 == anonymous --> <attribute name="RmiPort">1098</attribute> ... </mbean>
To read
<!-- ==================================================================== --> <!-- JNDI --> <!-- ==================================================================== --> <mbean code="org.jboss.naming.NamingService" name="jboss:service=Naming" xmbean-dd="resource:xmdesc/NamingService-xmbean.xml"> ... <!-- The listening port for the bootstrap JNP service. Set this to -1 to run the NamingService without the JNP invoker listening port. --> <attribute name="Port">-1</attribute> ... <!-- The port of the RMI naming service, 0 == anonymous --> <attribute name="RmiPort">0</attribute> ... </mbean>
The RmiPort is mostly optional but it means we won't bind to 1098 so that can be helpful.
You may also want to remove the thread pool associated by removing this line from the same XML block:
<depends optional-attribute-name="LookupPool" proxy-type="attribute">jboss.system:service=ThreadPool</depends>
and the thread pool block itself:
<!-- A Thread pool service --> <mbean code="org.jboss.util.threadpool.BasicThreadPool" name="jboss.system:service=ThreadPool"> <attribute name="Name">JBoss System Threads</attribute> <attribute name="ThreadGroupName">System Threads</attribute> <attribute name="KeepAliveTime">60000</attribute> <attribute name="MinimumPoolSize">1</attribute> <attribute name="MaximumPoolSize">10</attribute> <attribute name="MaximumQueueSize">1000</attribute> <attribute name="BlockingMode">run</attribute> </mbean>
<mbean code="org.jboss.naming.JNDIView" name="jboss:service=JNDIView" xmbean-dd="resource:xmdesc/JNDIView-xmbean.xml"> </mbean>
<!-- ==================================================================== --> <!-- Security --> <!-- ==================================================================== --> <!-- <mbean code="org.jboss.security.plugins.SecurityConfig" name="jboss.security:service=SecurityConfig"> <attribute name="LoginConfig">jboss.security:service=XMLLoginConfig</attribute> </mbean> <mbean code="org.jboss.security.auth.login.XMLLoginConfig" name="jboss.security:service=XMLLoginConfig"> <attribute name="ConfigResource">login-config.xml</attribute> </mbean>
<!-- The JAAS security domain to use in the absense of an explicit security-domain specification in the war WEB-INF/jboss-web.xml --> <!-- <attribute name="DefaultSecurityDomain">java:/jaas/other</attribute>-->
and
<!-- A mapping to the server security manager service which must be operation compatible with type org.jboss.security.plugins.JaasSecurityManagerServiceMBean. This is only needed if web applications are allowed to flush the security manager authentication cache when the web sessions invalidate. --> <!-- <depends optional-attribute-name="SecurityManagerService" proxy-type="attribute">jboss.security:service=JaasSecurityManager </depends>-->
<!-- JAAS security manager and realm mapping --> <mbean code="org.jboss.security.plugins.JaasSecurityManagerService" name="jboss.security:service=JaasSecurityManager"> <attribute name="SecurityManagerClassName"> org.jboss.security.plugins.JaasSecurityManager </attribute> <attribute name="DefaultCacheTimeout">1800</attribute> <attribute name="DefaultCacheResolution">60</attribute> </mbean>
<mbean code="org.jboss.mq.server.jmx.Topic" name="jboss.mq.destination:service=Topic,name=testTopic"> <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends> <!-- <depends optional-attribute-name="SecurityManager">jboss.mq:service=SecurityManager</depends> <attribute name="SecurityConf"> <security> <role name="guest" read="true" write="true"/> <role name="publisher" read="true" write="true" create="false"/> <role name="durpublisher" read="true" write="true" create="true"/> </security> </attribute>--> </mbean> <mbean code="org.jboss.mq.server.jmx.Topic" name="jboss.mq.destination:service=Topic,name=testTopic"> <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends> <!-- <depends optional-attribute-name="SecurityManager">jboss.mq:service=SecurityManager</depends> <attribute name="SecurityConf"> <security> <role name="guest" read="true" write="true"/> <role name="publisher" read="true" write="true" create="false"/> <role name="durpublisher" read="true" write="true" create="true"/> </security> </attribute>--> </mbean> <mbean code="org.jboss.mq.server.jmx.Topic" name="jboss.mq.destination:service=Topic,name=testDurableTopic"> <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends> <!-- <depends optional-attribute-name="SecurityManager">jboss.mq:service=SecurityManager</depends> <attribute name="SecurityConf"> <security> <role name="guest" read="true" write="true"/> <role name="publisher" read="true" write="true" create="false"/> <role name="durpublisher" read="true" write="true" create="true"/> </security> </attribute>--> </mbean> <mbean code="org.jboss.mq.server.jmx.Queue" name="jboss.mq.destination:service=Queue,name=testQueue"> <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends> <!-- <depends optional-attribute-name="SecurityManager">jboss.mq:service=SecurityManager</depends> <attribute name="SecurityConf"> <security> <role name="guest" read="true" write="true"/> <role name="publisher" read="true" write="true" create="false"/> <role name="noacc" read="false" write="false" create="false"/> </security> </attribute>--> </mbean>
<mbean code="org.jboss.mq.server.jmx.InterceptorLoader" name="jboss.mq:service=TracingInterceptor"> <attribute name="InterceptorClass">org.jboss.mq.server.TracingInterceptor</attribute> <depends optional-attribute-name="NextInterceptor">jboss.mq:service=DestinationManager</depends> <!-- <depends optional-attribute-name="NextInterceptor">jboss.mq:service=SecurityManager</depends> --> </mbean>
<!-- <mbean code="org.jboss.mq.security.SecurityManager" name="jboss.mq:service=SecurityManager"> <attribute name="DefaultSecurityConfig"> <security> <role name="guest" read="true" write="true" create="true"/> </security> </attribute> <attribute name="SecurityDomain">java:/jaas/jbossmq</attribute> <depends optional-attribute-name="NextInterceptor">jboss.mq:service=DestinationManager</depends> </mbean> -->
<!-- Dead Letter Queue --> <mbean code="org.jboss.mq.server.jmx.Queue" name="jboss.mq.destination:service=Queue,name=DLQ"> <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends> <!-- <depends optional-attribute-name="SecurityManager">jboss.mq:service=SecurityManager</depends>--> </mbean>
<!-- JMS XA Resource adapter, use this to get transacted JMS in beans --> <tx-connection-factory> <jndi-name>JmsXA</jndi-name> <xa-transaction/> <adapter-display-name>JMS Adapter</adapter-display-name> <config-property name="SessionDefaultType" type="java.lang.String">javax.jms.Topic</config-property> <config-property name="JmsProviderAdapterJNDI" type="java.lang.String">java:/DefaultJMSProvider</config-property> <max-pool-size>20</max-pool-size> <!-- <security-domain-and-application>JmsXARealm</security-domain-and-application>--> </tx-connection-factory>
<!-- Security domains for testing new jca framework <application-policy name = "HsqlDbRealm"> <authentication> <login-module code = "org.jboss.resource.security.ConfiguredIdentityLoginModule" flag = "required"> <module-option name = "principal">sa</module-option> <module-option name = "userName">sa</module-option> <module-option name = "password"></module-option> <module-option name = "managedConnectionFactoryName"> jboss.jca:service=LocalTxCM,name=DefaultDS </module-option> </login-module> </authentication> </application-policy> <application-policy name = "JmsXARealm"> <authentication> <login-module code = "org.jboss.resource.security.ConfiguredIdentityLoginModule" flag = "required"> <module-option name = "principal">guest</module-option> <module-option name = "userName">guest</module-option> <module-option name = "password">guest</module-option> <module-option name = "managedConnectionFactoryName"> jboss.jca:service=TxCM,name=JmsXA </module-option> </login-module> </authentication> </application-policy> -->
<!-- Use the security domain defined in conf/login-config.xml <security-domain>HsqlDbRealm</security-domain> -->
<!-- <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="EnableTcpNoDelay">false</attribute> <depends optional-attribute-name="TransactionManagerService"> jboss:service=TransactionManager</depends> </mbean>
<mbean code="org.jboss.varia.deployment.BeanShellSubDeployer" name="jboss.scripts:service=BSHDeployer"> </mbean>
<!-- An mbean for hot deployment/undeployment of archives. --> <mbean code="org.jboss.deployment.scanner.URLDeploymentScanner" name="jboss.deployment:type=DeploymentScanner,flavor=URL"> ... <attribute name="ScanPeriod">5000</attribute> ... </mbean>
to read (by adding):
<!-- An mbean for hot deployment/undeployment of archives. --> <mbean code="org.jboss.deployment.scanner.URLDeploymentScanner" name="jboss.deployment:type=DeploymentScanner,flavor=URL"> ... <attribute name="ScanPeriod">5000</attribute> <attribute name="ScanEnabled">False</attribute> ... </mbean>
<!-- Needed if using HTTP Session Clustering or if the ClusteredSingleSignOn valve is enabled in the tomcat server.xml file --> <depends>jboss.cache:service=TomcatClusteringCache</depends>
<!-- Needed if using HTTP Session Clustering or if the ClusteredSingleSignOn valve is enabled in the tomcat server.xml file --> <depends>jboss.cache:service=TomcatClusteringCache</depends>
Click here for a complete list of service dependencies.