Nginx/Httpd負載均衡tomcat配置

来源:https://www.cnblogs.com/qiuhom-1874/archive/2020/07/20/13337003.html
-Advertisement-
Play Games

nginx的調度演算法中hash $remote_addr 和ip_hash是把IP地址的前24位做hash,所以如果你的IP前三段相同時,nginx它會認為是和nginxserver是同一區域網,所以它會把請求調度到同一區域網之前來請求過的後端server上進行響應;當然除了我們可以對源地址做ha... ...


  在前一篇博客中我們聊了下用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伺服器來配置就好;

  1、環境準備

  運行docker 啟動兩個tomcat容器當作後端tomcat server 並且把兩台tomcat容器的網頁目錄分別用存儲捲的方式映射到/tomcat/doc/tomcat1和tomcat1目錄

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

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

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

  現在分別放tomcat1和tomcat2看看對應主頁是否能夠訪問到

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

  2、配置nginx對tomcat做負載均衡

  提示:以上配置就是把兩台tomcat容器歸併為tcsevs組,然後反代/的訪問到這個組上即可。這樣配置預設是輪詢的;

  驗證:訪問宿主機上的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配置會話保持可以參考https://www.cnblogs.com/qiuhom-1874/p/12776261.html

  測試:檢查httpd的配置文件語法,如果沒有問題就重啟httpd,然後訪問httpd看看會有什麼變化

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

  提示:可以看到訪問httpd伺服器,在響應首部會多一個set-cookie首部,並且該首部的的值就是我們之前在配置文件中配置的KEY和value;set-cookie首部主要是在瀏覽器下次請求時,它會把set-cookie首部的值用cookie首部攜帶去訪問伺服器,這樣一來,伺服器就可根據客戶端請求報文的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的權重

  提示:正因為這個頁面可以動態的更改後端伺服器的屬性,所以通常需要做訪問限制;


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 第十三章 高級引用和指針 13.1按引用傳遞以提高效率 ​ 每次將值按對象傳入函數是,都將創建該對象的一個備份。每次按值從函數返回一個對象時,也將創建其備份。 ​ 對於用戶創建的大型對象,備份的代價很高。這將增加程式占用的記憶體量,而程式的運行速度將更慢。 ​ 在棧中,用戶創建的對象的大小為其成員變數 ...
  • 在某乎上看到一個問題,《30歲學軟體測試來得及嗎?》 問題:之前一直在工廠上班,看不到希望。已經30歲了,想轉學軟體測試來得及嗎? 同樣類型的問題,還有“我是大專學歷,學軟體測試能找到工作不?”“我是女生,軟體測試學起來難麽?”每天都會遇到很多同學有這些困惑,看看測試同仁對這件事是怎麼看的? 其中有 ...
  • 學習使用的環境:Win10,Python3.6,PyCharm Community Edition ,Django 2.2.12。 創建步驟: 1)安裝創建Django項目: 打開windows命令提示符: 安裝Django庫:pip install django==2.2.12 -i https: ...
  • 上次介紹了Azure Application Insights,實現了.net core程式的監控功能。這次讓我們來看看Azure DevOps Pipeline功能。Azure DevOps Pipeline 是Azure DevOps裡面的一個組件,對於12個月試用賬號同樣永久免費。 持續集成C ...
  • 在後臺管理系統中導出Excel功能是必不可少的,該模板可以幫助我們簡單優雅的實現導出功能,支持導出大數據。封裝如下: public class NPOIExcelExporterBase { protected ICellStyle HeadStyle { get; set; } protected ...
  • 這是一個使用WinForm開發的程式,用於在電腦上播放特定的樂音,包括中央C和國際標準音。 界面如下: .NET其實非常強大。使用.NET WinForm開發還是相當高效的,值得學習。 下載:https://hovertree.com/h/bjag/mcmub5gm.htm ...
  • 可以直接用CE進行雷總數修改,下麵是通過C#直接修改雷總數記憶體地址 /// PROCESS_ALL_ACCESS -> (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF) public const int PROCESS_ALL_ACCESS = (ST ...
  • 在本文中,我將展示如何使用DfaGraphWriter服務在ASP.NET Core 3.0應用程式中可視化你的終結點路由。上面文章我向您演示瞭如何生成一個有向圖(如我上篇文章中所示),可以使用GraphVizOnline將其可視化。最後,我描述了應用程式生命周期中可以檢索圖形數據的點。 作者:依樂 ...
一周排行
    -Advertisement-
    Play Games
  • GoF之工廠模式 @目錄GoF之工廠模式每博一文案1. 簡單說明“23種設計模式”1.2 介紹工廠模式的三種形態1.3 簡單工廠模式(靜態工廠模式)1.3.1 簡單工廠模式的優缺點:1.4 工廠方法模式1.4.1 工廠方法模式的優缺點:1.5 抽象工廠模式1.6 抽象工廠模式的優缺點:2. 總結:3 ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 本章將和大家分享ES的數據同步方案和ES集群相關知識。廢話不多說,下麵我們直接進入主題。 一、ES數據同步 1、數據同步問題 Elasticsearch中的酒店數據來自於mysql資料庫,因此mysql數據發生改變時,Elasticsearch也必須跟著改變,這個就是Elasticsearch與my ...
  • 引言 在我們之前的文章中介紹過使用Bogus生成模擬測試數據,今天來講解一下功能更加強大自動生成測試數據的工具的庫"AutoFixture"。 什麼是AutoFixture? AutoFixture 是一個針對 .NET 的開源庫,旨在最大程度地減少單元測試中的“安排(Arrange)”階段,以提高 ...
  • 經過前面幾個部分學習,相信學過的同學已經能夠掌握 .NET Emit 這種中間語言,並能使得它來編寫一些應用,以提高程式的性能。隨著 IL 指令篇的結束,本系列也已經接近尾聲,在這接近結束的最後,會提供幾個可供直接使用的示例,以供大伙分析或使用在項目中。 ...
  • 當從不同來源導入Excel數據時,可能存在重覆的記錄。為了確保數據的準確性,通常需要刪除這些重覆的行。手動查找並刪除可能會非常耗費時間,而通過編程腳本則可以實現在短時間內處理大量數據。本文將提供一個使用C# 快速查找並刪除Excel重覆項的免費解決方案。 以下是實現步驟: 1. 首先安裝免費.NET ...
  • C++ 異常處理 C++ 異常處理機制允許程式在運行時處理錯誤或意外情況。它提供了捕獲和處理錯誤的一種結構化方式,使程式更加健壯和可靠。 異常處理的基本概念: 異常: 程式在運行時發生的錯誤或意外情況。 拋出異常: 使用 throw 關鍵字將異常傳遞給調用堆棧。 捕獲異常: 使用 try-catch ...
  • 優秀且經驗豐富的Java開發人員的特征之一是對API的廣泛瞭解,包括JDK和第三方庫。 我花了很多時間來學習API,尤其是在閱讀了Effective Java 3rd Edition之後 ,Joshua Bloch建議在Java 3rd Edition中使用現有的API進行開發,而不是為常見的東西編 ...
  • 框架 · 使用laravel框架,原因:tp的框架路由和orm沒有laravel好用 · 使用強制路由,方便介面多時,分多版本,分文件夾等操作 介面 · 介面開發註意欄位類型,欄位是int,查詢成功失敗都要返回int(對接java等強類型語言方便) · 查詢介面用GET、其他用POST 代碼 · 所 ...
  • 正文 下午找企業的人去鎮上做貸後。 車上聽同事跟那個司機對罵,火星子都快出來了。司機跟那同事更熟一些,連我在內一共就三個人,同事那一手指桑罵槐給我都聽愣了。司機也是老社會人了,馬上聽出來了,為那個無辜的企業經辦人辯護,實際上是為自己辯護。 “這個事情你不能怪企業。”“但他們總不能讓銀行的人全權負責, ...