Mod-jk替换mod_weblogic过程报告
<o:p> </o:p>
替换原因:<o:p></o:p>
公司目前几乎全部是开源平台,而mod_weblogic是weblogic server内带的一个tomcat连接器,不提供源码,要使用不同平台的mod_weblogic必须要到不同平台的weblogic server中拿出来,可能会有商业授权的问题。而经过前期测试,mod_jk实际上已经很稳定,足以替换mod_weblogic。
<o:p> </o:p>
替换过程:<o:p></o:p>
替换过程主要有以下几步:
1、 选择jk版本,编译相应平台二进制文件
2、 修改apache配置
3、 修改tomcat配置
4、 在测试环境中调试,微调部分参数,提高性能和稳定性。
具体下面一一说明。
一、 选择jk版本,编译相应平台二进制文件<o:p></o:p>
我们目前选择的版本是<st1:chsdate isrocdate="False" month="12" w:st="on" day="30" islunardate="False" year="1899">1.2.26</st1:chsdate>,是jk最新的稳定版本(linux平台子版本号为偶数表示是一个稳定版本)。编译过程也比较简单,下面以我在测试平台编译过程为例。
首先下载tomcat-connectors-<st1:chsdate isrocdate="False" month="12" w:st="on" day="30" islunardate="False" year="1899">1.2.26</st1:chsdate>-src.tar.gz包到本地,我的目录是/usr/zgl/install,然后解压到本地,生成目录tomcat-connectors-1.2.26-src,cd tomcat-connectors-1.2.26-src/native,然后:
# ./configure --with-apxs=/usr/zgl/httpd/bin/apxs
/usr/zgl/httpd是apache目录。
# make && make install
过程中不出错就ok啦,当然保险起见,到apache的modules目录下看看mod_jk.so存在与否,最好在看看生成时间,如果没有问题,编译过程就结束了。
<o:p> </o:p>
二、 修改apache的httpd.conf配置<o:p></o:p>
首先当然是将httpd.conf中的weblogic部分的配置注释掉(^_^)。
jk的配置可以分为两个部分:基本配置和worker配置。下面简单介绍一下我们目前使用到的配置参数以及过程中遇到的问题。
基本配置项目如下:
配置项<o:p></o:p> | 说明<o:p></o:p> |
LoadModule jk_module /usr/alibaba/httpd/modules/mod_jk.so<o:p></o:p> | 告诉apache如何加载jk <o:p></o:p> |
JkLogFile "|/usr/local/sbin/cronolog ${exodus2_output}/logs/jk_logs/mod_jk.log.%w"<o:p></o:p> JkLogLevel error<o:p></o:p> JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"<o:p></o:p> | 日志设置,使用cronolog滚动日志,日志级别为error,日志日期格式等<o:p></o:p> |
JkOptions +ForwardURICompatUnparsed <o:p></o:p> | 这是最重要的设置,表示jk如何处理uri,是否需要对uri进行编码转换等。在exodus中,uri编码转换全部由webx框架处理,所以这儿选择+ForwardURICompatUnparsed,表示jk不parse uri,直接传递给tomcat。forward选项一个有4个,<st1:chsdate isrocdate="False" month="12" w:st="on" day="30" islunardate="False" year="1899">1.2.24</st1:chsdate>后缺省是+ForwardURIProxy,这个选项会对uri进行部分重新编码,如果在apache内需要对uri进行编码转换的请使用这个选项,并严格测试。<o:p></o:p> <o:p> </o:p> <o:p> </o:p> |
JkOptions +ForwardDirectories<o:p></o:p> | 这个选项告诉apache将目录相关uri交给tomcat解析,如果设为false,apache会到其缺省目录中寻找文件。<o:p></o:p> |
JkMountCopy All<o:p></o:p> | 表示某个VirtualHost是否继承全局mount设置,如果在每个VirtualHost中设置为on,表示这个VirtualHost会复制所有全局mount设置到这个VirtualHost,这里设置为all,表示所以mount设置适用于所有VirtualHost<o:p></o:p> |
JkShmFile ${exodus2_output}/jk.shm<o:p></o:p> | 用于LoadBalance和status的共享内存设置,只适用于*nix平台,我们没有使用LoadBalance,可能可以删除这个选项。<o:p></o:p> |
JkMount /offer/* localnode<o:p></o:p> | 表示将所有/offer开始的uri映射给localnode处理,localnode是一个worker,代表一个tomcat实例。<o:p></o:p> |
worker配置<o:p></o:p>
因为jk支持LoadBalance,一个jk可以连接多个tomcat并进行负载均衡,所以一个jk配置文件中会指定多个tomcat实例,每个tomcat实例称为一个worker,worker配置参数众多,很多都对性能有很大影响,需要仔细调试。<o:p></o:p>
配置项<o:p></o:p> | 说明<o:p></o:p> |
worker.list=localnode<o:p></o:p> | worker列表,如果需要负载均衡,连接多个tomcat实例,这里需要指定负载均衡节点和status节点。我们没有进行负载均衡,直接指定本地节点。 <o:p></o:p> |
worker.localnode.port=$ajp_port<o:p></o:p> worker.localnode.host=localhost<o:p></o:p> worker.localnode.type=ajp13<o:p></o:p> worker.localnode.lbfactor=1<o:p></o:p> | 指定worker的端口和主机地址等信息,这里端口必须和tomcat ajp13端口一致。<o:p></o:p> type代表使用何种协议,这里使用ajp13.<o:p></o:p> lbfactor代表负载均衡系数,这里为1.<o:p></o:p> |
worker.localnode.socket_keepalive=True<o:p></o:p> worker.localnode.socket_timeout=20<o:p></o:p> | 这两个参数表示底层socket连接使用长连接,timeout参数为20秒。这里注意socket_timeout代表每个tcp读写操作的timeout,和后面的connection连接timeout是两个概念。这个参数用来控制socket在发生异常时的反应速度,设置既不能很小,也不能很大,很小会导致大量的time_wait,很大会导致tomcat压力压不上去,缺省为0,表示无穷大,所以这个参数必须设置。<o:p></o:p> |
worker.localnode.connection_pool_size=250<o:p></o:p> worker.localnode.connection_pool_minsize=25<o:p></o:p> worker.localnode.connection_pool_timeout=600<o:p></o:p> | 连接池大小和timeout设置,连接池不可以设置很大,也不可以设置很小,具体看服务器压力。<o:p></o:p> 这里注意timeout参数必须和tomcat ajp端口timeout设置一致,否则会产生半开或者半闭连接,导致jk连接异常。<o:p></o:p> |
三、 修改tomcat端口设置<o:p></o:p>
jk使用ajp13协议和tomcat连接,所以tomcat需要配置一个新的ajp13端口和jk连接,相应的tomcat配置文件需要做相应修改。
端口配置:<Connector port="${ajp_port}" address="${jboss.bind.address}" backlog="256" maxThreads="250" emptySessionPath="true" enableLookups="false" connectionTimeout="600000" disableUploadTimeout="true" protocol="AJP/1.3" URIEncoding="GBK"/>
配置项<o:p></o:p> | 说明<o:p></o:p> |
port="${ajp_port}"<o:p></o:p> | 连接端口,必须和jk配置中worker端口一致,exodus中使用的是7011<o:p></o:p> |
address="${jboss.bind.address}"<o:p></o:p> | 绑定地址,jboss指定<o:p></o:p> |
backlog="256"<o:p></o:p> | 最大可以支持未完成连接数量,缺省是100,设置大一点比较好<o:p></o:p> |
maxThreads="250" | 最大连接数量,最好和worker连接池最大数量一致<o:p></o:p> |
emptySessionPath="true" | ???<o:p></o:p> |
enableLookups="false" | 是否允许DNS查找<o:p></o:p> |
connectionTimeout="600000" | timeout参数,必须和connection_pool_timeout参数一致,另外需要注意的是这儿单位是ms。<o:p></o:p> |
disableUploadTimeout="true" | 顾名思意<o:p></o:p> |
protocol="AJP/1.3" | 协议类型,必须是ajp13,否则jk和tomcat连不上啊<o:p></o:p> |
URIEncoding="GBK" | uri编码格式<o:p></o:p> |
<o:p> </o:p>
四、 在测试环境中调试,微调部分参数,提高性能和稳定性。<o:p></o:p>
这里说一下调试过程中发现的问题。
第一个问题就是forward参数设置,原来使用的是<st1:chsdate isrocdate="False" month="12" w:st="on" day="30" islunardate="False" year="1899">1.2.26</st1:chsdate>缺省设置ForwardURIProxy,但是在遇到编码转换的uri时,发生连接错误,tomcat收到的uri是错误转换后的uri,修改为ForwardURICompatUnparsed后问题解决,但是如果在apache配置中使用了mod_rewrite模块对url进行了编码转换,可能需要使用ForwardURIProxy,具体需要应用进行详细测试。<o:p></o:p>
<o:p> </o:p>
第二个问题是配置文件管理问题,jk可以将worker配置文件和url map配置单独一个文件管理,最初exodus也是这么做到,但是后来发现这样会导致文件同步问题,例如url map和worker中都有worker名称的引用,如果worker中修改了而url map中没有相应修改,就会导致莫名其妙的错误,所以后来将所有jk相关配置收集到一个文件中管理。<o:p></o:p>
<o:p> </o:p>
第三个问题是关于jk的LoadBalance问题,目前网上的配置几乎都是loadbalance配置的,而我们不需要loadbalance,配置成LoadBalance形式,增加了步骤,影响性能,所以需要删除相关LoadBalance配置,包括lb节点和status节点。这里注意的是要吧jkmount中的节点修改成本地节点,我一开始就是因为这个问题导致一致运行不起来,还以为jk一定要经过lb呢。<o:p></o:p>
<o:p> </o:p>
第三个问题是关于worker.localnode.socket_timeout的设置,这个设置缺省是0,代表的却是无穷大,一开始我们没有设置这个参数,后来发现ab始终压力压不上去,将这个参数设置为20s后,压力就上去了。分析估计是如果设置为0,代表这个timeout无效,这时候socket的反应比较迟钝,即使有死连接也不会立即关闭,而是不停检测,所以导致大量连接被占用,压力就上不去了。
<o:p> </o:p>
第四个问题是关于worker.localnode.connection_pool_timeout=600和tomcat设置中的connectionTimeout="600000",一开始worker设置中使用的是缺省值600s,而tomcat端口中设置是从原来http端口中拷贝过来的是20000ms,后来在生产环境发现每个服务器每隔十几分钟会有一条“refuse connect”日志,在网上找了一下也语焉不详。后来分析可能是jk端timeout设置和tomcat短设置不一样,jk端timeout时间长,tomcat端时间短,导致连接可能处于“half-open”状态,可以发送请求,但是tomcat端不能响应,经过参数调整后这个问题解决。这个参数最终定为600s是因为设定为20s时会经常有大量time_wait状态的连接,影响服务器性能,而如果定为太大,会导致服务器活动连接数太大,也会影响服务器性能,600s是一个比较合适的中间值。
<o:p> </o:p>
第五个问题是一个低级错误,在写jkmount时,将JkMount /community/* localnode写成JkMount //community/* localnode,导致相关url无法访问,而且非常难查,真是一个猥琐的错误!所以对待配置文件需要非常仔细,要字字查看才行。
<o:p> </o:p>
参考文档
最权威的参考文档还是apache网站原文:
jk配置文档:http://tomcat.apache.org/connectors-doc/generic_howto/loadbalancers.html
tomcat ajp端口配置文档:http://tomcat.apache.org/tomcat-5.5-doc/config/ajp.html
<o:p> </o:p>
<o:p> </o:p>