基于Apache+Tomcat实现负载均衡和集群服务
一、概念
从Tomcat权威指南中的测试数据,我们不难发现,对于静态页面的数据,Tomcat的处理速度比Apache要快很多,所以为什么要整合apache虽然在处理静态页面速度上比Apache快,但是Tomcat经不起大的并发量容易死。为此,我们就需要Apache,虽然apache的速度要慢一些,但能承受的起大的并发量。
我们再介绍一下为什么要让Apache与Tomcat之间进行连接。事实上Tomcat本身已经提供了HTTP服务,该服务默认的端口是8080,装好tomcat后通过8080端口可以直接使用Tomcat所运行的应用程序,你也可以将该端口改为80。
既然Tomcat本身已经可以提供这样的服务,我们为什么还要引入Apache或者其他的一些专门的HTTP服务器呢?原因有下面几个:
1. 提升对静态文件的处理性能;
2. 利用Web服务器来做负载均衡以及容错;
3. 无缝的升级应用程序。
这三点对一个web网站来说是非常之重要的,我们希望我们的网站不仅是速度快,而且要稳定,不能因为某个Tomcat宕机或者是升级程序导致用户访问不了,而能完成这几个功能的比较好的HTTP服务器是apache的http server了,它跟tomcat的结合是最紧密和可靠的。
在Apache2.2之前,一般有两个组件可选择。mod_jk和mod_jk2。后来mod_jk2由于没有开发人员的支持,没更新了,转而更新mod_jk,所以现在一般都使用mod_jk做Apache和Tomcat的连接器。要指出的是mod_jk支持 Apache 1.x和2.X系列。
不过,自从Apache2.2出来后,又多了两种种选择,那就是 proxy-ajp 和 http-proxy。大家知道Apache里的proxy模块,可以实现双向代理功能,功能非常强大。其实从连接器的实现原理上来说,用proxy模块来实现是非常自然的。proxy模块的功能无非就是把相关的请求发给特定的主机再返回结果。那连接器的功能需求就是要把所有对Servlet/JSP的请求都转给后台的Tomcat。使用proxy-ajp要比mod_jk的效率要高。使用Apache自带模块,要比另外编译的来得可靠。既然有了ajp_proxy专门的ajp协议代理,http-proxy就没有必要使用这种方法了,但这里我主要测试mod_jk来做负载均衡就不说那么多了。
二、网站架构
平台介绍:
OS Version:CentOS release 6.7 (Final) Http version: apache-tomcat-8.5.4 Jdk:java-1.8.0-openjdk Mysql version: 5.6.31 Kernel version: 2.6.32-573.el6.x86_64 [root@Tomcat1-219 tools]# service iptables stop #关闭iptables: iptables: Setting chains to policy ACCEPT: filter [ OK ] iptables: Flushing firewall rules: [ OK ] iptables: Unloading modules: [ OK ] [root@Tomcat1-219 tools]# chkconfig iptables off #关闭iptables开机启动 [root@Tomcat1-219 tools]# chkconfig --list |grep iptables #查看iptables开机启动情况 iptables 0:off 1:off 2:off 3:off 4:off 5:off 6:off [root@Tomcat1-219 tools]# vim /etc/sysconfig/selinux SELINUX=disabled #永久关闭selinux [root@Tomcat1-219 apr-1.5.2]# /usr/sbin/ntpdate time.nist.gov
三、Apache服务
因为编译Apache的要求如下:
1、磁盘空间 必须保证有50MB以上的自由临时磁盘空间。Apache安装完毕后会占据10MB左右的空间,实际的磁盘空间需求会因编译设置和是否安装第三方模块而有所不同。 2、ANSI-C编译器及编译环境 必须装有ANSI-C编译器,推荐使用自由软件基金会(FSF)的GCC。如果没有GCC,那么要确保使用的编译器符合ANSI标准,而且PATH中必须包含指向基本编译工具比如make的路径。 3、确保准确的时间 由于HTTP协议的元素都会用到时间,有必要了解一下你的系统所使用的时间同步机制。在基于网络时间协议(NTP)的系统中,一般是用tpdate或xntpd来同步时间。有关NTP软件的资料请参见NTP主页。 4、Perl 5 [可选] 有些用Perl写的支持脚本,如apxs或dbmmanage ,需要Perl5解释器(5.003或以上的版本就足够了)。如果系统中存在多个Perl解释器,比如有系统提供的Perl 4,还有你自己安装的Perl 5,推荐你使用 --with-perl 选项来确保configure脚本使用正确的版本。如果configure没有没找到Perl 5也没关系,这并不影响Apache httpd的编译和安装,只是相关的支持脚本不能使用而已。 5、apr/apr-util >= 1.2 apr和apr-util包含在Apache httpd的发行源代码中,并且在绝大多数情况下使用都不会出现问题。当然,如果apr或apr-util的1.0或1.1版本已经安装在你的系统中了,则必须将你的apr/apr-util升级到1.2版本,或者将httpd单独分开编译。要使用发行源代码中自带的apr/apr-util源代码进行安装,你必须手动完成。
所以我们要安装所需程序库
#ANSI-C编译器及编译环境,预先安装所需要的程序库 [root@Tomcat1-219 apr-1.5.2]# yum -y install gcc* autoconf libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel libxml2 libxml2-devel zlib zlib-devel glibc glibc-devel glib2 glib2-devel bzip2 bzip2-devel ncurses ncurses-devel curl curl-devel pcre-devel.x86_64
同步时间:
#确保准确的时间 [root@Tomcat1-219 apr-1.5.2]# /usr/sbin/ntpdate time.nist.gov 26 Aug 17:17:21 ntpdate[3179]: adjust time server 24.56.178.140 offset 0.455212 sec
安装apr:
[root@Tomcat1-219 apr-1.5.2]# wget http://www.apache.org/dist/apr/apr-1.5.2.tar.gz [root@Tomcat1-219 tools]# tar -xf apr-1.5.2.tar.gz [root@Tomcat1-219 tools]# cd apr-1.5.2 [root@Tomcat1-219 apr-1.5.2]# mkdir -pv /opt/application/apr-1.5.2 mkdir: created directory `/opt/application' mkdir: created directory `/opt/application/apr-1.5.2' [root@Tomcat1-219 apr-1.5.2]#./configure --prefix=/opt/application/apr [root@Tomcat1-219 apr-1.5.2]# make;make install
安装apr-util
[root@Tomcat1-219 tools]# wget http://www.apache.org/dist/apr/apr-util-1.5.4.tar.gz [root@Tomcat1-219 tools]# tar -xf apr-util-1.5.4.tar.gz [root@Tomcat1-219 tools]# cd apr-util-1.5.4 [root@Tomcat1-219 apr-util-1.5.4]# ./configure --prefix=/opt/application/apr-util-1.5.4/ --with-apr=/opt/application/apr-1.5.2/ [root@Tomcat1-219 apr-util-1.5.4]# make;make install
安装httpd
[root@Tomcat1-219 ~]# wget http://mirror.bit.edu.cn/apache//httpd/httpd-2.4.23.tar.gz [root@Tomcat1-219 ~]# tar -xf httpd-2.4.23.tar.gz [root@Tomcat1-219 ~]# cd httpd-2.4.23 [root@Tomcat1-219 httpd-2.4.23]# ./configure --prefix=/opt/application/httpd-2.4.23/ --with-apr=/opt/application/apr-1.5.2/ --with-apr-util=/opt/application/apr-util-1.5.4/ --enable-so --enable-mods-shared=all --with-mpm=worker --enable-proxy-balancer=shared --enable-proxy-http --enable-proxy-connect --enable-proxy --enable-rewrite --enable-proxy-ajp #--prefix http安装的目录; #--with-apr apr安装的目录; #--with-apr-util apr-util安装的目录; #--enable-so 必须编译成允许动态加载模块的方式,因为将来要加载mod_jk这个整合模块; #--enable-mods-shared=all 动态加载所有模块,以后所有想增加的模块都会以动态模式来安装; # 也就是最终在 httpd.conf 中以LoadModule形式来加载模块; #--with-mpm=worker 由于使用线程来处理,所以可以处理相对海量的请求,而系统资源的开销要小于基于进程的服务器。##但是,worker也使用了多进程,每个进程又生成多个线程,以获得基于进程服务器的稳定性。 #--enable-proxy-balancer=shared 表示让apache支持负载均衡功能,即动态的编译apache的负载均衡模块; #--enable-proxy-http=shared 表示动态编译apache的http代理模块; #--enable-proxy-ajp 表示动态编译apache的proxy-ajp模块; #--enable-rewrite让apache 支持地址重写功能,即动态编译apache的rewrite模块;
四、mod_jk
Building mod_jk for Unix
Apache
1.Make sure your Apache has DSO support. You can check this with $APACHE_HOME/bin/httpd -l. If you see "mod_so.c" in the output, DSO support is available. If it's missing, you may have to recompile or reinstall Apache.
[root@Tomcat1-219 ~]# /opt/application/httpd/bin/httpd -l Compiled in modules: core.c mod_so.c http_core.c worker.c
2.Find out whether your Apache has EAPI support. If you compiled it yourself from source, EAPI is probably not compiled in, unless you added it yourself (perhaps with mod_ssl). You need to build mod_jk.so with or without EAPI to match your Apache configuration. If you install a mismatched mod_jk.so, $APACHE_HOME/bin/apachectl configtest will warn you.
[root@Tomcat1-219 ~]# /opt/application/httpd/bin/apachectl configtest Syntax OK
3.Make sure you have Perl 5 installed. The apxs script used to build the module is written in Perl.
[root@Tomcat1-219 tomcat-connectors-1.2.41-src]# rpm -ql pcre /lib64/libpcre.so.0 /lib64/libpcre.so.0.0.1 /usr/bin/pcregrep /usr/bin/pcretest /usr/lib64/libpcrecpp.so.0 /usr/lib64/libpcrecpp.so.0.0.0 /usr/lib64/libpcreposix.so.0 /usr/lib64/libpcreposix.so.0.0.0 /usr/share/doc/pcre-7.8 /usr/share/doc/pcre-7.8/AUTHORS /usr/share/doc/pcre-7.8/COPYING /usr/share/doc/pcre-7.8/ChangeLog /usr/share/doc/pcre-7.8/LICENCE /usr/share/doc/pcre-7.8/NEWS /usr/share/doc/pcre-7.8/README /usr/share/man/man1/pcre-config.1.gz /usr/share/man/man1/pcregrep.1.gz /usr/share/man/man1/pcretest.1.gz
4.Change directory to TOMCAT_HOME/native/mod_jk/apache1.3 (or apache2.0).
[root@Tomcat1-219 tools]# cp tomcat-connectors-1.2.41-src/native/apache-2.0/mod_jk.so /opt/application/httpd/modules/mod_jk.so
作为apache与tomcat连接的桥梁,JK连接器使用C语言编写,与apache紧密结合,作为模块装载到apache服务器中,通过配置实现与特定的tomcat服务器进行通信,从而实现负载均衡的功能,这里需要注意的是配置脚本要添加一个apxs完整路径作为参数。apxs是一个为Apache HTTP服务器编译和安装扩展模块的工具,用于编译一个或多个源程序或目标代码文件为动态共享对象,使之可以用由mod_so提供的LoadModule指令在运行时加载到Apache服务器中。
所以接下来我们开始安装mod_jk:
[root@Tomcat1-219 tools]# tar -xf tomcat-connectors-1.2.41-src.tar.gz [root@Tomcat1-219 ~]# cd tomcat-connectors-1.2.41-src [root@Tomcat1-219 tomcat-connectors-1.2.41-src]# cd native/ [root@Tomcat1-219 native]# ll total 1364 -rw-r--r--. 1 root bin 351029 Jul 27 2015 aclocal.m4 drwxr-xr-x. 2 root bin 4096 Aug 27 13:43 apache-1.3 drwxr-xr-x. 3 root bin 4096 Aug 27 13:43 apache-2.0 -rwxr-xr-x. 1 root bin 1277 Dec 30 2014 buildconf.sh -rw-r--r--. 1 root bin 5072 Feb 26 2014 BUILDING.txt drwxr-xr-x. 3 root bin 4096 Aug 27 13:43 common -rw-r--r--. 1 root root 46800 Aug 27 13:43 config.log -rwxr-xr-x 1 root root 106 Aug 27 13:43 config.nice -rwxr-xr-x. 1 root root 64197 Aug 27 13:43 config.status -rwxr-xr-x. 1 root bin 468668 Jul 27 2015 configure -rw-r--r--. 1 root bin 21720 Dec 21 2014 configure.ac drwxr-xr-x. 3 root bin 4096 Jul 27 2015 docs drwxr-xr-x. 4 root bin 4096 Jul 27 2015 iis -rwxr-xr-x 1 root root 293168 Aug 27 13:43 libtool -rw-r--r-- 1 root root 29839 Aug 27 13:43 Makefile -rw-r--r--. 1 root bin 1362 Oct 22 2010 Makefile.am -rw-r--r--. 1 root bin 28996 Jul 27 2015 Makefile.in drwxr-xr-x. 2 root bin 4096 Jul 27 2015 netscape -rw-r--r--. 1 root bin 1844 Mar 18 2012 README.txt drwxr-xr-x. 3 root bin 4096 Jul 27 2015 scripts -rw-r--r--. 1 root bin 2565 Jul 27 2015 STATUS.txt -rw-r--r--. 1 root bin 13293 Nov 16 2011 TODO.txt [root@Tomcat1-219 native]# ./configure --with-apxs=/opt/application/httpd/bin/apxs [root@Tomcat1-219 native]# make [root@Tomcat1-219 native]# make install
JK连接器模块的部署
编译完成后使用ls命令来列出native目录下的所有目录和文件。注意有apache-1.3和apache-2.0两个目录。由于在配置编译的时候指定了apxs工具的位置。配置脚本会根据apxs的反馈结果自动识别目标apache服务器为2.x版本,因此本次编译生成的mod_jk.so模块会放在apache-2.0目录中,apache-1.3目录中是没有mod_jk.so的,这一点请注意。如下所示:
[root@Tomcat1-219 native]# ll total 1364 -rw-r--r--. 1 root bin 351029 Jul 27 2015 aclocal.m4 drwxr-xr-x. 2 root bin 4096 Aug 27 13:43 apache-1.3 drwxr-xr-x. 3 root bin 4096 Aug 27 13:43 apache-2.0 -rwxr-xr-x. 1 root bin 1277 Dec 30 2014 buildconf.sh -rw-r--r--. 1 root bin 5072 Feb 26 2014 BUILDING.txt drwxr-xr-x. 3 root bin 4096 Aug 27 13:43 common -rw-r--r--. 1 root root 46800 Aug 27 13:43 config.log -rwxr-xr-x 1 root root 106 Aug 27 13:43 config.nice -rwxr-xr-x. 1 root root 64197 Aug 27 13:43 config.status -rwxr-xr-x. 1 root bin 468668 Jul 27 2015 configure -rw-r--r--. 1 root bin 21720 Dec 21 2014 configure.ac drwxr-xr-x. 3 root bin 4096 Jul 27 2015 docs drwxr-xr-x. 4 root bin 4096 Jul 27 2015 iis -rwxr-xr-x 1 root root 293168 Aug 27 13:43 libtool -rw-r--r-- 1 root root 29839 Aug 27 13:43 Makefile -rw-r--r--. 1 root bin 1362 Oct 22 2010 Makefile.am -rw-r--r--. 1 root bin 28996 Jul 27 2015 Makefile.in drwxr-xr-x. 2 root bin 4096 Jul 27 2015 netscape -rw-r--r--. 1 root bin 1844 Mar 18 2012 README.txt drwxr-xr-x. 3 root bin 4096 Jul 27 2015 scripts -rw-r--r--. 1 root bin 2565 Jul 27 2015 STATUS.txt -rw-r--r--. 1 root bin 13293 Nov 16 2011 TODO.txt [root@Tomcat1-219 native]# ll apache-2.0/mod_jk.* -rw-r--r--. 1 root root 1880946 Aug 27 00:15 apache-2.0/mod_jk.a -rw-r--r--. 1 root bin 147504 Feb 18 2015 apache-2.0/mod_jk.c -rw-r--r--. 1 root bin 11019 Nov 14 2011 apache-2.0/mod_jk.dsp -rw-r--r--. 1 root root 934 Aug 27 00:15 apache-2.0/mod_jk.la -rw-r--r--. 1 root root 270 Aug 27 00:15 apache-2.0/mod_jk.lo -rw-r--r--. 1 root root 224336 Aug 27 00:15 apache-2.0/mod_jk.o -rwxr-xr-x. 1 root root 1143466 Aug 27 00:15 apache-2.0/mod_jk.so
我们现在将编译好的mod_jk.so拷贝到apache服务器的modules目录中,这个目录是专门用来存放扩展模块的:
[root@Tomcat1-219 tools]# cp tomcat-connectors-1.2.41-src/native/apache-2.0/mod_jk.so /opt/application/httpd/modules/mod_jk.so [root@Tomcat1-219 native]# ll /opt/application/httpd/modules/mod_jk* -rwxr-xr-x. 1 root root 1143466 Aug 27 00:16 /opt/application/httpd/modules/mod_jk.so
到这里JK连接器模块安装完成了,不过还需要配置其他文件,
我们开始修改tomcat1(tomcat8080),tomcat2(tomcat8080)的配置文件
[root@Tomcat1-219 tomcat8080]# vim conf/server.xml 120 <Engine name="Catalina" defaultHost="localhost" jvmRoute="s1"> #修改为workers.properties文件对应的值 [root@Tomcat2-220 tomcat8080]# vim conf/server.xml 120 <Engine name="Catalina" defaultHost="localhost" jvmRoute="s2"> #修改为workers.properties文件对应的值
workers.properties配置文件:
[root@Tomcat1-219 conf.d]# vim workers.properties 1 # 2 # workers.properties 3 # 4 5 # list the workers by name 6 worker.list=loadBalanceServers, jk_watcher 7 8 # Tomcat1 9 # ------------------------ 10 worker.s1.port=8009 11 worker.s1.host=192.168.2.219 12 worker.s1.type=ajp13 13 worker.s1.lbfactor=10 14 worker.s1.cachesize=5 15 worker.s1.connection_pool_size=800 16 worker.s1.connection_pool_minsize=25 17 worker.s1.connection_pool_timeout=600 18 # Tomcat2 19 # ------------------------ 20 worker.s2.port=8009 21 worker.s2.host=192.168.2.220 22 worker.s2.type=ajp13 23 worker.s2.lbfactor=10 24 worker.s2.cachesize=5 25 worker.s1.connection_pool_size=800 26 worker.s1.connection_pool_minsize=25 27 worker.s1.connection_pool_timeout=600 28 29 worker.loadBalanceServers.type=lb 30 worker.loadBalanceServers.balanced_workers=s1,s2 31 worker.loadBalanceServers.sticky_session=0 32 worker.jk_watcher.type=status 33 # worker.jk_watcher.read_only=True 34 worker.jk_watcher.mount=/admin/jk 35 worker.retries=3 36
uriworkermap.properties配置文件:
[root@Tomcat1-219 conf.d]# vim uriworkermap.properties 1 # 2 # uriworkermap.properties 3 # 4 5 #define all requests will be submitted to load balance servers 6 #if the condition is satisfied, the filter will validate the next statement until it's not. 7 #notice the order of the following statements 8 /*=loadBalanceServers 9 /jkstatus=jk_watcher 10 !/*.gif=loadBalanceServers 11 !/*.jpg=loadBalanceServers 12 !/*.tif=loadBalanceServers 13 !/*.png=loadBalanceServers 14 !/*.bmp=loadBalanceServers 15 !/*.html=loadBalanceServers 16 !/*.htm=loadBalanceServers 17 !/*.swf=loadBalanceServers 18 !/*.css=loadBalanceServers 19 !/*.js=loadBalanceServers
mod_jk.conf配置文件:
[root@Tomcat1-219 conf.d]# vim mod_jk.conf 1 LoadModule jk_module modules/mod_jk.so 2 JkWorkersFile /opt/application/httpd/conf.d/workers.properties 3 JkLogFile /opt/application/httpd/logs/mod_jk.log 4 JkShmFile /opt/application/httpd/logs/mod_jk.shm 5 JkMountFile /opt/application/httpd/conf.d/uriworkermap.properties 6 JkLogLevel debug 7 JkMount /* jie 8 JkMount /jkstatus/ stat1
我们启动apche和两个tomcat,并在每个tomcat的webapp下新建一个index.jsp文件
[root@Tomcat1-219 test]# vim /opt/application/tomcat8080/webapps/test/index.jsp 1 <html> 2 <head> 3 <title>HelloWorldJSP~</title> 4 </head> 5 <body> 6 <% 7 out.println("This is my Tomcat1-219's-JSP page"); 8 %> 9 </body> 10 </html>
打开浏览器:http://192.168.2.219:80/test/index.jsp
再刷新下网页,成功!
五、mod_proxy模块连接Tomcat
1、修改http/conf/httpd.conf配置文件
[root@Tomcat1-219 ~]# vim /opt/application/httpd/conf/httpd.conf LoadModule authn_file_module modules/mod_authn_file.so LoadModule authn_core_module modules/mod_authn_core.so LoadModule authz_host_module modules/mod_authz_host.so LoadModule authz_groupfile_module modules/mod_authz_groupfile.so LoadModule authz_user_module modules/mod_authz_user.so LoadModule authz_core_module modules/mod_authz_core.so LoadModule access_compat_module modules/mod_access_compat.so LoadModule auth_basic_module modules/mod_auth_basic.so LoadModule reqtimeout_module modules/mod_reqtimeout.so LoadModule filter_module modules/mod_filter.so LoadModule mime_module modules/mod_mime.so LoadModule log_config_module modules/mod_log_config.so LoadModule env_module modules/mod_env.so LoadModule headers_module modules/mod_headers.so LoadModule setenvif_module modules/mod_setenvif.so LoadModule version_module modules/mod_version.so LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_http_module modules/mod_proxy_http.so LoadModule proxy_ajp_module modules/mod_proxy_ajp.so LoadModule unixd_module modules/mod_unixd.so LoadModule status_module modules/mod_status.so LoadModule autoindex_module modules/mod_autoindex.so LoadModule dir_module modules/mod_dir.so LoadModule alias_module modules/mod_alias.so 这里是我LoadModule语句块的情况,文件末尾添加一句话 528 Include conf.d/*.conf [root@Tomcat1-219 conf.d]# vim http_tomcat.conf 1 <VirtualHost *:80> 2 ServerName apache-http-tomcat.com 3 ProxyRequests off 4 ProxyVia On 5 ProxyPreserveHost On 6 <Proxy *> 7 Require all granted 8 </Proxy> 9 ProxyPass / http://localhost:8080/ 10 ProxyPassReverse / http://localhost:8080/ 11 <Location /> 12 Require all granted 13 </Location> 14 </VirtualHost> [root@Tomcat1-219 conf.d]# ../bin/apachectl stop [root@Tomcat1-219 conf.d]# ../bin/apachectl 重启httpd服务
浏览器打开http://192.168.2.219:80,测试成功!
六、Tomcat服务及集群session会话保持
tomcat体系结构
Tomcat服务器的启动是基于一个server.xml文件的,Tomcat启动的时候首先会启动一个Server,Server里面就会启动Service,Service里面就会启动多个"Connector(连接器)",每一个连接器都在等待客户机的连接,当有用户使用浏览器去访问服务器上面的web资源时,首先是连接到Connector(连接器),Connector(连接器)是不处理用户的请求的,而是将用户的请求交给一个Engine(引擎)去处理,Engine(引擎)接收到请求后就会解析用户想要访问的Host,然后将请求交给相应的Host,Host收到请求后就会解析出用户想要访问这个Host下面的哪一个Web应用,一个web应用对应一个Context。
下面这张图更好帮我们理解这种情况:
元素名
|
属性
|
解释
|
server |
port |
指定一个端口,这个端口负责监听关闭tomcat的请求 |
shutdown |
指定向端口发送的命令字符串 |
|
service |
name |
指定service的名字 |
Connector(表示客户端和service之间的连接) |
port |
指定服务器端要创建的端口号,并在这个断口监听来自客户端的请求 |
minProcessors |
服务器启动时创建的处理请求的线程数 |
|
maxProcessors |
最大可以创建的处理请求的线程数 |
|
enableLookups |
如果为true,则可以通过调用request.getRemoteHost()进行DNS查询来得到远程客户端的实际主机名,若为false则不进行DNS查询,而是返回其ip地址 |
|
redirectPort |
指定服务器正在处理http请求时收到了一个SSL传输请求后重定向的端口号 |
|
acceptCount |
指定当所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数,超过这个数的请求将不予处理 |
|
connectionTimeout |
指定超时的时间数(以毫秒为单位) |
|
Engine(表示指定service中的请求处理机,接收和处理来自Connector的请求) |
defaultHost |
指定缺省的处理请求的主机名,它至少与其中的一个host元素的name属性值是一样的 |
Context(表示一个web应用程序,通常为WAR文件,关于WAR的具体信息见servlet规范) |
docBase |
应用程序的路径或者是WAR文件存放的路径 |
path |
表示此web应用程序的url的前缀,这样请求的url为http://localhost:8080/path/**** |
|
reloadable |
这个属性非常重要,如果为true,则tomcat会自动检测应用程序的/WEB-INF/lib 和/WEB-INF/classes目录的变化,自动装载新的应用程序,我们可以在不重起tomcat的情况下改变应用程序 |
|
host(表示一个虚拟主机) |
name |
指定主机名 |
appBase |
应用程序基本目录,即存放应用程序的目录 |
|
unpackWARs |
如果为true,则tomcat会自动将WAR文件解压,否则不解压,直接从WAR文件中运行应用程序 |
|
Logger(表示日志,调试和错误信息) |
className |
指定logger使用的类名,此类必须实现org.apache.catalina.Logger 接口 |
prefix |
指定log文件的前缀 |
|
suffix |
指定log文件的后缀 |
|
timestamp |
如果为true,则log文件名中要加入时间,如下例:localhost_log.001-10-04.txt |
|
Realm(表示存放用户名,密码及role的数据库) |
className |
指定Realm使用的类名,此类必须实现org.apache.catalina.Realm接口 |
Valve(功能与Logger差不多,其prefix和suffix属性解释和Logger 中的一样) |
className |
指定Valve使用的类名,如用org.apache.catalina.valves.AccessLogValve类可以记录应用程序的访问信息 |
directory |
指定log文件存放的位置 |
|
pattern |
有两个值,common方式记录远程主机名或ip地址,用户名,日期,第一行请求的字符串,HTTP响应代码,发送的字节数。combined方式比common方式记录的值更多 |
[root@Tomcat1-219 tools]# wget http://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-8/v8.5.4/bin/apache-tomcat-8.5.4.tar.gz --2016-08-27 14:02:52-- http://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-8/v8.5.4/bin/apache-tomcat-8.5.4.tar.gz Resolving mirrors.tuna.tsinghua.edu.cn... 166.111.206.63, 2402:f000:1:416:166:111:206:63 Connecting to mirrors.tuna.tsinghua.edu.cn|166.111.206.63|:80... connected. HTTP request sent, awaiting response... 200 OK Length: 9271609 (8.8M) [application/octet-stream] Saving to: “apache-tomcat-8.5.4.tar.gz” 100%[=========================================================>] 9,271,609 1.99M/s in 7.5s 2016-08-27 14:03:05 (1.18 MB/s) - “apache-tomcat-8.5.4.tar.gz” saved [9271609/9271609] [root@Tomcat1-219 tools]# cp -r apache-tomcat-8.5.4 /opt/application/tomcat8080 [root@Tomcat1-219 webapps]# ll #把测试用的test.war放在webapps目录下 total 14764 drwxr-x--- 14 root root 4096 Aug 27 14:05 docs drwxr-x--- 6 root root 4096 Aug 27 14:05 examples drwxr-x--- 5 root root 4096 Aug 27 14:05 host-manager drwxr-x--- 5 root root 4096 Aug 27 14:05 manager drwxr-x--- 3 root root 4096 Aug 27 14:05 ROOT drwxr-x--- 4 root root 4096 Aug 27 14:25 test drwxr-x--- 4 root root 4096 Aug 27 14:16 TestProject -rw-r--r-- 1 root root 15087013 Nov 19 2011 test.war
修改web.xml文件:
配置web.xml文件只需要在末端web-app前面添加<distributable/>即可;
<welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <distributable/> </web-app>
[root@Tomcat1-219 webapps]# netstat -tunlp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1346/sshd tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1425/master tcp 0 0 :::80 :::* LISTEN 1521/httpd tcp 0 0 :::22 :::* LISTEN 1346/sshd tcp 0 0 ::1:25 :::* LISTEN 1425/master [root@Tomcat1-219 webapps]# ../bin/startup.sh Using CATALINA_BASE: /opt/application/tomcat8080 Using CATALINA_HOME: /opt/application/tomcat8080 Using CATALINA_TMPDIR: /opt/application/tomcat8080/temp Using JRE_HOME: /usr Using CLASSPATH: /opt/application/tomcat8080/bin/bootstrap.jar:/opt/application/tomcat8080/bin/tomcat-juli.jar Tomcat started. [root@Tomcat1-219 webapps]# netstat -tunlp tomcat8080端口已经起来了 Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1346/sshd tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1425/master tcp 0 0 ::ffff:127.0.0.1:8005 :::* LISTEN 4349/java tcp 0 0 :::8009 :::* LISTEN 4349/java tcp 0 0 :::8080 :::* LISTEN 4349/java tcp 0 0 :::80 :::* LISTEN 1521/httpd tcp 0 0 :::22 :::* LISTEN 1346/sshd tcp 0 0 ::1:25 :::* LISTEN 1425/master
tomcat的日志没有报错,也能看到服务起来了:
[root@Tomcat1-219 tomcat8080]# tail -f logs/catalina.out 27-Aug-2016 14:28:11.401 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler [http-nio-8080] 27-Aug-2016 14:28:11.415 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler [ajp-nio-8009] 27-Aug-2016 14:28:11.422 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 7923 ms
测试session复制
分别在tomcat项目部署目录下创建test文件夹,并创建session.jsp文件,文件内容如下:
打开浏览器输入http://192.168.2.219/test/session.jsp
再刷新下网页:
LoadModule: #表示当apache服务启动时要加载模块jk_module为模块的别名,后面跟的modules/mod_jk.so就是相对于apache服务器所在目录(/opt/application/httpd-2.4.23/)的模块文件名; <IfModule jk_module>区域: #表示当apache服务器加载jk_module(在LoadModule指令中指定的模块别名)模块时所做的配置; JkWorkersFile: #指定负载均衡服务器的配置文件,文件名为相对于apache服务器所在目录的conf/workers.properties文件; JkMountFile: #指定那些请求交由负载均衡服务器来处理,那些由apache服务器来处理,配置文件为相对于apache服务器所在目录的conf/uriworkermap.properties文件; JkLogFile: #指定JK连接器的日志输出文件,文件为相对于apache服务器所在目录的logs/mod_jk.log文件; JkLogLevel #指定JK连接器输出日志的级别,级别为warn以上的日志将被输出到日志文件中,可选的值级别由低到高分别为:TRACE DEBUG INFO WARN ERROR FATAL ------------------------------------------------------------------------------------------------------------------------------------------------ <IfModule worker.c>区域: #表示当apache服务器以worker模式工作时使用的配置。 StartServers: #设置服务器启动时建立的子进程数量。因为子进程数量动态的取决于负载的轻重,所有一般没有必要调整这个参数。 ServerLimit: #服务器允许配置的进程数上限。只有在你需要将MaxClients和ThreadsPerChild设置成需要超过默认值16个子进程的时候才需要使用这个指令。不要将该指令的值设置的比MaxClients 和ThreadsPerChild需要的子进程数量高。修改此指令的值必须完全停止服务后再启动才能生效,以restart方式重启动将不会生效。 ThreadLimit: #设置每个子进程可配置的线程数ThreadsPerChild上限,该指令的值应当和ThreadsPerChild可能达到的最大值保持一致。修改此指令的值必须完全停止服务后再启动才能生效,以restart方式重启动将不会生效。 MaxClients: #用于伺服客户端请求的最大接入请求数量(最大线程数)。任何超过MaxClients限制的请求都将进入等候队列。默认值是"400",16 (ServerLimit)乘以25(ThreadsPerChild)的结果。因此要增加MaxClients的时候,你必须同时增加 ServerLimit的值。笔者建议将初始值设为(以Mb为单位的最大物理内存/2),然后根据负载情况进行动态调整。比如一台4G内存的机器,那么初始值就是4000/2=2000。 MinSpareThreads: #最小空闲线程数,默认值是"75"。这个MPM将基于整个服务器监视空闲线程数。如果服务器中总的空闲线程数太少,子进程将产生新的空闲线程。 MaxSpareThreads: #设置最大空闲线程数。默认值是"250"。这个MPM将基于整个服务器监视空闲线程数。如果服务器中总的空闲线程数太多,子进程将杀死多余的空闲线程。MaxSpareThreads的取值范围是有限制的。Apache将按照如下限制自动修正你设置的值:worker要求其大于等于 MinSpareThreads加上ThreadsPerChild的和。 ThreadsPerChild: #每个子进程建立的线程数。默认值是25。子进程在启动时建立这些线程后就不再建立新的线程了。每个子进程所拥有的所有线程的总数要足够大,以便可以处理可能的请求高峰。 MaxRequestsPerChild: #设置每个子进程在其生存期内允许伺服的最大请求数量。到达MaxRequestsPerChild的限制后,子进程将会结束。如果MaxRequestsPerChild为"0",子进程将永远不会结束。将MaxRequestsPerChild设置成非零值有两个好处:可以防止(偶然的)内存泄漏无限进行而耗尽内存; 给进程一个有限寿命,从而有助于当服务器负载减轻的时候减少活动进程的数量。 #如果设置为非零值,笔者建议设为10000-30000之间的一个值。 公式: ThreadLimit >= ThreadsPerChild MaxClients <= ServerLimit * ThreadsPerChild,并且MaxClients必须是ThreadsPerChild的倍数 MaxSpareThreads >= MinSpareThreads+ThreadsPerChild
接下来配置上面提到的conf/workers.properties文件和conf/uriworkermap.properties文件:
# # workers.properties # # list the workers by name worker.list=loadBalanceServers, jk_watcher # Tomcat1 # ------------------------ worker.s1.port=8009 worker.s1.host=192.168.2.219 worker.s1.type=ajp13 worker.s1.lbfactor=10 worker.s1.cachesize=5 worker.s1.connection_pool_size=800 worker.s1.connection_pool_minsize=25 worker.s1.connection_pool_timeout=600 # Tomcat2 # ------------------------ worker.s2.port=8109 worker.s2.host=192.168.2.219 worker.s2.type=ajp13 worker.s2.lbfactor=10 worker.s2.cachesize=5 worker.s1.connection_pool_size=800 worker.s1.connection_pool_minsize=25 worker.s1.connection_pool_timeout=600 worker.loadBalanceServers.type=lb worker.loadBalanceServers.balanced_workers=s1,s2 worker.loadBalanceServers.sticky_session=false worker.jk_watcher.type=status # worker.jk_watcher.read_only=True worker.jk_watcher.mount=/admin/jk worker.retries=3
# # uriworkermap.properties # #define all requests will be submitted to load balance servers #if the condition is satisfied, the filter will validate the next statement until it's not. #notice the order of the following statements /*=loadBalanceServers /jkstatus=jk_watcher !/*.gif=loadBalanceServers !/*.jpg=loadBalanceServers !/*.tif=loadBalanceServers !/*.png=loadBalanceServers
在配置文件中,以“!”开头的条件表示“不要”,“=”表示交给。
因此条件“/*=loadBalanceServers”表示将任何请求交给负载均衡服务器。
条件“!/*.jpg=loadBalanceServers”表示不要将.jpg结尾的请求交给负载均衡服务器
apache服务器接收到一个请求后会按照配置文件中的约束条件一个一个地检查,然后按照最后满足的匹配条件来决定由哪个worker来处理请求。
经过上面的条件筛选,最符合条件的就是“/*=loadBalanceServers”。因此将请求转给了负载均衡服务器。
试想一下,如果在apache主目录下放置了一个名为a.jpg的图片,访问路径为http://127.0.0.1/a.jpg,请求经过该配置的检查,最后满足的条件就是“!/*.jpg=loadBalanceServers”,不要将.jpg结尾的请求交给负载均衡服务器,因此apache服务自己处理了该请求。
.jpg是静态数据,apache由C语言实现,直接针对系统底层进行IO操作,因此静态性能优良。而tomcat作为Servlet容器,擅长的是J2EE相关业务的解析。因此通过这样配置可以实现应用的“动静态分离”,相互取长补短,优化了性能。类似地也可以将.js、.css和.html等等静态文件按照上述格式填写到uriworkermap.properties配置文件中。
修改/opt/application/tomcat8080/conf/web.xml,配置web.xml文件只需要在末端web-app前面添加<distributable/>即可;
4682 4683 <welcome-file-list> 4684 <welcome-file>index.html</welcome-file> 4685 <welcome-file>index.htm</welcome-file> 4686 <welcome-file>index.jsp</welcome-file> 4687 </welcome-file-list> 4688 <distributable/> 4689 </web-app>
修改linux打开文件描述符,修改成65535;
#<domain> <type> <item> <value> # * soft nofile 65535 * hard nofile 65535 [root@Tomcat1-219 conf]# ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 3831 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 65535 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 10240 cpu time (seconds, -t) unlimited max user processes (-u) 3831 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited
原创文章,作者:zuoyang1990,如若转载,请注明出处:http://www.178linux.com/40555