在上一期我说完了关于tomcat的基本使用方法并且还添加了一个小项目(其实就是一个welcome cookiesinn的页面),不过由于tomcat对http协议的选项匮乏(可以理解为功能略少)在实际使用中经常遇到使用httpd来代理tomcat,并且中间使用ajp协议进行代理!
为什么多此一举使用httpd来反向代理tomcat?
首先就像刚刚说到的使用tomcat自带的http协议肯定无法满足企业的需求,当然如果使用人数较少或者是用于代码测试也不需要多此一举的来反向代理。第二种方案是为了以后实现动静分离,所以使用httpd来反向代理tomcat。这样大大减少了动态网站服务器的压力,当然如果tomcat还是无法顶住压力接下应该使用的是负载均衡,而不是反向代理了!
httpd反向代理tomcat实验拓扑:
使用效果如下所示:
请求的流程也比较的简单:client请求资源给httpd->通过主机的网卡经过用户空间交给httpd->httpd收到请求之后分析报文根据需要开始传递给后端tomcat主机->后端tomcat主机收到请求后通过ajp | http协议将请求报文给httpd->httpd收到报文后再转交给client。
当然如果你觉得放在一个主机中不满意的话,可以拆成两台虚拟机进行实验!
httpd反向代理tomcat的方案:
方案一共有三种:①用httpd的http proxy模块 ②使用httpd的ajp proxy模块③使用tomcat提供的mod_jk模块进行,需要对httpd增加mod_jk模块进行代理(非常不推荐,因为还要编译模块,并且配置复杂!)
使用httpd的http proxy模块来反向代理:
首先当然就是安装tomcat和httpd了,关于安装httpd这个直接使用yum进行安装;yum install httpd -y 即可,或者和我一样编译安装。安装tomcat可以参考上一期进行安装。
①首先打开httpd的相关模块,在httpd的配置文件中(针对编译安装httpd,如果yum安装也检查一下)
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
保证上述的三个模块打开即可!
②给httpd添加虚拟主机并且进行反向代理:
首先在httpd.conf的配置文件中打开虚拟主机:
# Virtual hosts
Include /etc/httpd/extra/httpd-vhosts.conf
随后别忘了把主页中的DocumentRoot注释掉:
#DocumentRoot “/usr/local/apache/htdocs”
编辑虚拟主机的配置文件:/etc/httpd/extra/httpd-vhosts.conf
<VirtualHost *:80>
ServerName 172.16.1.20 #httpd的主机名
ErrorLog /var/log/http_error.log #错误日志存放位置
CustomLog /var/log/http_access.log common #访问日志存放位置
ProxyVia Off #进行反响代理并增加首部,详细在下面
ProxyRequests Off #关闭正向代理,详细在下面
ProxyPreserveHost Off #支持后端虚拟主机的主机名,详细在下面
ProxyPass / http://172.16.1.20:8080/
ProxyPassReverse / http://172.16.1.20:8080/
<Proxy *>
Require all granted
</Proxy>
<Location / >
Require all granted
</Location>
</VirtualHost>
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。
ProxyPreserveHost {On|Off}:如果启用此功能,代理会将用户请求报文中的Host:行发送给后端的服务器,而不再使用ProxyPass指定的服务器地址。如果想在反向代理中支持虚拟主机,则需要开启此项,否则就无需打开此功能。
ProxyPass & ProxyPassReverse 这两个选项都是填写后端主机的URL和端口,我在上面填写的URL是使用第二种方案的ajp协议,如果需要使用第一种方案请将ajp替换为http并且将端口改掉!默认tomcat的http协议为8080,ajp协议为8009!需要注意的是,如果path以“/”结尾,则对应的url也必须以“/”结尾,反之亦然。
如果需要更加详细的proxy代理说明可以查看httpd官方文档:http://httpd.apache.org/docs/2.4/en/mod/mod_proxy.html
③编辑tomcat定义一个虚拟主机:
<Engine name="Catalina" defaultHost="172.16.1.20"> <Realm className="org.apache.catalina.realm.LockOutRealm"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> </Realm> <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> </Host> <Host name="172.16.1.20" appBase="/var/tomcat" unpackWARs="true" autoDeploy="true"> <Context path="/" docBase="myapp" /> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="/var/logs" prefix="myapp_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> </Host> #上述是我从engine的配置段进行配置的虚拟主机大家可以参考!
④启动服务并且查看实验结果:
注意,我这边虚拟机使用的是nat模式所以我在物理机访问使用的端口映射来进行访问,大家访问的时候只需要写上URL即可不需要写8080端口。
使用httpd的http ajp模块来反向代理:
在上面我已经打开了在httpd.conf配置文件中的ajp模块,所以这一步省略。只需要在定义虚拟主机的时候改变ProxyPass & ProxyPassReverse的值即可:
ProxyPass / ajp://172.16.1.20:8009/
ProxyPassReverse / ajp://172.16.1.20:8009/
随后重启服务并查看代理结果!
使用mod_jk作为httpd反代tomcat:
虽然一直非常不推荐使用mod_jk因为配置麻烦并且也没有其他特殊的功能,不过在很老版本的httpd是不支持反代tomcat的所以要用到mod_jk这个由tomcat出品的东西!
①下载mod_jk模块:
在tomcat.apache.org之中,看到download之中的Tomcat Connectors点进去以后别忘了选择是unix linux macos版本的!
②编译mod_jk模块:
[root@www ~] tar -xf tomcat-connectors-1.2.42-src.tar.gz [root@www ~] cd tomcat-connectors-1.2.42-src [root@www tomcat-connectors-1.2.42-src] ll total 52 drwxr-xr-x. 2 root bin 81 Sep 27 20:13 conf drwxr-xr-x. 10 root bin 4096 Sep 27 20:13 docs -rw-r--r--. 1 root bin 7819 Apr 1 2014 HOWTO-RELEASE.txt drwxr-xr-x. 6 root bin 99 Sep 27 20:13 jkstatus -rw-r--r--. 1 root bin 13597 May 4 2008 LICENSE drwxr-xr-x. 9 root bin 4096 Sep 27 20:14 native -rw-r--r--. 1 root bin 455 Jan 2 2016 NOTICE -rw-r--r--. 1 root bin 1238 Mar 18 2012 README.txt drwxr-xr-x. 2 root bin 4096 Sep 27 20:13 support drwxr-xr-x. 4 root bin 4096 Sep 27 20:13 tools drwxr-xr-x. 9 root bin 4096 Sep 27 20:13 xdocs [root@www tomcat-connectors-1.2.42-src] cd native/ [root@www native]# ./configure --with-apxs=/usr/local/apache/bin/apxs && make && make install #上述是编译安装的过程,执行编译在native文件中。 #注意的是如果你是使用yum安装的httpd
③创建mod_jk的专用配置文件:
在创建之前首先还是检查一下mod_jk文件是否存在?
[root@www native] ls /usr/local/apache/modules/ | grep "^mod_jk" mod_jk.so
创建专用配置文件:
[root@www native] vim /etc/httpd/extra/httpd-jk.conf # Load the mod_jk LoadModule jk_module modules/mod_jk.so #装载mod_jk模块 JkWorkersFile /etc/httpd/extra/workers.properties #指明运行时配置文件的位置 JkLogFile logs/mod_jk.log #指定log日志位置 JkLogLevel debug #指定日志级别,根据需求自定义 JkMount /* cookiesinn #将所有httpd请求映射为cookiesinn集群中,这个名字可以自定义 JkMount /status/ test1 #状态监控页面,这个名字也可以自己定义
配置完毕mod_jk的配置文件以后咱们还没有定义主机的配置文件,按照我们上面定义的地址:/etc/httpd/extra/workers.properties我们还得定义这个文件:
[root@www native] vim /etc/httpd/extra/workers.properties worker.list=cookiesinn,test1 #定义时要和httpd_jk.conf中定义的集群一致 worker.cookiesinn.port=8009 #定义后端的端口 worker.cookiesinn.host=172.16.1.20 #定义后端的额主机 worker.cookiesinn.type=ajp13 #定义使用协议 worker.cookiesinn.lbfactor=1 #定义权重 worker.test1.type = status #定义时要和httpd_jk.conf中状态监控页面一致
增加mod_jk的子配置文件给httpd.conf主配置文件:
添加如下语法最好和Include一起不过添加在结尾也没多大关系:
Include /etc/httpd/extra/httpd-jk.conf
④修改tomcat配置文件:
只需要修改engine段落即可,比如: <Engine name=”Catalina” defaultHost=”172.16.1.20″ jvmRoute=”cookiesinn”>其中里面的名字要与httpd在中workers.properties里面的定义的<worker name>相同注意要看仔细定义名字的主机地址端口是否和tomcat本机相符!
⑤重新启动服务并且测试是否OK?
不过在重新启动服务之前还得提醒大家一下,别忘了将httpd.conf主配置文件中的虚拟主机给关闭,并且将DocumentRoot的主页打开:
[root@www httpd] vim /etc/httpd/httpd.conf #首先注释虚拟主机: # Virtual hosts #Include /etc/httpd/extra/httpd-vhosts.conf #其次开启DocumentRoot: DocumentRoot "/usr/local/apache/htdocs"
看起来一切搞定,不过可能会有少数人出现:It Works!或者是httpd的专用首页,如果遇到这种情况首先需要查看DocumentRoot是否取消注释?随后还得在httpd.conf主配置文件中修改这个语句:DirectoryIndex index.html 添加index.jsp在index.html之前,效果是:DirectoryIndex index.jsp index.html
好了以上三种办法已经全部写完了!感谢大家能全部看完。
Comments