Nginx + Tomcat基於HTTP協議實現反代、動靜分離、負載均衡和session會話保持
1、演示環境:
IP |
作業系統 |
部署程式 |
192.168.1.143 |
CentOS 7.5 |
Nginx |
192.168.1.144 |
CentOS 7.5 |
Tomcat |
192.168.1.145 |
CentOS 7.5 |
Tomcat |
2、配置192.168.1.144節點的主機名:
# vim /etc/hosts --> 192.168.1.144 TomcatA.qiuyue.com TomcatA
# vim /etc/hostname --> TomcatA
# hostnamectl set-hostname TomcatA
# hostname TomcatA
# logout
Ctrl + Shift + r
# hostname
3、配置192.168.1.145節點的主機名:
# vim /etc/hosts --> 192.168.1.145 TomcatB.qiuyue.com TomcatB
# vim /etc/hostname --> TomcatB
# hostnamectl set-hostname TomcatB
# hostname TomcatB
# logout
Ctrl + Shift + r
# hostname
4、192.168.1.144節點自定義Tomcat Host虛擬主機:
# cd /usr/local/tomcat/conf
# cp server.xml server.xml.bak
# vim server.xml,在</Host>和</Engine>之間新增如下程式碼:
<Host name="TomcatA.qiuyue.com" appBase="/data/webapps" unpackWARs="true" autoDeploy="true">
<Context path="" docBase="ROOT" reloadable="true" />
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="/data/logs" prefix="TomcatA_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" />
</Host>
5、192.168.1.145節點自定義Tomcat Host虛擬主機:
# cd /usr/local/tomcat/conf
# cp server.xml server.xml.bak
# vim server.xml,在</Host>和</Engine>之間新增如下程式碼:
<Host name="TomcatB.qiuyue.com" appBase="/data/webapps" unpackWARs="true" autoDeploy="true">
<Context path="" docBase="ROOT" reloadable="true" />
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="/data/logs" prefix="TomcatB_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" />
</Host>
6、192.168.1.144節點建立如下目錄及測試頁:
# mkdir -pv /data/{webapps,logs}
# mkdir -pv /data/webapps/ROOT
# vim /data/webapps/ROOT/index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head><title>TomcatA</title></head>
<body>
<h1><font color="red">TomcatA.qiuyue.com</font></h1>
<table border="1">
<tr>
<td>Session ID</td>
<% session.setAttribute("qiuyue.com","qiuyue.com"); %>
<td><%= session.getId() %></td>
</tr>
<tr>
<td>Created ON</td>
<td><%= session.getCreationTime() %></td>
</tr>
</table>
</body>
</html>
7、192.168.1.145節點建立如下目錄及測試頁:
# mkdir -pv /data/{webapps,logs}
# mkdir -pv /data/webapps/ROOT
# vim /data/webapps/ROOT/index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head><title>TomcatB</title></head>
<body>
<h1><font color="blue">TomcatB.qiuyue.com</font></h1>
<table border="1">
<tr>
<td>Session ID</td>
<% session.setAttribute("qiuyue.com","qiuyue.com"); %>
<td><%= session.getId() %></td>
</tr>
<tr>
<td>Created ON</td>
<td><%= session.getCreationTime() %></td>
</tr>
</table>
</body>
</html>
8、分別啟動192.168.1.144節點和192.168.1.145節點上的Tomcat:
# catalina.sh stop # catalina.sh configtest # catalina.sh start # ss -tunlp | grep -w :8080
9、配置192.168.1.143節點/etc/hosts檔案:# vim /etc/hosts
192.168.1.144 TomcatA.qiuyue.com TomcatA
192.168.1.145 TomcatB.qiuyue.com TomcatB
10、在192.168.1.143節點中使用curl命令訪問:
# curl http://TomcatA.qiuyue.com:8080 //能正常顯示文字內容
# curl http://TomcatB.qiuyue.com:8080 //能正常顯示文字內容
11、192.168.1.143節點實現反代、動靜分離和負載均衡:
# yum -y install epel-release
# yum -y install nginx
# cd /etc/nginx
# cp nginx.conf nginx.conf.bak
# vim nginx.conf
(1)在http配置段中、server配置段外新增如下upstream:
upstream tcsrvs {
server TomcatA.qiuyue.com:8080;
server TomcatB.qiuyue.com:8080;
}
(2)在server配置段中新增如下location:
location ~* \.(jsp|do)$ {
proxy_pass http://tcsrvs;
}
備註:將.jsp和.do結尾的請求反向代理至http://tcsrvs
# nginx -t # systemctl start nginx.service # ss -tunlp | grep -w :80
12、本地瀏覽器訪問測試:
192.168.1.143
192.168.1.143/index.jsp,訪問的是預設虛擬主機
13、修改192.168.1.144節點Tomcat預設虛擬主機:
# catalina.sh stop
# vim server.xml
<Engine name="Catalina" defaultHost="localhost">修改為
<Engine name="Catalina" defaultHost="TomcatA.qiuyue.com">
# catalina.sh configtest # catalina.sh start # ss -tunlp | grep -w :8080
14、修改192.168.1.145節點Tomcat預設虛擬主機:
# catalina.sh stop
# vim server.xml
<Engine name="Catalina" defaultHost="localhost">修改為
<Engine name="Catalina" defaultHost="TomcatB.qiuyue.com">
# catalina.sh configtest # catalina.sh start # ss -tunlp | grep -w :8080
15、本地瀏覽器中重新訪問192.168.1.143/index.jsp
輪詢顯示,Session ID一直在變:
16、實現session會話保持:# vim nginx.conf
方法一:根據客戶端IP
upstream tcsrvs {
ip_hash;
server TomcatA.qiuyue.com:8080;
server TomcatB.qiuyue.com:8080;
}
# nginx -t # nginx -s reload # ss -tunlp | grep -w :80
本地瀏覽器中訪問192.168.1.143/index.jsp,無論如何重新整理,頁面都不會改變:
Google Chrome瀏覽器F12:
方法二:根據分發和識別cookie,使同一個客戶端的請求始終落在同一臺後端伺服器上,預設標識名為route
工作流程:
1、客戶端首次發起訪問請求,Nginx接收
2、Nginx發現請求頭沒有cookie,以輪詢方式將請求分發給後端伺服器
3、後端伺服器處理完請求,將響應資料返回給Nginx
4、Nginx生成帶route的cookie,返回給客戶端,route的值與後端伺服器對應,每臺後端真實伺服器都會有一個唯一的route值,可能是明文,也可能是md5、sha1等hash值
5、客戶端接收請求,並儲存帶有route的cookie
6、當客戶端下一次傳送請求時,會帶上route,Nginx根據接收到的cookie中的route值,轉發給對應的後端伺服器
備註:當瀏覽器關閉,Nginx會給客戶端重新分配一臺後端伺服器
CentOS 7.5中yum方式安裝的Nginx版本為1.12.2,預設沒有啟用sticky功能
下載同版本的nginx-1.12.2.tar.gz進行編譯安裝,並新增sticky模組
# cp /usr/sbin/nginx /usr/sbin/nginx.20181203
# yum -y install gcc gcc-c++ openssl openssl-devel zlib zlib-devel pcre pcre-devel libxslt-devel libxml2-devel gd-devel perl-devel perl-ExtUtils-Embed GeoIP GeoIP-devel GeoIP-data wget
# tar -xf nginx-1.12.2.tar.gz -C /usr/src
# cd /usr/src/nginx-1.12.2
# ./configure --help | grep sticky //預設不支援sticky模組,是第三方模組
# wget https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/get/master.tar.gz
# tar -xf master.tar.gz
# mv nginx-goodies-nginx-sticky-module-ng-08a395c66e42 nginx-sticky-module
# nginx -V //複製yum方式安裝時預設的編譯選項
# ./configure --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/run/nginx.pid --lock-path=/run/lock/subsys/nginx --user=nginx --group=nginx --with-file-aio --with-http_auth_request_module --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_geoip_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --add-module=/usr/src/nginx-1.12.2/nginx-sticky-module
# make //不能執行make install
# /usr/src/nginx-1.12.2/objs/nginx -t
# /usr/src/nginx-1.12.2/objs/nginx -V
# cp -rf /usr/src/nginx-1.12.2/objs/nginx /usr/sbin/nginx
# nginx -s reload
# nginx -V
# ps -ef | grep nginx | grep -v grep
upstream tcsrvs {
# ip_hash;
sticky;
server TomcatA.qiuyue.com:8080;
server TomcatB.qiuyue.com:8080;
}
# nginx -t # nginx -s reload # ss -tunlp | grep -w :80
本地瀏覽器中訪問192.168.1.143/index.jsp,無論如何重新整理,頁面都不會改變:
備註:cookie負載均衡相比ip hash一個明顯的優點是對於內網nat使用者的負載均衡,ip hash無法做到