Nginx/Httpd負載均衡tomcat配置

  在前一篇博客中咱們聊了下用Nginx和httpd對後端tomcat服務作反代相關配置,回顧請參考https://www.cnblogs.com/qiuhom-1874/p/13334180.html;今天咱們來聊一聊用Nginx和httpd對tomcat集羣作負載均衡的配置以及須要注意的點;在前邊的演示和配置都是以單臺tomcat來配置使用;可是在生產中單臺tomcat實在支撐不了大規模的訪問,這個時候咱們就須要考慮把多臺tomcat作成集羣對外提供服務;多臺tomcat作成集羣對外提供服務就必然要有一個調度器來對客戶端的請求作調度,經常使用的調度器有nginx httpd haproxy lvs等等;用這些調度器來對tomcat作負載均衡的配置和對其餘web服務器作負載均衡的配置沒有本質的不一樣;咱們均可以把tomcat看成web服務器來配置就好;html

  一、環境準備node

  運行docker 啓動兩個tomcat容器看成後端tomcat server 而且把兩臺tomcat容器的網頁目錄分別用存儲卷的方式映射到/tomcat/doc/tomcat1和tomcat1目錄nginx

  提示:以上就運行了兩個tomcat容器,分別是tct1和tc2,而且咱們把/usr/local/tomcat/webapps/myapp映射到宿主機的/tomcat/doc/tomcat1和tomcat2,這樣作咱們就能夠直接把網頁腳本放到宿主機上的這個目錄從而實現把網頁部署到tomcat的默認虛擬主機上;web

  編輯兩個容器的主頁文件內容算法

  提示:以上分別給tomcat1和tomcat2提供了一個測試主頁;docker

  如今分別放tomcat1和tomcat2看看對應主頁是否可以訪問到後端

  提示:能夠看到tomcat1和tomcat2都可以訪問到,到此後端tomcat的環境就準備好了;接下來咱們來配置nginx來對他們作負載均衡;瀏覽器

  二、配置nginx對tomcat作負載均衡tomcat

  提示:以上配置就是把兩臺tomcat容器歸併爲tcsevs組,而後反代/的訪問到這個組上便可。這樣配置默認是輪詢的;bash

  驗證:訪問宿主機上的80端口看看是否分別可以訪問到後端兩臺tomcat容器提供的主頁?

  檢查nginx配置文件語法格式並啓動nginx

  訪問宿主機的80端口,看看是否可以訪問到後端tomcat提供的頁面?

  提示:能夠看到訪問宿主機的80端口是可以正常訪問到後端tomcat服務器上的,而且也看出了默認輪詢調度的效果;可是這裏存在一個問題,同一用戶訪問宿主機的80端口,給咱們響應的結果session id都不一樣,這意味着nginx並無追蹤到用戶的狀態信息,緣由是由於http請求原本就是無狀態的,爲了讓服務記錄用戶的狀態信息,在nginx上咱們能夠基於源ip作調度,什麼意思呢,就是同一源ip地址,nginx都把該請求調度到同一臺後端server上,使得同一用戶訪問的狀態信息始終調度到同一後端server上;

  nginx基於源ip作會話保持

  提示:ip_hash和hash $remote_addr都表示對源ip進行哈希計算,而後把取獲得結果和總權重作模運算,結果落到那個節點,就調度到那個節點;什麼意思呢,如上所示,後端server有兩個,且權重都爲1,那麼他們的權重和就是2,ip_hash和hash $remote_addr就是把客戶端的ip地址的前三段進行hash計算,而後把獲得的值再和權重和作取模運算,很顯然取模後端結果要麼是0要麼是1,若是取模後的結果是1,那麼nginx基於它內部的對應關係,把該請求就調度到tomcatB或者tomcatA;

  測試:重啓niginx ,訪問宿主機的80端口看看是否都把請求調度到同一後端server上?

  提示:能夠看到如今訪問宿主機的80端口就沒有在輪詢了,而是始終調度到tomcatA這臺server上進行響應;可是咱們訪問127.0.0.1的80端口它又調度到tomcatB上去了,這是由於nginx的調度算法中hash $remote_addr 和ip_hash是把IP地址的前24位作hash,因此若是你的IP前三段相同時,nginx它會認爲是和nginxserver是同一局域網,因此它會把請求調度到同一局域網以前來請求過的後端server上進行響應;固然除了咱們能夠對源地址作hash,咱們也能夠對其餘首部作hash計算,原理都是相似的,都是把對應首部的值作hash計算,而後同權重和作取模運算;而後根據nginx內部的對應關係,把取模後端結果相同的請求調度到同一後端server,就是基於這樣的原理,把客戶端和後端server綁定到一塊兒實現了會話綁定;

  httpd對tomcat作負載均衡

  httpd作負載均衡器,須要確認httpd是否開啓了proxy_http_module、proxy_module  、proxy_balancer_module若是須要用到ajp還須要肯定proxy_ajp_module模塊是否啓用,以及調度算法的三個模塊 lbmethod_bybusyness_module 、lbmethod_byrequests_module、lbmethod_bytraffic_module;以上模塊對於調度算法來講用到那個啓用那個也行,對於http或者ajp也是同樣的;用獲得就啓用,用不上不啓用也不要緊;

  提示:能夠看到咱們須要用的模塊都是啓用了的;

  配置httpd對後端tomcat 作負載均衡

  提示:從上面的配置,其實感受和nginx的配置邏輯很類似,首先把後端server歸併成一個組,而後反代時把請求代理到定義的組上便可;這裏說一下調度算法吧,proxyset lbmethod 用來指定調度算法的,默認不寫是使用byrequests,這個算法就是httpd裏的輪詢調度算法,固然在每一個balancermember 後面加上權重,就成了加權輪詢了;除此調度算法,咱們還可使用bytraffic,這個調度算法是根據和後端server的傳輸流量來調度,若是某個服務器傳輸流量很大,那麼他會把請求往傳輸流量相對小的服務器上調度;bybusyness這個調度算法是根據後端server的繁忙程度來調度;相似nginx裏的least_conn最少鏈接算法;對balancermember 咱們也能夠向nginx 那樣設置單獨屬性,只須要在後面寫上對應的屬性便可;經常使用的屬性有status 這個屬性表示表示對應balancermember是處於什麼狀態,其中對status有6種取值;D表示禁用對應server,不提供任何請求;S表示人工手動標識爲不可用;I表示強制上線模式(強制忽略錯誤模式);H表示熱備模式(至關於nginx裏的backup,只有組裏的其餘server都不可用時,它纔會被激活,用於say sorry);E表示強制處於錯誤模式(即使沒有錯誤也要讓他處於有錯誤);N表示排幹模式;除了status來指定balancermember的狀態,還可使用loadfactor來指定權重,相似於nginx裏的weight;

  停掉nginx,檢查httpd 的配置文件語法,若是沒有問題就啓動httpd

  訪問httpd提供的服務,看看是否訪問到後端tomcat的頁面

  提示:能夠看到和nginx的訪問同樣,均可以實現輪詢;

  httpd基於cookie對後端tomcat作會話粘性

  提示:以上配置表示給客戶端請求cookie首部添加一個標識,ROUTEID=%{BALANCER_WORKER_ROUTE}e表示,咱們指定的ROUTEID標識的值爲balancermember 後面的route屬性指定的值;env=BALANCER_ROUTE_CHANGED表示,若是咱們指定的route的值發生變化時,它須要從新調度;簡單講就是給cookie信息打標籤;proxyset stickysession=ROUTEID 表示給該組全部成員設置會話粘性KEY的名稱爲ROUTEID,這個值一般要和上面的set-cookie後面的KEY對應;若是把它寫到每一個balancermember後面表示單獨給某個server設置會話粘性KEY的名稱;若是寫在proxy配置段裏須要用proxyset指令來設置,表示給該組的全部member設置 stickysession;簡單講就是聲明以那個key來當作會話粘性的基準來作調度;這個邏輯和haproxy裏面的會話保持設定相似;有關haproxy配置會話保持能夠參考http://www.javashuo.com/article/p-xovornbp-t.html

  測試:檢查httpd的配置文件語法,若是沒有問題就重啓httpd,而後訪問httpd看看會有什麼變化

  用curl 來模擬第一次訪問httpd服務器,看看響應首部有什麼變化?

  提示:能夠看到訪問httpd服務器,在響應首部會多一個set-cookie首部,而且該首部的的值就是咱們以前在配置文件中配置的KEY和value;set-cookie首部主要是在瀏覽器下次請求時,它會把set-cookie首部的值用cookie首部攜帶去訪問服務器,這樣一來,服務器就可根據客戶端請求報文的cookie的值,來分析本次請求是那個客戶端發送過來,後續服務端該怎麼調度;

  用瀏覽器訪問,看看客戶端後續的請求,是否是把第一次訪問中的set-cookie的值拿上去請求服務端?

 

   提示:能夠看到瀏覽器第一次訪問,服務器會在響應首部中添加一個set-cookie的首部;這個首部的值就是ROUTEID是目前響應咱們的後端server上的route的值;

  提示:能夠看到客戶端在請求首部cookie中,把以前set-cookie中的值都攜帶過去了;此時httpd收到客戶端請求就能夠根據設置的stickysession 指定的KEY來判斷該把對應請求發送到那個後端server上進行響應了;這樣一來,只要客戶端的cookie不變,那麼它每次訪問服務端都會以cookie首部的值去告訴服務端該調度到那臺後端server上;

  用curl模仿客戶端請求攜帶cookie訪問服務端

[root@docker_node01 ~]# curl -I --cookie "ROUTEID=.TOMCAT1" http://192.168.0.22/myapp/ 
HTTP/1.1 200 
Date: Mon, 20 Jul 2020 14:26:02 GMT
Server: Apache/2.4.6 (CentOS)
Content-Type: text/html;charset=ISO-8859-1
Transfer-Encoding: chunked
Set-Cookie: JSESSIONID=F03BABD6CC4905066B3BF78947D024CC; Path=/myapp; HttpOnly
Via: 1.1 www.test1.com

[root@docker_node01 ~]# curl --cookie "ROUTEID=.TOMCAT1" http://192.168.0.22/myapp/     

<html>
    <head><title>TomcatA</title></head>
    <body>
        <h1><font color="blue">TomcatA</font></h1>
        <table align="centre" border="1">
            <tr>
            <td>Session ID</td>

            <td>FDD5095817FBEE6B58054666B64E46C2</td>
            </tr>
            <tr>
            <td>Created on</td>
            <td>1595255172651</td>
            </tr>
        </table>
    </body>
</html>
[root@docker_node01 ~]# curl --cookie "ROUTEID=.TOMCAT2" http://192.168.0.22/myapp/ 

<html>
    <head><title>TomcatB</title></head>
    <body>
        <h1><font color="green">TomcatB</font></h1>
        <table align="centre" border="1">
            <tr>
            <td>Session ID</td>

            <td>BC5EAC6B1B75E54F4C92CCB0B5018808</td>
            </tr>
            <tr>
            <td>Created on</td>
            <td>1595255213765</td>
            </tr>
        </table>
    </body>
</html>
[root@docker_node01 ~]#

  提示:能夠看到當咱們使用curl模仿客戶端訪問攜帶cookie時,在響應首部就不會在給咱們發set-cookie首部(這裏的set-cookie是指和咱們在服務器設定相關的首部),而且咱們攜帶不一樣ROUTEID的cookie,它會根據咱們攜帶的ROUTEID的值把咱們調度到不一樣的後端server上進行響應;對於httpd負載均衡代理後端tomcat用ajp的配置方式和http的配置方式同樣的,不一樣的只是把後端server的http協議修改爲ajp,後端tomcat的端口修改爲ajp協議監聽的端口便可,默認tomcatajp協議監聽在8009端口;

  配置httpd後端管理界面頁

  提示:以上配置表示啓動httpd管理頁面,並綁定到/manager-page這個uri上,對於/manager-page這個uri不作任何代理,而且該rui只能容許ip地址爲192.168.0.232的主機訪問,其餘主機都沒有權限,包括服務器自己;

  驗證:用非192.168.0.232的主機訪問192.168.0.22/manager-page看看是否可以訪問到?

[root@docker_node01 ~]# ip a l ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:22:36:7f brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.22/24 brd 192.168.0.255 scope global ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe22:367f/64 scope link 
       valid_lft forever preferred_lft forever
[root@docker_node01 ~]# httpd -t
Syntax OK
[root@docker_node01 ~]# systemctl restart httpd
[root@docker_node01 ~]# curl http://192.168.0.22/manager-page  
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /manager-page
on this server.</p>
</body></html>
[root@docker_node01 ~]#

  提示:能夠看到用192.168.0.22去訪問,提示403沒有權限;

  用192.168.0.232去訪問,看看是否可以訪問到管理頁面?

  提示:用192.168.0.232上的瀏覽器上能夠正常訪問到httpd的管理頁面的;

  動態修改tomcat1的權重

  提示:正由於這個頁面能夠動態的更改後端服務器的屬性,因此一般須要作訪問限制;

相關文章
相關標籤/搜索