當前位置:編程學習大全網 - 源碼下載 - apache+Tomcat負載平衡設置詳解

apache+Tomcat負載平衡設置詳解

  壹 簡介

 每個Tomcat worker是壹個服務於web server 等待執行servlet的Tomcat實例 例如我們經常使用像Apache之類的web server轉發sevlet請求給位於其後面的壹個Tomcat進程(也就是前面所說的worker) 本文詳細介紹了如何配置各種類型worker和 loadbalance 並說明了各種類型worker的特性和loadbalance配置的原理

  二 為什麽使用Tomcat workers

 上文描述了壹個非常簡單的結構 事實上能夠配置多個Tomcat workers來處理web server轉發的servlet請求 而這樣配置的理由不外乎以下幾種假想環境

 * 我們在開發環境中發布不同的Tomcat workers為各自不同的應用服務 當然在開發環境中的開發者***享同壹個web server 但是每個Tomcat worke服務於擁有它的開發者

 * 我們在不同的Tomcat進程上定義各自的虛擬主機 這樣不同的公司可以使用各自的web site 從而使他們的web site得到了合理的分割

 * 我們提供負載平衡的web site 也就意味著同時使用多個Tomcat workers 而每個Tomcat worker具有獨立的主機並且在workers之間要分配通過web server轉發來的請求

 當然 這些假想情況也許並不能涵蓋使用多個workers的所有狀況

  三 workers properties配置說明

 定義Tomcat workers的方法是在apache的conf目錄下編寫壹個名為 workers properties 的屬性文件 本文將詳細解釋如何進行配置的

  定義Workers列表

 定義workers的方法就是在apache的conf目錄下編寫壹個workers properties文件 使其作為apache的插件來發揮作用

 定義workers列表的格式

 worker list =<使用 分割的worker 名字列表>

 例如

  worker list= worker worker

 當apache啟動時 workers properties作為插件將初始化出現在worker list列表中的workers

  定義Workers的類型

 每個被命名的worker都應有壹些關於其自身的附加信息 這些信息包括了worker的類型和其它相關信息 這裏討論的是JK 中定義的workers類型

 定義worker類型的格式

 worker worker名字 type =<worker類型>

 worker名字的命名最好遵循java的命名規範

 worker類型取值於下面的表格

 定義壹個名為 local 的worker 其使用ajpv 協議與Tomcat 進程通訊

  worker local type=ajp

 定義壹個名為 remote 的worker 其使用ajpv 協議與Tomcat 進程通訊

  worker remote type=ajp

 定義壹個名為 fast 的worker 其使用JNI的方式與Tomcat 進程通訊

  worker fast type=jni

 定義壹個名為 loadbalancer 的worker 其作為對多個Tomcat 進程的負載平衡使用

  worker loadbalancer type=lb

 各個類型具有不同的行為 我們在下文中會詳細解釋

  設置Worker屬性

 在定義worker之後 還需要提供各個worker的屬性 這些屬性的定義使用下面的方式

 worker <worker名字> <屬性>=<屬性值>

  ajp 類型的Worker屬性

 ajp 類型的worker工作時使用基於TCP/IP socket的ajpv 協議轉發請求給 進程外 Tomcat worker

 ajp worker屬性如下

 host

 偵聽ajp 請求的Tomcat worker主機

 port

 Tomcat worker主機的偵聽端口

 lbfactor

 當此Tomcat worker被用於壹個負載平衡worker使用時 此屬性將被使用 它定義了此worker的負載平衡權值

 例如 下面的 worker 定義了壹個位於主機上的Tomcat 它使用 端口偵聽apache發來的請求 並具有 的負載權值

  worker worker host=worker worker port= worker worker lbfactor=

 註意 在ajpv 協議中 針對每個請求都要壹個連接建立 使用 關閉 其默認偵聽端口為

  ajp 類型的Worker屬性

 ajp 類型的worker工作時使用基於TCP/IP socket的ajpv 協議轉發請求給 進程外 Tomcat worker

 ajpv 協議與ajpv 協議的主要不同

 * ajpv 具有更豐富的二進制協議 它使用將頻繁使用的字符串編碼為小整數的方式對請求數據進行壓縮

 * ajpv 重用打開的socket並保留這些打開的socket以處理將來的請求 這在apache與Tomcat之間具有防火墻的網絡環境下是必要的

 * ajpv 具有對SSL信息的處理能力 以致容器能夠實現SSL的相關方法(如isSecure())

 註意 ajp 當前只能用於支持 進程外 協議的Tomcat x x and

 下表描述了ajp worker接受的屬性

 host

 偵聽ajp 請求的Tomcat worker主機

 port

 Tomcat worker主機的偵聽端口

 lbfactor

 當此Tomcat worker被用於壹個負載平衡worker使用時 此屬性將被使用 它定義了此worker的負載平衡權值

 cachesize

 當在多線程的web server(例如apache IIS Netscape)中使用JK時 此屬性是有效的 如果將cachesize的值設置為較高的值 這些支持多線程的web server將獲得很好的處理能力 如果此屬性不被設置 則連接cache特性將失效

 cache_timeout

 本屬性用於聲明JK在cache中保留壹個打開的socket的時間 它對減少web serer的線程數有所幫助

 使用cache_timeout的原因

 周所周知 壹個身背重負的web server(例如apache)建立childs/threads來處理負載 而當負載減少時它將銷毀無用的childs/threads 每個 child在轉發請求給Tomcat時要打開壹個ajp 連接 而在Tomcat那壹端也將建立壹個ajp 線程與之通訊 但是問題出現在壹個 ajp 連接建立完成後 child沒有及時的釋放那個ajp 連接 由於web server 將保持它的childs/threads運行已處理高負載 即使childs/threads處理快速的靜態內容 在Tomcat端也將積累很多的無用ajp 線程

 socket_keepalive

 當防火墻位於web server與Tomcat之間時 防火墻將嘗試斷開未激活的網絡連接 此屬性將告訴操作系統在未激活的連接中發送KEEP_ALIVE信息(發送間隔時間依賴於操作系統的設置 壹般為 秒) 這樣將防止防火墻切斷未激活的網絡連接

 但此設置並不是萬能鑰匙 它對於某些防火墻也無能為力

 socket_timeout

 此屬性說明連接在未激活的狀況下持續多久 web server將主動切斷之 這是壹個使Tomcat端的陳舊線程不致過多的好方法 但是也帶來了在下壹次請求到來時需要重新打開socket的開銷 此屬性與cache_timeout有類似的功效 但是它工作在non cache模式

 connect_timeout

 web server在連接建立後將壹個PING請求發送到ajp 協議的連接上 此屬性說明了web server等待PONG回應的時間(以ms為單位) 此屬性在jk 版本被增加進來 以求避免Tomcat的死機 Tomcat + + and +實現了對使用ajp 的 ping/pong的支持 此屬性默認為失效的

 prepost_timeout

 web server在轉發壹個請求後將壹個PING請求發送到ajp 協議的連接上 此屬性說明了web server等待PONG回應的時間(以ms為單位) 此屬性在jk 版本被增加進來 以求避免Tomcat的死機 Tomcat + + and +實現了對使用ajp 的 ping/pong的支持 此屬性默認為失效的

 reply_timeout

 此屬性告訴web server在接到遠端的Tomcat已死並實時的切換到集群中的另外壹個Tomcat的回應之前等待壹段時間 默認情況下web server將永遠等待 屬性值為web server要等待回應的時間(以ms為單位) 所以如果具有運行時間較長的servlet時設置其值要小心 此屬性在jk 版本被增加進來 以求避免Tomcat的死機和在支持ajp 的servlet引擎上發生的問題 此屬性默認為失效的

 recovery_options

 此屬性說明了web server在檢測到Tomcat失敗後如何進行恢復工作 默認情況下 web server將轉發請求給處於負載平衡模式中的另壹個Tomcat 屬性值為 說明全部恢復 屬性值為 說明如果在Tomcat接到請求後出現失敗狀況 則不進行恢復 屬性值為 說明如果在Tomcat發送頭給客戶端後出現失敗狀況 則不進行恢復 屬性值為 說明如果在Tomcat接到請求後出現失敗狀況或者在Tomcat發送頭給客戶端後出現失敗狀況 則不進行恢復 此屬性在jk 版本被增加進來 以求避免Tomcat的死機和在支持ajp 的servlet引擎上發生的問題 此屬性默認為全部恢復

 例如 壹個名為 worker 的worker的配置

  worker worker host=worker worker port= worker worker lbfactor= worker worker cachesize= worker worker cache_timeout= worker worker socket_keepalive= worker worker want ajp connection to be dropped after mn (timeout)worker worker socket_timeout=

 說明 上例中的worker要求操作系統在連接上發送KEEP ALIVE信號

 註意 在ajpv 協議中默認端口為

  設置lb Worker屬性

 負載平衡類型的worker並不與Tomcat worker通訊 它負責管理這些Tomcat worker

 其管理範圍如下

 * 初始化在web server的worker列表中定義的worker

 * 使用worker的負載平衡權值 執行基於權值的負載平衡 將數量多的請求發送到負載平衡權值高(在web server看來就是更加健壯的)的worker

 * 維護在同壹個Tomcat worker上的同壹個session的請求 使其發送到同壹個Tomcat worker上 以達到Tomcat worker上的session壹致性 持續性

 * 標識已經失敗的Tomcat workers 懸空發向它們的請求 在被lb worker管理的其它workers上尋找可以失敗恢復的worker

 被同壹個lb worker管理多個worker之間的負載平衡的(基於它們的lbfactor和當前用戶session) 也可以盡量避免由於單壹的Tomcat進程死掉而造成這個網站被 殺 的不良反應

 下表說明了lb worker接受的屬性

 * balanced_workers 壹個由 分割的worker列表 用來聲明lb worker需要被管理的workers 這些workers不應出現在worker list屬性中

 * sticky_session 表述是否將對SESSION ID的請求路由回到相同的Tomcat worker 如果屬性值不為 它將被設置為JK_TRUE session將是粘性的 即SESSION ID的請求路由回到相同的Tomcat worker 當Tomcat正使用能夠跨越多個Tomcat實例持久化session數據的Session Manager時 它將被設置為JK_FALSE 屬性默認值為JK_TRUE

 例如 worker balance 管理著兩個workers worker worker

worker balance balanced_workers=worker worker

  高級lb Worker屬性

 JK x版本通過增加兩個新的屬性 local_worker_only 和 local_worker 為lb worker增添了新的負載平衡和容錯支持

 下面讓我們舉壹個實際的環境作為example

 壹個集群具有兩個節點(worker +worker ) 壹個web server與tomcat workers壹前壹後 壹個負載平衡器(lb Worker)位於節點的前面 web server的後面

 配置如下

  worker list=router# Define a local_worker worker using ajp worker worker port= worker worker host=worker worker type=ajp worker worker lbfactor= worker worker local_worker= # Define another local_worker worker using ajp worker worker port= worker worker host=worker worker type=ajp worker worker lbfactor= worker worker local_worker= # Define the LB workerworker router type=lbworker router balanced_workers=worker worker worker router local_worker_only=

 在worker 和worker 上的local_worker標誌告訴lb_worker哪個連接屬於本地worker

 如果 local_worker值為非 則它將被設置為JK_TRUE 用來標記 local worker 而JK_FALSE的情況則相反 如果至少壹個worker被標記為local worker 則lb_worker將工作於local worker模式 這種模式下 所有的local workers將被移到在lb_worker中的內部worker列表的頭部

 這意味著壹個帶有session id的請求到達lb_worker時 相應的worker(根據權值排序 權值最大的那個worker)將被確定作為此請求的接受/處理者 如果這個 worker死掉/當機 請求將被發送到處於非錯誤狀態的第壹個local worker 如果壹個沒有session id的請求到達lb_worker時 此請求將被路由到第壹個local worker 如果所有的local worker均處於錯誤狀態 則這時 local_worker_only 標誌顯得尤其重要 如果local_worker_only的屬性值為非 則它被設置為 JK_TRUE 否則被設置為 JK_FALSE 當它被設置為 JK_TRUE時 這個沒有session id的請求將得到壹個錯誤作為回應 否則lb_worker將嘗試將請求路由到其它的被管理的worker上 如果其中的壹個worker處於錯誤狀態 並且恢復會話的工作並沒有任何改變 local worker將查找這個沒有session id的請求(因為在local worker中保存有這個請求的session) 而其它的worker只能查找帶有session id的請求

 註意 local_worker默認值是 local_worker_only默認值也是

  為什麽需要這麽復雜的過程嗎?

 因為我們對於壹個關閉的節點需要壹個具有靈性的維護

 在節點前面的平衡器周期性的對每個節點的特定端口進行查詢 如果我們從集群中移走壹個節點 我們就會隱性的關閉掉這個特定的端口 由於負載平衡器不能連接它 這個節點將被標記為down 但是我們沒有移動在那個關閉的節點上的session到其它的節點上 在這個環境下 如果平衡器發送壹個沒有 session id的請求到壹個端口被關掉的節點 那麽壹個錯誤將發生 如果平衡器測試到壹個節點被標記為down的狀態 而沒有其它的節點允許發送沒有session id的請求 這樣這些陳舊的session請求就只有路由到那個被關閉的節點才能被接受 在壹段時間後 這些陳舊的session將超時 由於所有的陳舊的session過期 那個不可達(被關閉)的節點將失去這個請求 同時也會導致我們的servlet系統發送壹個沒有session id的重定向回應給瀏覽器

 但是可能被關閉的節點將會up 重新加入到集群中來 在它上面仍將保留著陳舊的session 所以在最後壹個 session超時後 更新節點能夠為陳舊的session的恢復帶來希望 而不是殺掉sessions或者把它們移到其它節點上 而且有時如果那些陳舊的session中有許多big的對象 那麽移動它們也將花費許多時間

  jni類型的Worker屬性

 jni worker會在web server進程中打開壹個JVM 並在其中執行Tomcat 這叫做 進程內 worker 來往於JVM的消息將通過調用JNI方法被傳遞 這使jni worker比那些需要使用ajp消息通訊的 進程外 worker執行的更快

 註意 由於JVM是多線程的 jni worker應該只被用於在支持對線程的web server(AOLServer IIS Netscape and Apache )上 同時還應該確認在web server上使用的線程方案是否與被使用的JK web server插件相匹配

 由於jni worker 打開了壹個JVM 它將接受壹些屬性(例如classpath等)並將其傳遞給JVM

 worker worker名 class_path 進程內 的JVM要使用的classpath 它將包括所有的Tomcat的jar文件和class 配置文件等

 為了獲得JSP編譯器的支持 我們需要將Javac添加到classpath中 當然對於Java 需要添加tools jar到classpath 而對於JDK xx則要添加classes zip到classpath

 worker worker名 class_path 用於以多行的形式聲明多個classpath JK環境將用 或者 把這些classpath 連接起來

 例如 給名為 wrkjni 的worker設置classpath

  worker wrkjni class_path=/var/tomcat /lib/tomcat jarworker wrkjni class_path=/opt/IBMJava /lib/tools jar

 worker worker名 bridge 用於標識將通過JNI方式被使用的Tomcat的類型 此屬性目前有兩個屬性值 tomcat or tomcat Tomcat x雖然已經過時 但是被提供用於發布在壹些類似iSeries系統上 此屬性的默認值為tomcat

 例如 給 wrkjni 設置bridge類型為tomcat

  worker wrkjni bridge=tomcat

 worker worker名 cmd_line 此屬性提供了在Tomcat啟動代碼執行的命令行 使用時將命令行的命令 參數分解為多個cmd_line屬性 JK環境通過在各個cmd_line屬性值之間添加空格將這些cmd_line連接在壹起

 例如 設置 wrkjni 的cmd_line屬性

  worker wrkjni cmd_line= configworker wrkjni cmd_line=/etc/tomcat /conf/alt server xmlworker wrkjni cmd_line= homeworker wrkjni cmd_line=/var/tomcat

 上面例子中的第壹行聲明了 config參數名 而第二行聲明了與之對應的參數值 第三行與第四行同理

 worker worker名 jvm_lib 用於聲明JVM的實現庫的完整路徑 Jni worker使用這個路徑動態裝載JVM

 例如 設置 wrkjni 的JVM shared lib (IBM SDK on Linux)

  worker wrkjni jvm_lib=/opt/IBMJava /jre/bin/classic/libjvm so

 例如 設置 wrkjni 的JVM shared lib (Sun SDK on Windows)

  worker wrkjni jvm_lib=c:\JDK\ \jre\bin\classic

 worker worker名 stdout 設置JVM寫它的System out的完整路徑位置

 例如 將 wrkjni 的JVM系統輸出路徑設置為/var/log/

  worker wrkjni stdout=/var/log/

 worker worker名 stderr 設置JVM寫它的System err的完整路徑位置

 例如 將 wrkjni 的JVM系統錯誤輸出路徑設置為/var/log/

  worker wrkjni stderr=/var/log/

 worker worker名 ms 設置JVM的初始堆大小

 例如 設置 wrkjni 的JVM的初始堆為 M

  worker wrkjni ms=

 worker worker名 mx 設置JVM的最大的堆大小

 例如 設置 wrkjni 的JVM堆最大為 M

  worker wrkjni mx=

 worker worker名 sysprops 設置JVM的系統屬性

 例如 設置 wrkjni 的JVM使用法語

  worker wrkjni sysprops= Duser region=FR

 worker worker名 ld_path 設置附加的動態鏈接庫路徑(類似於LD_LIBRARY_PATH)

 例如 添加壹些動態鏈接庫路徑到 wrkjni 的java環境中

  worker wrkjni ld_path=/opt/IBMJava /jre/bin/worker wrkjni ld_path=/opt/IBMJava /jre/bin/classic

 註意 在Linux下 上面的ld_path並不能更新LD_LIBRARY_PATH 所以需要在執行web server之前手動更新LD_LIBRARY_PATH

  屬性文件宏

 我們可以在屬性文件中定義 宏 這些宏讓我們定義屬性 並在以後使用它們來構建其它的屬性文件 當我們修改Java Home Tomcat Home 系統路徑分隔符時這是很有用的

 例如 定義了屬性workers tomcat_home workers java_home

  workers tomcat_home=d:\tomcaorkers java_home=d:\sdk\jdk

 在定義worker inprocess class_path時就可以使用前面定義的workers tomcat_home

  worker inprocess class_path=$(workers tomcat_home)$(ps)classes

  壹個簡單而完整的worker properties

 文件中定義了比較完整的結構 可以做為參考模版

 * 壹個位於localhost的使用 端口的ajp worker

 * 壹個位於localhost的使用 端口的ajp worker

 * 壹個jni worker

 *? 壹個lb worker 負責ajp worker ajp workers的負載平衡

 文件內容如下

lishixinzhi/Article/program/Java/ky/201311/28541

  • 上一篇:2021有哪些感動中國的事跡和獎項?
  • 下一篇:kafka怎麽做到基於磁盤卻比內存還快?
  • copyright 2024編程學習大全網