??xml version="1.0" encoding="utf-8" standalone="yes"?> When you start the jboss on computer A, you should see the logs (server.log) telling you that there is one node ready and listening, and once you start the jboss on computer B, on the log will appear the two nodes, the two IP's ready to consume messages. 5) Now it's time to send a Message to the Queue. To accomplish this it's necessary to change the connection factory to "ClusteredConnectionFactory" (JMSDispatcher.java - See the code below). java.naming.provider.url=192.168.0.143:1099,192.168.0.210:1099 Session Bean除了可以使用注释来发布外Q也可以使用相应的配|文件来发布。在q种情况下,׃需要在接口和Session Bean中用注释了。在JBoss中需要两个文件对Session beanq行配置。这两个文g是ejb-jar.xml和jboss.xml.q两个文件应该META-INF目录中,该目录应该放在jar文g的根目录。ejb-jar.xml文g负责配置session beanQ下面是一个典型的配置代码Q?/p>
]]>
]]>
]]>
]]>
]]>
]]>
http://docs.jboss.org/jbossas/getting_started/v4/html/mdb.html
http://carter.zhmy.com/archives/2007/112108.html
$ cd $JBOSS_HOME/bin
$ ./run.sh -c all -b 192.168.0.143 -Djboss.messaging.ServerPeerID=1
Computer B:
$ cd $JBOSS_HOME/bin
$ ./run.sh -c all -b 192.168.0.210 -Djboss.messaging.ServerPeerID=2
It is necesary to give an ID to each server and this is accomplished with this directive:
-Djboss.messaging.ServerPeerID
Also on the jndi.properties (if you are using the default InitialContext) file it's necessary to add the two computers ip's separated by comma to the java.naming.provider.url property. (In my case a create a Properties variable and I set all the necessary properties, JMSDispatcher.java - see the code below).
The client that I wrote is a web application, that consist in one index.jsp page, which contains a form that prompts you for the name of the queue, the type of messaging (Queue or Topic), the server ip and port, how many times it will send the message and the actual message to be sent; also the web application has a Servlet (JMSClusteredClient.java - see code below) that receives the postback and helper class (JMSDispatcher.java - see code below) that sends the message to the jboss servers. You can to deploy it in any computer. In my case I deployed it on the Computer A. And you can access it through this URL: http://192.168.0.143:8080/JMSWeb/ (just modify the IP where the client war was deployed).If you notice (on the index.jsp - code below) I've already put some default values that reflects the name of the Queue, and the IP's of my two computers. Now, If you increment the number of times that the message will be sent (maybe a 10) and fill out the message box, and click "Send" you should see on the two servers some of the messages being consumed by the MDB.
]]>Java同步文g到Jboss虚拟目录
]]>
server/<configuration (all/default/production)>/deploy/jboss-messaging.sar/messaging-service.xml
and change ServerPeerID from 0 to something unique.
The other suggestion I'd make is that you track down the other SOA platform installation. The IP address of that cluster node should be in your server.log close to the "number of cluster members" statement.
]]>
<?xml version="1.0" encoding="ASCII"?>
<ejb-jar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:ejb="http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd"
version="3.0">
<display-name>MyEJB</display-name>
<enterprise-beans>
<session>
<ejb-name>Greeter</ejb-name>
<business-local>service.GreeterBeanLocal</business-local>
<business-remote>service.GreeterBeanRemote</business-remote>
<ejb-class>service.GreeterBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
</ejb-jar>
其中<ejb-name>元素是一个表C,表示当前配置的session bean的名U?lt;business-local>?lt;bussiness-remote>分别用来指定本地接口和远E接口?lt;ejb-class>用来指定session bean的javac?/p>
jboss.xml文g主要用来指定jndiQ如下面的代码所C:
<?xml version="1.0"?> <jboss xmlns:xs="http://www.jboss.org/j2ee/schema" xs:schemaLocation="http://www.jboss.org/j2ee/schema jboss_5_0.xsd" version="5.0"> <enterprise-beans> <session> <ejb-name>Greeter</ejb-name> <jndi-name>mygreeter</jndi-name> <local-jndi-name>mygreeter_local</local-jndi-name> </session> </enterprise-beans> </jboss> |
上面的代码中?lt;ejb-name>元素的值和要ejb-jar.xml中的<ejb-name>元素的值相同?lt;jndi-name>用来指定q程的jndi名称?lt;local-jndi-name>用来指定本地jndi的名U。如果访问远E的session beanQ可以用下面代码:
Properties prop = new Properties(); InitialContext ctx = new InitialContext(); System.out.println(((service.Greeter)ctx.lookup("mygreeter")).greet("bill")); |
从上面代码可看出QlookupҎ通过“mygreeter”来查找服务端的session bean.
Trigger是一个抽象类Q?span style="font-family: Calibri">Quartz提供了两个比较常用的触发?span style="font-family: Calibri">SimpleTrigger?span style="font-family: Calibri">CronTrigger。它们都?span style="font-family: Calibri">Trigger的子c?/span>
q是一个简单的触发器,通过它我们可以定义触发的旉Qƈ选择性的讑֮重复的次数和间隔旉。它有以下常用的属?/span>
参数?/span> |
参数cd |
备注 |
name |
String |
触发器名U?/span> |
group |
String |
触发器组名称 |
repeatCount |
int |
重复ơ数Q注意:如果?span style="font-family: Calibri">0表示不执行,-1表示不限制次敎ͼ直到q期Q,默认?span style="font-family: Calibri">0 |
repeatInterval |
long |
间隔旉Q注意:是以毫秒为单?/span> |
startTime |
Date |
开始时_默认当前旉 |
endTime |
Date |
q期旉Q默认一直执行(直到执行ơ数已达?span style="font-family: Calibri">repeatCountQ?/span> |
q个触发器的功能非常强大Q而且非常灉|Q但需要掌握有关的Cron表达式知?/span>
参数?/span> |
参数cd |
备注 |
name |
String |
触发器名U?/span> |
group |
String |
触发器组名称 |
cronEx |
CronExpression |
规则表达?/span> |
startTime |
Date |
开始时_默认当前旉 |
endTime |
Date |
q期旉Q默认一直执行(直到执行ơ数已达?span style="font-family: Calibri">repeatCountQ?/span> |
触发器规则表辑ּ配置Q?/span>
格式:
[U?span>] [分] [时] [日] [月] [周] [q]
格式说明Q?/span>
位置 |
旉域名 |
是否必须 |
允许?/span> |
允许通配W?/span> |
1 |
U?/span> |
?/span> |
0-59 |
, - * / |
2 |
?/span> |
?/span> |
0-59 |
, - * / |
3 |
时 |
?/span> |
0-23 |
, - * / |
4 |
?/span> |
?/span> |
1-31 |
, - * ? / L W |
5 |
?/span> |
?/span> |
1-12 |
, - * / |
6 |
?/span> |
?/span> |
1-7?span style="font-family: Calibri">MON-SUN |
, - * ? / L # |
7 |
q?/span> |
?/span> |
empty?span style="font-family: Calibri">1970-2099 |
, - * / |
通配W说明:
|
|
* |
可用在所有字D中Q表C对应时间域的每一个时刻,例如Q?span style="font-size: 9pt">*在分钟字D|Q表C?span style="font-size: 9pt">“每分?span style="font-size: 9pt">” |
? |
该字W只在日期和星期字段中用,它通常指定?span style="font-size: 9pt">“无意义的?span style="font-size: 9pt">”Q相当于点位W?/p> |
- |
表示区间。例?在小时上讄 "10-12",表示 10,11,12炚w会触?/span> |
, |
表示指定多个|例如在周字段上设|?span> "MON,WED,FRI" 表示周一Q周三和周五触发 |
/ |
x/y表达一个等步长序列Q?span style="font-size: 9pt">xv始|y为增量步长倹{如在分钟字D中使用0/15Q则表示?span style="font-size: 9pt">0,15,30?span style="font-size: 9pt">45U,?span style="font-size: 9pt">5/15在分钟字D中表示5,20,35,50Q你也可以?span style="font-size: 9pt">*/yQ它{同?span style="font-size: 9pt">0/y |
L |
该字W只在日期和星期字段中用,代表“Last”的意思,但它在两个字D中意思不同?span style="font-size: 9pt">L在日期字D中Q表C个月份的最后一天,如一月的31P非闰q二月的28P如果L用在星期中,则表C星期六Q等同于7。但是,如果L出现在星期字D里Q而且在前面有一个数?span style="font-size: 9pt">XQ则表示“q个月的最?span style="font-size: 9pt">X?span style="font-size: 9pt">”Q例如,6L表示该月的最后星期五 |
W |
该字W只能出现在日期字段里,是对前导日期的修饎ͼ表示该日期最q的工作日。例?span style="font-size: 9pt">15W表示该?span style="font-size: 9pt">15hq的工作日,如果该月15h星期六,则匹?span style="font-size: 9pt">14h期五Q如?span style="font-size: 9pt">15日是星期日,则匹?span style="font-size: 9pt">16h期一Q如?span style="font-size: 9pt">15h星期二,那结果就?span style="font-size: 9pt">15h期二。但必须注意兌的匹配日期不能够跨月Q如你指?span style="font-size: 9pt">1WQ如?span style="font-size: 9pt">1h星期六,l果匚w的是3h期一Q而非上个月最后的那天?span style="font-size: 9pt">W字符串只能指定单一日期Q而不能指定日期范?/p> |
# |
该字W只能在星期字段中用,表示当月某个工作日。如6#3表示当月的第三个星期?span style="font-size: 9pt">(6表示星期五,#3表示当前的第三个)Q?span style="font-size: 9pt">4#5表示当月的第五个星期三,假设当月没有W五个星期三Q忽略不触发 |
SimpleJob.java
package com.test.job;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class SimpleJob implements Job{
public void execute(JobExecutionContext context)
throws JobExecutionException {
// your business logic
// ...
System.out.println("simpleJob running ....");
}
}
TestSimpleJob.java
package com.test.job;
import java.text.ParseException;
import org.quartz.CronExpression;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleTrigger;
import org.quartz.impl.StdSchedulerFactory;
public class TestSimpleJob {
public static void main(String[] args){
try {
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
String jobName = "simpleJob";
String groupName = "DEFAULT";
//删除作业
if(scheduler.getJobDetail(jobName,groupName) != null){
scheduler.deleteJob(jobName, groupName);
}
//作业的详l信?/p>
//d名称QQ务组名称QQ务实现类
JobDetail jobDetail = new JobDetail(jobName,groupName,SimpleJob.class);
//创徏单触发器
SimpleTrigger simpleTrigger = new SimpleTrigger("simpleTrigger",null);
simpleTrigger.setRepeatCount(100); // 调用100?/p>
simpleTrigger.setRepeatInterval(5*1000); //?span style="font-family: 'Courier New'; color: #3f7f5f; font-size: 10pt">5U钟调用一?/p>
//注册作业
scheduler.scheduleJob(jobDetail, simpleTrigger);
CronTrigger cronTrigger = new CronTrigger("cronTrigger",null);
CronExpression cronExpression = null;
try {
cronExpression = new CronExpression("0 0 12 * * ?"); //每天12点运?/p>
cronTrigger.setCronExpression(cronExpression);
//注册作业
scheduler.scheduleJob(jobDetail, cronTrigger);
if(! scheduler.isShutdown()){
scheduler.start();
}
} catch (ParseException e) {
e.printStackTrace();
}
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
Scheduler负责理Quartz的运行环境,Quartz它是Z多线E架构的Q它启动的时候会初始化一套线E,q套U程会用来执行一些预|的作业?/span>
要创Z个作业ƈ能够被触发调用,必须?span style="font-family: Calibri">Scheduler上面注册一?span style="font-family: Calibri">JobDetail
?span style="font-family: Calibri">Trigger?/span>Scheduler提携了所?span style="font-family: Calibri">Trigger?span style="font-family: Calibri">JobDetailQ它们协调工作。这?span style="font-family: Calibri">Trigger?span style="font-family: Calibri">JobDetail通过自n?span style="font-family: Calibri">name?span style="font-family: Calibri">group属性区?span>?/span>
Scheduler ?span style="font-family: Calibri">SchedulerFactory产生Q我们可以通过以下方式获取Scheduler的实例:
//?span style="background: #d9d9d9">ServletContext
SchedulerFactory factory = (SchedulerFactory)
ServletActionContext.getServletContext().getAttribute("org.quartz.impl.StdSchedulerFactory.KEY");
//获取Scheduler对象
Scheduler defScheduler = factory.getScheduler();
dQ其实就是一个接口。要创徏一个Q务,必须得实现这个接口。该接口只有一个executeҎQQ务每ơ被调用的时候都会执行这个executeҎ的逻辑?/span>
public class TestJob impletemens org.quartz.Job{
@Override
public void execute(JobExecutionContext context) throws JobExecutionException{
// you business logic
// …
System.out.println("########### this is testJob running ############");
}
}
JobDetail 用来保存我们作业的详l信息。一个JobDetail可以有多个TriggerQ但是一个Trigger只能对应一个JobDetail。下面是JobDetail的一些常用的属性和含义
参数?/span> |
cd |
备注 |
name |
String |
d的名Uͼ必须 |
group |
String |
d所在组Q默认ؓDEFAULT |
jobClass |
Class |
d的实现类Q必?/span> |
description |
String |
描述 |
jobDataMap |
JobDataMap |
用来l作业提供数据支持的数据l构 |
volatility |
Boolean |
重启应用之后是否删除d的相关信息,默认false |
durability |
Boolean |
d完成之后是否依然保留到数据库Q默?span style="font-family: Calibri">false |
shouldRecover |
Boolean |
应用重启之后时候忽略过期Q务,默认false |
jobListeners |
Set |
监听?/span> |
q是一个给作业提供数据支持的数据结构,使用Ҏ和java.util.Map一P非常方便。当一个作业被分配l调度器ӞJobDataMap实例随之生成?/p>
Job有一个StatefulJob子接口,代表有状态的dQ该接口是一个没有方法的标签接口Q其目的是让Quartz知道d的类型,以便采用不同的执行方案。无状态Q务在执行时拥有自qJobDataMap拯Q对JobDataMap的更改不会媄响下ơ的执行。而有状态Q务共享共享同一个JobDataMap实例Q每ơQ务执行对JobDataMap所做的更改会保存下来,后面的执行可以看到这个更改,也即每次执行d后都会对后面的执行发生媄响?/p>
正因个原因,无状态的Job可以q发执行Q而有状态的StatefulJob不能q发执行Q这意味着如果前次的StatefulJobq没有执行完毕,下一ơ的d阻塞等待,直到前次d执行完毕。有状态Q务比无状态Q务需要考虑更多的因素,E序往往拥有更高的复杂度Q因此除非必要,应该量使用无状态的Job?/p>
如果Quartz使用了数据库持久化Q务调度信息,无状态的JobDataMap仅会在Scheduler注册d时保持一ơ,而有状态Q务对应的JobDataMap在每ơ执行Q务后都会q行保存?/p>
JobDataMap实例也可以与一个触发器相关联。这U情况下Q对于同一作业的不同触发器Q我们可以在JobDataMap中添加不同的数据Q以便作业在不同旉执行时能够提供更为灵zȝ数据支持Q学校上午放g健操录音W一版,下午攄二版Q?/p>
不管是有状态还是无状态的dQ在d执行期间对Trigger的JobDataMap所做的更改都不会进行持久,也即不会对下ơ的执行产生影响?/p>
Quartz作业存储方式
Quartz提供两种基本作业存储cd。第一U类型叫做RAMJobStoreQ第二种cd叫做JDBC作业存储?span>
cd |
优点 |
~点 |
RAMJobStore |
不要外部数据库,配置ҎQ运行速度?/p> |
因ؓ调度E序信息是存储在被分配给JVM的内存里面,所以,当应用程序停止运行时Q所有调度信息将被丢失。另外因为存储到JVM内存里面Q所以可以存储多个Job?span style="line-height: 160%; font-family: 'ˎ̥', 'serif'; color: #222222; font-size: 9pt">Trigger会受到限制 |
JDBC作业存储 |
支持集群Q因为所有的d信息都会保存到数据库中,可以控制事物Q还有就是如果应用服务器关闭或者重启,d信息都不会丢失,q且可以恢复因服务器关闭或者重启而导致执行失败的d |
q行速度的快慢取决与q接数据库的快慢 |
1、以下是配置是内存存?/span>
#============================================================================
# Configure RAMJobStore
#============================================================================
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
2、以下配|是数据库存?/span>
#============================================================================
# Configure JobStore
#============================================================================
#===========================
#Configure JDBC-JobStoreTX
#===========================
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.dataSource = myDS
org.quartz.jobStore.useProperties = false
#============================
# Configure DataSource
#============================
org.quartz.dataSource.myDS.driver = oracle.jdbc.OracleDriver
org.quartz.dataSource.myDS.URL = jdbc:oracle:thin:@localhost:1521:test
org.quartz.dataSource.myDS.user = user
org.quartz.dataSource.myDS.password = password
org.quartz.dataSource.myDS.maxConnections = 10
看一下这个文?里面用户名与密码都是以明文方式存储的,q样子对pȝ的安全而言带来了极大的威协。所以我们要为我们这个明文的密码加一下密,q就是本文的目的.
2.说到密码加密Q这里我们用CJBoss下的一个类org.jboss.resource.security.SedureIdentityLoginModule,看看我们该如何用它来帮我们的密码加密?
先看个配|数据源的例?mysql-ds.xml)
接着我们修改server\default\conf\login-config.xml文g,加上下面q一D配|文?/p>
3.补充一下,q个加密的密码是哪来?/p>
写上你自q路径和你要加密的密码p?我这里要加密的密码是123456,加密q之后就?4c5fd2979a86168
PermGen space的全U是Permanent Generation space,是指内存的永久保存区域。这一部分用于存放Class?/span>Meta的信?/span>,Class在被 Load的时候被攑օPermGen space区域Q?/span>
它和和存?/span>Instance?/span>Heap区域不同,GC(Garbage Collection)不会在主E序q行期对PermGen spaceq行清理Q所以如果你?/span>APP?/span>LOAD很多CLASS的话,很可能出现PermGen space错误?/span>
q种错误常见?/span>web服务器对JSPq行pre compile的时候?/span>
ҎҎQ在 run.bat 中加入:-Xms512m -Xmx1024m -XX:MaxNewSize=256m -XX:MaxPermSize=256m
因ؓ目中引用了很多?/span> jar 包,而这?/span> jar 包中?/span> class 信息会被 JBoss ?/span> class loader 加蝲?/span> PermGen space 区域Q在 JVM 默认的情况下Q该部分I间的大只?/span> 4MQ在 jar 包非常多的情况下Q显然是不够用的Q所以通过 -XX:MaxPermSize=256m 指定最大值后卛_解决问题?/span>
而当出现出现java.lang.OutOfMemoryError: Java heap space q个异常Ӟ通过调节-Xms512m -Xmx1024mq个可以解冟?/span>
另外Q这个两个参?/span> -XX:+UseParallelGC -XX:+UseParallelOldGC 让服务ƈ行回收内存空间。但是,q两个参数配|上M后,也会占用一定的内存I间?/span>
本文转自博客 http://m.tkk7.com/fiele/archive/2009/07/27/288609.html
当不使用mail-service服务的时?(J2EE 标准?JavaMail 客户?span>)
l U除server/slim/deploy/mail-service.xml
l U除server/slim/lib/mail* (mail-plugin.jar, mail.jar - JavaMail stuff)
l U除server/slim/lib/activation.jar (JavaMail使用?span style="font-family: Calibri">Java zd框架【Java Activation Framework?
当不使用~存失效服务的时?span> (一般在集群配置里作?span>CMP选择一个beans用与失效~存)
l U除 server/slim/deloy/cache-invalidation-service.xml
当不使用J2EE客户端部|服务的时?q不是一个很有益?span>J2EE规格必须服务Q对于EAR application-client.xml描述W?/span>)
l U除 server/slim/deploy/client-deployer-service.xml
当不使用集成HAR部v和Hibernate会话理服务的时?
l U除server/slim/deploy/hibernate-deployer-service.xml (HAR support)
l U除server/slim/lib/jboss-hibernate.jar (HAR support)
l U除server/slim/lib/hibernate2.jar (Hibernate itself)
l U除server/slim/lib/cglib-full-2.0.1.jar (used by Hibernate to create proxies of POJOs)
l U除server/slim/lib/odmg-3.0.jar (由hibernate使用的一些傻瓜试的对象-关系映射行ؓ是从一些傻瓜式的委员会来的[goofy committee]http://www.service-architecture.com/database/articles/odmg_3_0.html
不?span> Hypersonic的时?(在生产环境里你可能不使用q个)
注意在默认配|里 JBossMQ使用 DefaultDS名字同样被部|Ԍ用于?span>Hypersonic映射. 在配|上对于其他选择的更多信息,?JBoss MQ Persistence Wiki pages .
l U除server/slim/deploy/hsqldb-ds.xml
l U除server/slim/lib/hsqldb-plugin.jar
l U除server/slim/lib/hsqldb.jar
不?JBossMQ 的时?span>(我们?JMS 服务?
l U除the entire server/slim/deploy/jms directory
l U除server/slim/lib/jbossmq.jar
不?span> HTTPInvoker的时?(?span>RMI到HTTP的隧?/span>)
l U除the entire server/slim/deploy/http-invoker.sar 文g?
不?span> XA 数据源的使用 (分布?and/or 可恢复的事务)
l U除server/slim/deploy/jboss-xa-jdbc.rar
如果你不需?span>JMX-Console 然后删除?
l U除server/slim/deploy/jmx-console.war 或?/span>使用别的Ҏ 使它安全
如果你不需要制?span>JMX调用RMI (警告the shutdown.sh 是否q样?
l U除server/slim/deploy/jmx-invoker-adaptor-server.sar
l U除server/slim/deploy/jmx-adaptor-plugin.jar 或者你可能x好想?a >安全?the JMX invoker-adaptor替
如果你不需?span>web-console
l U除server/slim/deploy/management/web-console.war
如果你不需?span>JMX的JSR-77扩充
l U除server/slim/deploy/management/console-mgr.sar
如果你需?span>web-console 或?jsr-77 扩充的其中之一
l U除server/slim/deploy/management directory entirely
如果你不使用控制?span>/email监控警报
l U除server/slim/deploy/monitoring-service.xml
l U除server/slim/lib/jboss-monitoring.jar
如果你不通过Properties Service使用富资源编辑器(JMX)或者装载properties到系lproperties 里?/span>
l U除server/slim/deploy/properties-service.xml
l U除server/slim/lib/properties-plugin.jar
?span>scheduler-service.xml是一个例子,除非你在它的里面攑օ自己的东?
l U除server/slim/deploy/scheduler-service.xml
如果你不适用JBoss调度理 (允许你安排请求依赖MBeans)
l U除server/slim/deploy/schedule-manager-service.xml
l U除server/slim/lib/scheduler-plugin* (scheduler-plugin.jar, scheduler-plugin-example.jar)
如果你不需要供应商特定?span>sql异常援助[handing] (just leave it, really)
l U除server/slim/deploy/sqlexception-service.xml
如果你既没有使用客户端事务管理,也没有缓存连?span>(我们~存q接来代替池Q例如就JAAS->DB User 来说—Q用这个意味着你是个坏人,需要被拍击[using this means you are a bad person and need to be smacked]) .
l U除server/slim/deploy/user-service.xml
如果你不使用JBoss的UUID key生成 (大多情况下用于CMP主键生成Q但是我们的数据库也同样支持的很?
l U除server/slim/deploy/uuid-key-generator.sar
l U除server/slim/lib/autonumber-plugin.jar
user-service.xml 是一个例?– 除非你在它里面做一些事?span> (你自qmbeans)Q你可以U除?
l U除server/slim/deploy/user-service.xml
前言
q个主要是如果对JBossASq行调优和瘦w的. q个概念在多数情冉|交叉的。当通过瘦n减少闲置服务U程q不能带来大的性能影响的时候,允许你用较的内存和资源对其他性能方便q行调整。当然它可以~短启动旉。而且Q作Z般的安全观念――U除你不使用的服务。我们将分开两个U类: 瘦n和调? 首先我们使用默认的配|ƈ从那里开始瘦w?对于clustering的话题,在以后的wiki面q行讨论 ;-) ). q个不牵扯开发者和理角色交叉调优的区域开发者和理角色 (应用E序调优象cache大小一?. q主要是对于理调优的徏?
q徏议将做技术上非J2EEq_兼容(3.2.6无论如何不顺?的JBoss实例的有关的那些注意Q象除去J2EE关键 服务的那样将DJBoss p|TCK。多数性能调优/理d工作Q在现实世界l构里,在技术上属于q个cd?/span>
假设你已l复?span>server/default 文g夹ƈ它重新命名为server/slim.
调优
Java Virtual Machine Java虚拟?/strong>
l 对于你的机器和内存大来调整VM垃圾攉或?a >调整 JDK 5 的垃圾收?/span>
|
l 使用64位的机器?4位的VMQ以便你能用大的heap(?大小Q通常?Q?GB的大?4位支持在所有最新的SPARC/Solaris 寄存器运行Solaris 9 或者以后的版本是有效的, Itanium 使用 JDK 1.4, 或者在Linux x64 上用JDK 5.
l 如果你不使用上面的最?span>32位heapI间(2-4 GB 的heap)Q不要?–d64. 使用64位地址需要更多的内存来做同样的工作量Qƈ且对于应用程序不需要如此多的内存来说ƈ不能提供更大优势?/span>
l 除了避免额外的heaps外还要避免额外大的heaps. (我们不能告诉你具备什么资|因ؓ它取决于你正做什?. q媄?span>generational 垃圾攉和扫描heap的ȝ旉. 有效的调整一个小heap是困隄 (即你的应用E序仅仅需要?00MBQ如果你使用q行垃圾攉QCMSQ然后你需要远高于512MB). 特大Lheaps为垃圾收集花费不必要的时间扫描内存?/span>
l 避开 Sun 1.4 VM. JDK 5 主要是在垃圾攉斚w非常的好.
l 使用 -server 参数除了使用其他-XX:ThreadStackSize=128k (Solaris) 或?-Xss128k (其他Mq_). 在Solaris ?-Xss128k 什么也没有?(你只可以讄较大的线E栈大小). q允怽每个U程通过使用较少的内存达到创建更多线E的目的。but might result in blown stacks with extremely recursive code. 然? 128k ?is still nothing to shake a stick at.
l 你真的需要明白恰当的generational 垃圾攉调整和你真的已经q行了负载测?(OpenSTA?, JMeter, {等) 认是有把握?
l 你确实将使用一个超q?span>2个处理器的多核心机器Q及使用不同的^行和q行垃圾攉选择 (我们谈及q先q的JBoss训练暗示伏笔) 对于最大性能和高拉机回收吞吐?span>. 不过,你确实需要理解怎么调整才能使得垃圾攉很好的工作。JDK 5大部分是自我调整.
l JDK 1.4的默?NewSize? 不是好的猜想. 坏的l验法则: < 20% 是一个好?NewSize?. 20%以上的消Ҏ危险的,q是JDK令h讨厌的一个,能导致它psychoticallyq行所有满垃圾回收和从?unsuspend 或者释攑և _多的内存. JDK 5 g没有展示个bugQƈ?/span>g已回升更理智的默认倹{?
JBoss/Java on Linux
如果你正在运?span>JBoss AS在Linux服务器上Q你应该看看q篇文章的作者: Andrew Oliver, Jboss事业? Red Hat公司, N Q在 在Linux服务器上怎么优化Jboss/Java
Tomcat
l ~辑你的server/slim/jbossweb-tomcat5?.sar/server.xml 文g
l 查你正在使用的连接器?span>XML文档. 例如, HTTP q接?
<Connector port="8080" address="${jboss.bind.address}"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true"/>
l 你应该有多于你最大预?span>25Q?l验法则)的线E?maxThreads)来处理负?来一ơ性的q发讉K)
l 你应该有minSpareThreads {于恰好比你正常负蝲多一?/span>
l 你应该有maxSpareThreads{于恰好比你峰D载多一?
l minSpareThreads 意思是 "启动准备qA, L保持臛_q些U程来等待处?
l maxSpareThreads means "如果我们L过minSpareThreads那么L保持 maxSpareThreads 来等待处?
l U除M不需要的值和日志。如果你不用JBoss的安全,U除q个安全?(见下?.
l Precompile(预编?span>) JSPs. (q个内置的编译器非常的会Q它可能对于型站点不值得?)
l 在你?span>sever/slim/jbossweb-tomcat50.sar/conf/web.xml 里关闭开发("development"Q模?/span>
RMI的远E调?
默认情况?span>, JBoss来的每个RMIh创徏一个新U程. 在一个大pȝ中这一般不是高效率? 其次,它允许无限制的连接在性能或者通信峰值或者run-away q接斚w创徏客户端可能是危险的。ؓ了补救这个你应该考虑转向被集中的池请?/span>.
~辑 server/slim/conf/standardjboss.xml
通过改变每个XML分段L把所有代理绑定改变成被集中的池请求:
<invoker-mbean>jboss:service=invoker,type=jrmp</invoker-mbean>
?/p>
<invoker-mbean>jboss:service=invoker,type=pooled</invoker-mbean>
JBoss也有大部分无文g证明?a >PooledInvokerHA你可以试试?/p>
Log4j
日志在性能斚w也有重要的媄?span>. 改变日志U别跟踪能给JBossAS 带来蠕虫一L速度。改变别ؓ ERROR (或者WARN) 能引人注目的提升速度?
l 默认情况?span>, JBoss的日志被打印到控制台和server.log文g里ƈ且它默认使用的日志别是 "INFO".
l 考虑不记录到System.out (你也能仍旧想改变方向以抓取JVM 错误)
l 考虑改变日志的别ؓERROR. 观察JBoss的log4j配置文g的变化,你可以在其运行的时候改变这个配|?
l l你?span>java class层次增加一个类别过滤器.
x打印到控制台的日志(console loggingQ?
l ~辑 server/slim/conf/log4j.xml
l 改变下面?span>XML 片段:
<root>
<appender-ref ref=CONSOLE"/>
<appender-ref ref="FILE"/>
</root>
修改?
<root>
<appender-ref ref="FILE"/>
</root>
l 然后你可以删除此片段:
<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>
改变日志的?span>:
l ~辑 server/slim/conf/log4j.xml
l U除/注释 q些XML 片段:
<category name="org.apache">
<priority value="INFO"/>
</category>
<!—极限 org.jgroups cd为INFO -->
<category name="org.jgroups">
<priority value="INFO"/>
</category>
l 改变q个XML片段以改变rootcd:
<root>
<appender-ref ref="CONSOLE"/> <!—你可能在前面已经U除q个-->
<appender-ref ref="FILE"/>
</root>
看上dq样
<root>
<priority value="ERROR" />
<appender-ref ref="CONSOLE"/> <!--你可能在前面已经U除q个-->
<appender-ref ref="FILE"/>
</root>
另外Q如果你使用?span>hibernate的话Q?/span>
l ~辑 server/slim/conf/log4j.xml
l 增加如下XML 片段
<category name="org.hibernate" >
<priority value="INFO" />
</category>
最?span>, 在log4j中也许是最重要的事情,?strong>你拥有的 class l构?/strong>保你的极限的日志? 假设你正在用的log4j打算不向System.out打印M东西. q将大大的降低log4j的额外开销Qƈ且允怽完全享受益处Q像如果调用(log.isDebugEnabled())....如果你那么做Q那么你的代码中的所有日志都通过appenderq行格式? q个threshold 在appender被从日志消息中去除出去. 它能产生大量的垃圾信息。假设你的java package ?#8220;a.b”开始的? 在log4j.xml增加一些像q样的信?
<!--极限a.b cd为INFO -->
<category name="a.b">
<priority value="INFO"/>
</category>
q个可以增加C?span>org.apache ?org.jboss (见上?中找到过滤类别的同一区域.
部v扫描器(Deployment Scanner Q?/span>
l 部v扫描器每?span>5U扫描一ơ,在比较慢的文件系l上其吃周?(*cough* NTFS *cough*).
l 见下面的瘦nstuff on Q怎么调整U数以至于它发生的不那么频繁或者不全部发生?
无状态会?span>BeansQStateless Session Beans Q?/span>
l EJB 1.x-2.x 无状态会?span>beans operate with an ill-advised pooling model (required by the specification). 如果你find你需要考虑讄比默认(10Q实例要多的最线E池的大?
~辑 server/slim/conf/standardjboss.xml, 向下滚动:
<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>
q找?span>:
<container-pool-conf>
<MaximumSize>100</MaximumSize>
</container-pool-conf>
</container-configuration>
改变它ؓ:
<container-pool-conf>
<MinimumSize>100</MinimumSize>
<MaximumSize>100</MaximumSize>
<strictMaximumSize/>
<strictTimeout>30000</strictTimeout>
</container-pool-conf>
</container-configuration>
在很大程度上一U服务器环境中不希望q些池增长和~减(因ؓ它导致内存碎片,不如潜在的堆使用). 从性能上来? nuber要够的大以提供保证你的所有请求不d的服务?
CMP 调整
l 读这个链?span>: [url]http://www.artima.com/forums/flat.jsp?forum=141&thread=24532[/url]
l 和这个链?span>: [url]http://www.onjava.com/pub/a/onjava/2003/05/28/jboss_optimization.html[/url]
l 现在ditch CMP 和?/span>JBossHibernate 代替
q接池(Connection PoolsQ?
l 不要使用XA版本Q除非你真的知道你需要用它. XAq接的性能不好.
l 与其在可用的地方利用数据库特定的"ping"支持"check-connection"(查连?Q或者利用数据库特定驱动的fail-over支持倒不如从不checking connections. (Cq所有的优化选项都适合你的环境Q我们正在讨论的是最x? ?/span>