使用apache和nginx连接tomcat

集群 struggling 1587次浏览 2个评论

Apache可以通过mod_jk和mod_proxy模块连接Tomcat,但mod_proxy只有在apache 2.2.x系列的版本才直接提供,但它可以提供更丰富的功能和安全性;而对于apache 1.3.x和2.0.x来说mod_jk才更适用。

e54056441e3509a92d209821ebc1de08

AJP是定向包协议。因为性能原因,使用二进制格式来传输可读性文本。WEB服务器通过TCP连接和SERVLET容器连接。为了减少进程生成socket的花费,WEB服务器和SERVLET容器之间尝试保持持久性的TCP连接,对多个请求/回复循环重用一个连接。一旦连接分配给一个特定的请求,在请求处理循环结束之前不会在分配。换句话说,在连接上,请求不是多元的。这个使连接两端的编码变得容易,虽然这导致在一时刻会有很多连接。

apache 和 nginx 可以通过以下协议来连接tomcat。

<code>

	LAMT:
		apache(mod_jk, ajp) + tomcat(ajp connector)
		apache(mod_proxy, (http, https, ajp)) + tomcat(http, https, ajp)
	LNMT:
		nginx + tomcat(http, https)

</code>

规划:

<code>
前端代理: Apache   外网IP: 192.168.1.210   内网IP:172.16.1.110
                    
后端tomcat : IP : 172.16.1.111

</code>

一,使用mod_proxy模块来连接apache与tomcat。

1,安装apr和apr-util

可以从http://apr.apache.org/获取apr和apr-util的源码,目前最新的版本是APR 1.5.2。

<code>
[root@www.feiyu.com  ~]# tar  xf  apr-1.4.6.tar.bz2
[root@www.feiyu.com  ~]# cd apr-1.4.6
[root@www.feiyu.com  ~]# ./configure --prefix=/usr/local/apr 
[root@www.feiyu.com  ~]# make && make install
</code>

apr-util是apr的工具库,其可以让程序员更好的使用apr的功能。目前最新版是APR-util 1.5.4。

<code>
[root@www.feiyu.com  ~]# tar xf apr-util-1.4.1.tar.bz2
[root@www.feiyu.com  ~]# cd apr-util-1.4.1
[root@www apr-util-1.4.1]#  ./configure  --prefix=/usr/local/apr-util  --with-apr=/usr/local/apr
[root@www apr-util-1.4.1]#  make && make install
</code>

2,安装apache

httpd目前最新的2.4系列版本中引入了event MPM,其在性能上较之其它MPM有了较大的提升。

这里我们直接使用rpm包来安装httpd。

<code>
[root@node1 ~]# yum install -y httpd
</code>

3,配置apache通过mod_proxy模块与Tomcat连接

要使用mod_proxy与Tomcat实例连接,需要apache已经装载mod_proxy、mod_proxy_http、mod_proxy_ajp和proxy_balancer_module(实现Tomcat集群时用到)等模块。

<code>
[root@node1 ~]# /usr/local/apache/bin/httpd -D DUMP_MODULES | grep  proxy
 proxy_module (shared)
 proxy_connect_module (shared)
 proxy_ftp_module (shared)
 proxy_http_module (shared)
 proxy_fcgi_module (shared)
 proxy_scgi_module (shared)
 proxy_ajp_module (shared)
 proxy_balancer_module (shared)
 proxy_express_module (shared)

[root@node1 ~]# cd  /etc/httpd/conf.d/
[root@node1 conf.d]# vim mod_proxy.conf  
ProxyVia on                       
Proxyrequests off        #正反代理不能同时启用,关闭正向代理
ProxyPreserveHost on

ProxyPass / ajp://172.16.1.111:8009/
ProxyPassReverse / ajp://172.16.1.111:8009/


        Order Allow,Deny
        Allow from all

</code>

关于如上apache指令的说明:

ProxyPreserveHost {On|Off}:如果启用此功能,代理会将用户请求报文中的Host:行发送给后端的服务器,而不再使用ProxyPass指定的服务器地址。如果想在反向代理中支持虚拟主机,则需要开启此项,否则就无需打开此功能。

ProxyVia {On|Off|Full|Block}:用于控制在http首部是否使用Via:,主要用于在多级代理中控制代理请求的流向。默认为Off,即不启用此功能;On表示每个请求和响应报文均添加Via:;Full表示每个Via:行都会添加当前apache服务器的版本号信息;Block表示每个代理请求报文中的Via:都会被移除。

ProxyRequests {On|Off}:是否开启apache正向代理的功能;启用此项时为了代理http协议必须启用mod_proxy_http模块。同时,如果为apache设置了ProxyPass,则必须将ProxyRequests设置为Off。

ProxyPass [path] !|url [key=value key=value …]]:将后端服务器某URL与当前服务器的某虚拟路径关联起来作为提供服务的路径,path为当前服务器上的某虚拟路径,url为后端服务器上某URL路径。使用此指令时必须将ProxyRequests的值设置为Off。需要注意的是,如果path以“/”结尾,则对应的url也必须以“/”结尾,反之亦然。

另外,mod_proxy模块在httpd 2.1的版本之后支持与后端服务器的连接池功能,连接在按需创建在可以保存至连接池中以备进一步使用。连接池大小或其它设定可以通过在ProxyPass中使用key=value的方式定义。常用的key如下所示:

<code>
◇ min:连接池的最小容量,此值与实际连接个数无关,仅表示连接池最小要初始化的空间大小。
◇ max:连接池的最大容量,每个MPM都有自己独立的容量;都值与MPM本身有关,如Prefork的总是为1,而其它的则取决于ThreadsPerChild指令的值。
◇ loadfactor:用于负载均衡集群配置中,定义对应后端服务器的权重,取值范围为1-100。
◇ retry:当apache将请求发送至后端服务器得到错误响应时等待多长时间以后再重试。单位是秒钟。
</code>

如果Proxy指定是以balancer://开头,即用于负载均衡集群时,其还可以接受一些特殊的参数,如下所示:

<code>
◇lbmethod:apache实现负载均衡的调度方法,默认是byrequests,即基于权重将统计请求个数进行调度,bytraffic则执行基于权重的流量计数调度,bybusyness通过考量每个后端服务器的当前负载进行调度。
◇ maxattempts:放弃请求之前实现故障转移的次数,默认为1,其最大值不应该大于总的节点数。
◇ nofailover:取值为On或Off,设置为On时表示后端服务器故障时,用户的session将损坏;因此,在后端服务器不支持session复制时可将其设置为On。
◇ stickysession:调度器的sticky session的名字,根据web程序语言的不同,其值为JSESSIONID或PHPSESSIONID。
</code>

上述指令除了能在banlancer://或ProxyPass中设定之外,也可使用ProxySet指令直接进行设置,如:

<Proxy balancer://hotcluster>
   BalancerMember http://www1.feiyu.com:8080 loadfactor=1
   BalancerMember http://www2.feiyu.com:8080 loadfactor=2
   ProxySet lbmethod=bytraffic
</Proxy>

ProxyPassReverse:用于让apache调整HTTP重定向响应报文中的Location、Content-Location及URI标签所对应的URL,在反向代理环境中必须使用此指令避免重定向报文绕过proxy服务器。

为了让apache能使用/etc/httpd/conf.d/mod_proxy.conf 配置文件中的配置信息,需要编辑/etc/httpd/httpd.conf,添加如下一行:

<code>
[root@node1 httpd]# vim  httpd.conf
Include conf.d/*.conf
</code>

启动后端的tomcat服务器,

<code>
[root@node1 conf.d]# service httpd  start
[root@node1 conf.d]# curl -I http://172.16.1.111:8080
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=ISO-8859-1
Transfer-Encoding: chunked
Date: Sat, 15 Aug 2015 08:31:54 GMT
</code>

访问成功。

二,使用mod_jk模块来连接apache与tomcat

mod_jk是ASF的一个项目,是一个工作于apache端基于AJP协议与Tomcat通信的连接器,它是apache的一个模块,是AJP协议的客户端(服务端是Tomcat的AJP连接器)。首先需要安装tomcat-connectors,可以在此处下载http://tomcat.apache.org/download-connectors.cgi.

<code>
[root@www.feiyu.com  ~]# tar xf tomcat-connectors-1.2.37-src.tar.gz 
[root@www.feiyu.com  ~]# cd tomcat-connectors-1.2.37-src/native/
[root@www.feiyu.com  ~]# ./configure --with-apxs=/usr/local/apache/bin/apxs      #任意第三方模块都要使用模块函数
[root@www.feiyu.com  ~]# make && make install
</code>

使用以下方式来查询是否有apxs模块,rpm包安装的默认没有,需要安装httpd-devel包

<code>
[root@node1 tomcat-connectors-1.2.40-src]# yum install  -y httpd-devel
[root@node1 conf.d]# rpm -ql httpd-devel |grep apx
/usr/sbin/apxs
/usr/share/man/man8/apxs.8.gz
</code>

apache要使用mod_jk连接器,需要在启动时加载此连接器模块。为了便于管理与mod_jk模块相关的配置,这里使用一个专门的配置文件/etc/httpd/conf.d/mod_jk.conf来保存相关指令及其设置。其内容如下:

<code>
[root@node1 conf.d]# vim mod_jk.conf
# Load the mod_jk
LoadModule  jk_module  modules/mod_jk.so
JkWorkersFile  /etc/httpd/conf.d/workers.properties
JkLogFile  logs/mod_jk.log
JkLogLevel  debug             #启动正常后将其修改为notice
JkMount  /*  TomcatA       #所有内容转发给tomcatA,tomcatA是在workers.properties中命名的,叫JVM route
JkMount  /status/  statA
</code>

除了需要使用LoadModule指令在apache中装载模块外,mod_jk还需要在apache的主配置文件中设置其它一些指令来配置其工作属性。如JkWorkersFile则用于指定保存了worker相关工作属性定义的配置文件,JkLogFile则用于指定mod_jk模块的日志文件,JkLogLevel则可用于指定日志的级别(info, error, debug),此外还可以使用JkRequestLogFormat自定义日志信息格式。而JkMount(格式: JkMount )指定则用于控制URL与Tomcat workers的对应关系。

对于apache代理来说,每一个后端的Tomcat实例中的engine都可以视作一个worker,而每一个worker的地址、连接器的端口等信息都需要在apache端指定以便apache可以识别并使用这些worker。约定俗成,配置这些信息的文件通常为workers.properties,其具体路径则是使用前面介绍过的JkWorkersFile指定的,在apache启动时,mod_jk会扫描此文件获取每一个worker的配置信息。比如,我们这里使用/etc/httpd/conf.d/workers.properties。

workers.properties文件一般由两类指令组成:一是mod_jk可以连接的各worker名称列表,二是每一个worker的属性配置信息。它们分别遵循如下使用语法。

   worker.list = < a comma separated list of worker names >
   worker. <worker name> .<property> = <property value>

其中worker.list指令可以重复指定多次,而worker name则是Tomcat中engine组件jvmRoute参数的值。如:

<code>
worker.TomcatA.host=172.16.1.111
</code>

根据其工作机制的不同,worker有多种不同的类型,这是需要为每个worker定义的一项属性woker..type。常见的类型如下:

<code>
◇ ajp13:此类型表示当前worker为一个运行着的Tomcat实例。
◇ lb:lb即load balancing,专用于负载均衡场景中的woker;此worker并不真正负责处理用户请求,而是将用户请求调度给其它类型为ajp13的worker。
◇   status:用户显示分布式环境中各实际worker工作状态的特殊worker,它不处理任何请求,也不关联到任何实际工作的worker实例。具体示例如请参见后文中的配置。
</code>

worker其它常见的属性说明:

<code>
◇ host:Tomcat 7的worker实例所在的主机;
◇ port:Tomcat 7实例上AJP1.3连接器的端口;
◇ connection_pool_minsize:最少要保存在连接池中的连接的个数;默认为pool_size/2;
◇ connection_pool_timeout:连接池中连接的超时时长;
◇ mount:由当前worker提供的context路径,如果有多个则使用空格格开;此属性可以由JkMount指令替代;
◇ retries:错误发生时的重试次数;
◇ socket_timeout:mod_jk等待worker响应的时长,默认为0,即无限等待;
◇ socket_keepalive:是否启用keep alive的功能,1表示启用,0表示禁用;
◇ lbfactor:worker的权重,可以在负载均衡的应用场景中为worker定义此属性;
</code>

另外,在负载均衡模式中,专用的属性还有:

<code>
◇balance_workers:用于负载均衡模式中的各worker的名称列表,需要注意的是,出现在此处的worker名称一定不能在任何worker.list属性列表中定义过,并且worker.list属性中定义的worker名字必须包含负载均衡worker。具体示例请参见后文中的定义。
◇ method:可以设定为R、T或B;默认为R,即根据请求的个数进行调度;T表示根据已经发送给worker的实际流量大小进行调度;B表示根据实际负载情况进行调度。
◇sticky_session:在将某请求调度至某worker后,源于此址的所有后续请求都将直接调度至此worker,实现将用户session与某worker绑定。默认为值为1,即启用此功能。如果后端的各worker之间支持session复制,则可以将此属性值设为0。
</code>

根据前文中的指定,这里使用/etc/httpd/cond.d/workers.properties来定义一个名为TomcatA的worker,并为其指定几个属性。文件内容如下:

<code>
worker.list=TomcatA,statA
worker.TomcatA.port=8009
worker.TomcatA.host=172.16..1.111
worker.TomcatA.type=ajp13
worker.TomcatA.lbfactor=1
worker.stat1.type = status
</code>

至此,一个基于mod_jk模块与后端名为TomcatA的worker通信的配置已经完成,重启httpd服务即可生效。

<code>
[root@node1 conf.d]# curl -I http://172.16.1.111:8080  
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=ISO-8859-1
Transfer-Encoding: chunked
Date: Sat, 15 Aug 2015 10:12:04 GMT
</code>

成功访问!

三,整合nginx和tomcat

以下使用nginx-1.8.0-1.gf.el6.i686.rpm,

<code>
[root@node1 nginx]# ls
nginx-1.8.0-1.gf.el6.i686.rpm
[root@node1 nginx]# rpm -ivh nginx-1.8.0-1.gf.el6.i686.rpm

[root@node1 nginx]# cd /etc/nginx/conf.d/
[root@node1 conf.d]# vim default.conf            #在配置文件中添加

    location  ~* \.(jsp|do) {
    
        proxy_pass http://172.16.1.111:8080;
    } 

[root@node1 conf.d]# service httpd  stop   
[root@node1 conf.d]# service nginx start

[root@node1 conf.d]# curl -I  http://172.16.1.111:8080/
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=ISO-8859-1
Transfer-Encoding: chunked
Date: Sat, 15 Aug 2015 10:25:31 GMT
</code>

要使用tomcat集群时,只需配置nginx的upstream模块,如下所示:

<code>
		http {
			upstream tomcat {
				server 172.16.1.111:8080;
				server 172.16.1.112:8080;
			}
			server {
				location ~* \.(jsp|do)$ {
					proxy_pass http://tomcat;
				}
			}
		}



</code>

DevOps-田飞雨 》》转载请注明源地址
喜欢 (0)or分享 (0)
发表我的评论
取消评论
*

表情 贴图 加粗 链接 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
(2)个小伙伴在吐槽
  1. 转载请附上原文链接
    struggling  2015-12-17 09:34 回复