Apache負載均衡

Apache負載均衡

2.1 Tomcat鏈接方式

        首先我們先介紹一下爲什麼要讓http server與Tomcat之間進行連接。事實上Tomcat本身已經提供了HTTP服務,該服務默認的端口是8080,裝好tomcat後通過8080端口可以直接使用Tomcat所運行的應用程序,你也可以將該端口改爲80。既然Tomcat本身已經可以提供這樣的服務,我們爲什麼還要引入Apache或者其他的一些專門的HTTP服務器呢?原因有下面幾個:

        1. 提升對靜態文件的處理性能。

        2. 利用Web服務器來做負載均衡以及容錯。

        3. 無縫的升級應用程序。

        這三點對一個web網站來說是非常之重要的,我們希望我們的網站不僅是速度快,而且要穩定,不能因爲某個Tomcat宕機或者是升級程序導致用戶訪問不了,而能完成這幾個功能的、最好的HTTP服務器也就只有apache的http server了,它跟tomcat的結合是最緊密和可靠的。

        默認情況下,Tomcat在server.xml中配置了兩種連接器:

        第一個連接器監聽8080端口,負責建立HTTP連接。在通過瀏覽器訪問Tomcat服務器的Web應用時,使用的就是這個連接器。

        第二個連接器監聽8009端口,負責和其他的HTTP服務器建立連接。在把Tomcat與其他HTTP服務器集成時,就需要用到這個連接器。

        兩種端口可以同時開,也可以開一個。例如我們使用apache通過ajp進行負載均衡配置時,可以關掉tomcat的http8080端口以防止可以被單獨訪問。

        Web客戶訪問Tomcat服務器上JSP組件的兩種方式如圖:

 

 

        使用http方式,配置文件

 
<Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">

        使用ajp方式,配置文件

<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">

 

2.2 mod_proxy

        mod_proxy_balancer是apache httpd自帶的負載平衡支持。其優點可以根據實際的運行時機器的環境來決定負載均衡的策略。實現Session在node上進行共享傳遞。

 

2.2.1 加載so庫

#mod_proxy_blancer
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so  
LoadModule proxy_ftp_module modules/mod_proxy_ftp.so 
LoadModule proxy_http_module modules/mod_proxy_http.so 
LoadModule proxy_connect_module modules/mod_proxy_connect.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so

 

2.2.2 http方式

<Proxy balancer://mycluster>
    BalancerMember http://127.0.0.1:8080 loadfactor=3
    BalancerMember http://127.0.0.1:7080 loadfactor=3
    ProxySet lbmethod=byrequests
</Proxy>
ProxyRequests Off
ProxyPass /test balancer://mycluster/ stickysession=JSESSIONID nofailover=Off
ProxyPassReverse /test balancer://mycluster/  

 

        實現負載均衡的原理爲:假設Apache接收到http://127.0.0.1 /test請求,由於該請求滿足ProxyPass條件(其URL前綴爲“/"),該請求會 被分發到後臺某一個BalancerMember。譬如該請求可能會轉發到http://127.0.0.1:8080/進行處理。當第二個滿足條件的URL請求過來時,該請求可能會被分發到另外一臺BalancerMember,譬如,可能會轉發到 http://127.0.0.1:7080/如此循環反覆,便實現了負載均衡的機制。

        loadfactor表示:後臺服務器負載到由Apache發送請求的權值,該值默認爲1,可以將該值設置爲1到100之間的任何值。以上面的配置爲例,進行4此請求時,則有3次連續的這樣請求被負載到BalancerMember爲http://127.0.0.1:8080/的服務器;有1次被負載到BalancerMember爲http://127.0.0.1:7080/的服務器。

        lbmethod表示:負載載均衡策略。 

        lbmethod=byrequests 按照請求次數均衡(默認) 

        lbmethod=bytraffic 按照流量均衡 

        lbmethod=bybusyness 按照繁忙程度均衡(總是分配給活躍請求數最少的服務器)

        ProxyPass表示:所有的test請求都會重定向到balancer://mycluster/處理。balancer是內置負載。

        ProxyPassReverse表示:反向代理,也就是將所有的請求反向代理到負載均衡後的應用url路徑中。

        stickysession表示:進行Session複製使用。

 

2.2.3 AJP方式

        tomcat提供了ajp協議和httpd通信。當不想tomcat的8080端口開放時,可以使用此方式,配置文件:

<Proxy balancer://mycluster>
    BalancerMember ajp://127.0.0.1:8009 loadfactor=2 route=tomcat1
    BalancerMember ajp://127.0.0.1:7009 loadfactor=2 route=tomcat2
    ProxySet lbmethod=byrequests
</Proxy>
ProxyRequests Off
ProxyPass /test balancer://mycluster/ stickysession=JSESSIONID nofailover=Off
ProxyPassReverse /test balancer://mycluster/  

 

2.2.4 熱備份

        熱備份的實現很簡單,只需添加 status=+H 屬性,就可以把某臺服務器指定爲備份服務器:

        此時請求總是流向 8080這個url ,一旦8080掛掉, Apache會檢測到錯誤並把請求分流給7080。Apache會每隔幾分鐘檢測一下8080的狀況,如果8080恢復,就繼續使用8080。

<Proxy balancer://mycluster>
    BalancerMember http://127.0.0.1:8080
    BalancerMember http://127.0.0.1:7080 status=+H 
    ProxySet lbmethod=byrequests
</Proxy>
ProxyRequests Off
ProxyPass /test balancer://mycluster/ stickysession=JSESSIONID nofailover=Off
ProxyPassReverse /test balancer://mycluster/  

 

2.2.5 虛擬主機

        配置文件

<VirtualHost *:80>  
    ServerAdmin [email protected]
    ServerName localhost  
    ServerAlias localhost  
    <Proxy balancer://mycluster>
        BalancerMember ajp://127.0.0.1:8009 loadfactor=1 route=tomcat1
        BalancerMember ajp://127.0.0.1:7009 loadfactor=1 route=tomcat2
        ProxySet lbmethod=bytraffic
    </Proxy>
    ProxyRequests Off
    ProxyPass /test balancer://mycluster/ stickysession=JSESSIONID nofailover=Off  
    ProxyPassReverse /test balancer://mycluster/  
    ErrorLog "logs/error.log"  
    CustomLog "logs/access.log" common  
</VirtualHost>

 

2.2.6 監控功能

        可添加以下配置,可以查看監控頁面。通過訪問:http://127.0.0.1/balancer-manager。

配置文件

<Location /balancer-manager>   
    SetHandler balancer-manager 
    Order Allow,Deny
    Allow from all 
</Location>

 

2.3 mod_jk

        Tomcat提供了專門的JK插件來負責Tomcat和HTTP服務器的通信。應該把JK插件安置在對方的HTTP服務器上。當HTTP服務器接收到客戶請求時,它會通過JK插件來過濾URL,JK插件根據預先配置好的URL映射信息,決定是否要把客戶請求轉發給Tomcat服務器處理。例如預先配置好所有"/*.jsp"形式的URL都由Tomcat服務器來處理

        Tomcat提供了不同的JK插件的實現模塊。常用的JK插件有:

        與Apache HTTPD服務器集成:mod_jk.so

        與Windows IIS服務器集成:isapi_redirect.dll

 

2.3.1 Workers.properties

        Workers實際上屬於Tomcat的鏈接器(Connector),代表了一個Tomcat實例,這個實例代表了由某種web服務器來執行 servelet程序。舉例來說,我們可以使用某個服務器,例如apache 來把servelet請求轉遞Tomcat進程(worker)來進行後臺處理。

        這樣我們就可以通過配置多個 Worker,讓不同的請求能夠被不同的Worker處理,這些Worker可以提供不同的開發環境,使得所有開發者可以共享一個服務器而每個人都擁有自己的Worker。

        想要提供負載平衡,只要在同一臺機器上運行多個Tomcat Worker並且能夠在這些Worker之間分佈Web請求。

        Tomcat Workers都定義在一個叫做workers.properties屬性文件之中,並且workers的說明告訴應該如何使用它們。

 

2.3.1.1 全局配置項

指令 默認 說明
worker.list ajp13 由逗號分離開的worker名稱列表.
worker.maintain 60 輔助連接池保持間隔,以秒爲單位。

 

2.3.1.2 鏈接指令

 

可配置一個通用的,然後每個work進行繼承。

指令 默認 說明
type ajp13 指定Tomcat服務器 與Apache之間的通信協議
host localhost Tomcat主機名或 IP 地址。
port 8009 Tomcat偵聽端口號。AJP13的默認端口是8009.
socket_connect_timeout socket_timeout*1000 套接字超時時間(毫秒爲單位)。
socket_keepalive false 在未激活的連接中發送KEEP_ALIVE信息(發送間隔時間依賴於操作系統的設置,一般爲120秒)
ping_mode -

探測tomcat的狀態策略。

C(content):鏈接模式,最後一次鏈接判斷是否超時。connect_timeout定義時間。若未定義使用ping_timeout。

P(prepost):請求模式,通過每次請求判斷是否超時。prepost_timeout定義時間。若未定義使用ping_timeout。

I(interval):間隔模式,定期檢測鏈接是否超時。connection_ping_interval間隔時間。ping_timeout超時時間。

A:以上所有的探測策略都將開啓。

connection_pool_size   JK會維護多個長連接做爲一個池。它被用來設置每個WebServer(Apache)子進程的最大連接數。
connection_pool_minsize (pool+1)/2 連接池中維護最小的連接數。
connection_pool_timeout 0 在連連池中維護的非活動連接連續多少秒後被釋放。如果爲0,則不釋放。
connection_acquire_timeout retries*retry_interval 獲取接連的超時。
lbfactor 1 負載平衡器權值

 

 

2.3.1.3 負載均衡設置

指令 默認 說明
balance_workers   逗號分隔的worker列表
sticky_session true 負載噴發採用Session粘貼機制,按SessionID噴發請求。爲了保障同一SessionID的請求被分發到同一臺服務器上。
sticky_session_force false 如果爲True, SessionID並不合法時則返回500錯誤,否則,丟掉Session並轉發到另外的機器上。

 

 

2.3.1.4 實例

# Define two status worker:
# - jk-status for read-only use
# - jk-manager for read/write use
worker.list=jk-status
worker.jk-status.type=status
worker.jk-status.read_only=true

worker.list=jk-manager
worker.jk-manager.type=status

# We define a load balancer worker
# with name "balancer"
worker.list=balancer
worker.balancer.type=lb
worker.balancer.error_escalation_time=0
worker.balancer.max_reply_timeouts=10
worker.balancer.sticky_session=true
worker.balancer.sticky_session_force=true  

# Now we add members to the load balancer First member is "tomcat1", most attributes are inherited from the template "worker.template".
worker.balancer.balance_workers=tomcat1
worker.tomcat1.reference=worker.template
worker.tomcat1.host=127.0.0.1
worker.tomcat1.port=8009
worker.tomcat1.activation=A

# Second member is "tomcat2", most attributes are inherited from the template "worker.template".
worker.balancer.balance_workers=tomcat2
worker.tomcat2.reference=worker.template
worker.tomcat2.host=127.0.0.1
worker.tomcat2.port=7009
worker.tomcat2.activation=A

# Finally we put the parameters
worker.template.type=ajp13
worker.template.socket_connect_timeout=5000
worker.template.socket_keepalive=true
worker.template.ping_mode=A
worker.template.ping_timeout=10000
worker.template.connection_pool_minsize=0
worker.template.connection_pool_timeout=600
worker.template.reply_timeout=300000
worker.template.recovery_options=3

 

2.3.2 uriworkermap.properties

/*.do=balancer
/*.jsp=balancer

#/*.gif=balancer
#/*.jpg=balancer
#/*.png=balancer
#/*.css=balancer
#/*.js=balancer
#/*.htm=balancer
#/*.html=balancer
#/*.txt=balancer


# Optionally filter out all .jpeg files inside that context
# For no mapping the url has to start with exclamation (!)

!/servlets-examples/*.jpeg=lb

#
# Mount jkstatus to /jkmanager
# For production servers you will need to
# secure the access to the /jkmanager url
#
/jk-manager=jk-manager
/jk-status=jk-status

 

 

2.3.3 httpd.conf

        需要在中添加httpd的配置文件中加載jk的配置文件。

 

# 加載jk配置文件
#Include conf/mod_jk.conf

 

2.3.4 mod_jk.conf

# a versioned file name.
LoadModule jk_module modules/mod_jk_2.2_32.so
<IfModule jk_module>
    JkWorkersFile conf/workers.properties
    JkLogFile logs/mod_jk.log
    JkLogLevel info
    JkShmFile logs/mod_jk.shm
    # JkOptions +RejectUnsafeURI
    # JkStripSession On
    JkWatchdogInterval 60
    <Location /jk-status>
        # Inside Location we can omit the URL in JkMount
        JkMount jk-status
        Order deny,allow
        Deny from all
        Allow from 127.0.0.1
    </Location>
    <Location /jk-manager>
        # Inside Location we can omit the URL in JkMount
        JkMount jk-manager
        Order deny,allow
        Deny from all
        Allow from 127.0.0.1
    </Location>
    JkMountFile conf/uriworkermap.properties
JkMount /* balancer
    # JkUnMount /myapp/static/* *
    # JkUnMount /myapp/images/* balancer
    # SetEnvIf REQUEST_URI "\.(htm|html|css|gif|jpg|js)$" no-jk
    # SetEnvIf Request_URI "/transactions/" JK_REPLY_TIMEOUT=600000
    # SetEnvIf Request_URI "/reports/" JK_REPLY_TIMEOUT=0
</IfModule>

 

 

2.3.5 編譯Linux版本JK

        在linux自行編譯jk時,需要以下步驟:

        1.解壓tomcat-connectors-1.2.37-src.tar.gz

        2.指定httpd的apxs文件。他會自動將mod_jk.do生成到httpd的modules下。

 
./configure --with-apxs=/opt/apache/httpd/bin/apxs

 

2.4 Session同步方式

2.4.1 sticky模式

        前端balancer可實現sticky模式的session同步功能。利用負載均衡器的sticky模式的方式把所有同一session的請求都發送到相同的Tomcat節點。這樣不同用戶的請求就被平均分配到集羣中各個tomcat節點上,實現負載均衡的能力。這樣做的缺點是沒有災難恢復的能力。一旦一個節點發生故障,這個節點上所有的session信息全部丟失;同一用戶同一session只和一個webServer交互,一旦這個webserver發生故障,本次session將丟失,用戶不能繼續使用。

 

2.4.2 複製模式

        利用Tomcat session複製的機制使得所有session在所有Tomcat節點中保持一致。當一個節點修改一個session數據的時候,該節點會把這個 session的所有內容序列化,然後廣播給所有其它節點。這樣當下一個用戶請求被負載均衡器分配到另外一個節點的時候,那個節點上有完備的 session信息可以用來服務該請求。這種做法的問題是對session哪怕有一點點修改,也要把整個sessions數據全部序列化 (serialize),還要廣播給集羣中所有節點,不管該節點到底需不需要這個session。這樣很容易會造成大量的網絡通信,導致網絡阻塞。一般採 用這種方式,當Tomcat節點超過4個時候,整個集羣的吞吐量就不能再上升了;

        此方式是通過tomcat本身提供的功能,只需要修改server.xml文件

        (1)修改Engine節點信息: <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">

        (2)去掉<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/> 的註釋符

        (3)web.xml中增加 <distributable/>

 

2.5 Linux部署常見問題

        1.Failed to lookup provider 'shm' for 'slotmem': is mod_slotmem_shm loaded??

        加載mod_slotmem_shm.so就可以了。

 

        2.BalancerMember Can't find 'byrequests' lb method

        三種模式,需要加載三個so:

        mod_lbmethod_bybusyness.so

        mod_lbmethod_byrequests.so

        mod_lbmethod_bytraffic.so

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章