Apache + Tomcat + mod_jk實現集羣服務

Tomcat中的集羣原理是經過組播的方式進行節點的查找並使用TCP鏈接進行會話的複製。php

實現效果:用apache 分發請求到tomcat中的對應的項目 html

環境說明:java

操做系統:window xpnode

Javasdk: 1.7 linux

Apache: 2.2.14    (本地安裝路徑:D:\Apache2.2\)web

Tomcat: 7.0.42  ( http://tomcat.apache.org/download-70.cgi ),若是在同一臺機器上模擬,下載zip版本. 實例中展現了2個節點apache

mod_jk: 1.2.37:  ( http://tomcat.apache.org/download-connectors.cgi )windows

安裝步驟:

1.安裝jdktomcat

2.安裝Apache2.2,使用默認設置,而且安裝路徑中不要空格.服務器

3.解壓tomcat

4.拷貝mod_jk.so到Apache安裝路徑的modules文件夾下

配置步驟

修改Apache配置:

關於修改涉及到的文件httpd.conf和workers.properties文件能夠下載一份mod_jk的源碼包參看

1.修改Apache配置文件httpd.conf (筆者路徑:D:\Apache2.2\conf\httpd.conf), 在最後一行末尾添加:

include "D:\Apache2.2\conf\mod_jk.conf"

2. 在httpd.conf 同目錄下新建mod_jk.conf文件

#加載mod_jk Module 
LoadModule jk_module modules/mod_jk.so

#指定 workers.properties文件路徑
JkWorkersFile conf/workers.properties

#指定哪些請求交給tomcat處理,"controller"爲在workers.propertise裏指定的負載分配控制器名
JkMount /* controller

3.在httpd.conf同目錄下新建 workers.properties文件

#這裏能夠配置任意多個Tomcat,此處配置了2個Tomat服務器.
#host和port根據本身實際配置.實例配置的是本機兩個tomcat,分別使用不一樣的端口.避免衝突
#若是Tomcat再也不同一機器上,不必改端口的。


#server 列表
worker.list=controller,tomcat1,tomcat2  


#========tomcat1========

worker.tomcat1.port=9988        #ajp13 端口號,在tomcat下server.xml配置,默認8009
worker.tomcat1.host=localhost        #tomcat的主機地址,如不爲本機,請填寫ip地址
worker.tomcat1.type=ajp13
worker.tomcat1.lbfactor=1        #server的加權比重,值越高,分得的請求越多

#========tomcat2========

worker.tomcat2.port=9999        #ajp13 端口號,在tomcat下server.xml配置,默認8009
worker.tomcat2.host=localhost        #tomcat的主機地址,如不爲本機,請填寫ip地址
worker.tomcat2.type=ajp13
worker.tomcat2.lbfactor=1        #server的加權比重,值越高,分得的請求越多 


#========controller,負載均衡控制器========
worker.controller.type=lb


#指定此負載平衡器負責的Tomcat應用節點。

worker.controller.balanced_workers=tomcat1,tomcat2   #指定分擔請求的tomcat

#此處指定集羣是否須要會話複製,若是設爲true,則代表爲會話粘性,不進行會話複製,當某用戶的請求第一次分發到哪臺
#Tomcat後,後繼的請求會一直分發到此Tomcat服務器上處理;若是設爲false,則代表需求會話複製。

worker.controller.sticky_session=false      #設爲false,則代表需求會話複製。

修改Tomcat配置:

說明,若是修改了tomcat配置文件,最好將文件編碼轉換成utf-8格式.

由於實例中咱們定義了2個tomcat處理分發.因此咱們將tomcat的解壓版本(zip)格式複製一份.用來分別擔當不一樣的分發處理角 色. 這裏由於在一臺機器上,因此咱們使用zip版本的,固然你某個分發處理機器上只一個tomcat服務器的話,能夠選擇安裝版本的.這裏推薦使用解壓 版的.tomcat6的配置方式跟7一致.

以tomcat-node1爲實例

1.修改分發tomcat對應的service.xml文件,保證Apache對應的 workers.properties中的AJP13的connector的port. 

<!-- 定義一個AJP 1.3 鏈接端口爲9988 ,默認值爲8009,這裏咱們改爲咱們本身定義的9988端口 -->
<Connector port="9988" protocol="AJP/1.3" redirectPort="8443" />

2.增長jvmRoute的值,保證同workers.properties裏邊配置的值一致

<!--增長jvmRoute,值爲在Apache中配置的list集羣結點中的值,這裏定義爲tomcat1結點-->
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">

3.去掉默認註釋掉的集羣配置

<!--取消集羣結點相關的註釋,該句默認值註釋掉的,咱們須要配置集羣因此去掉註釋,讓其起做用-->
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>

若是咱們的tomcat結點分佈在不一樣的機器上,那麼咱們的集羣至此已經配置完成.去掉多餘註釋,顯示作了修改的部位

修改前

<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

<!-- You should set jvmRoute to support load-balancing via AJP ie :
<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
-->
<Engine name="Catalina" defaultHost="localhost">

<!--For clustering-->
<!--
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
-->

修改後的tomcat-node1

<!-- 定義一個AJP 1.3 鏈接端口爲9988 ,默認值爲8009,這裏咱們改爲咱們本身定義的9988端口 -->
<Connector port="9988" protocol="AJP/1.3" redirectPort="8443" />

<!--增長jvmRoute,值爲在Apache中配置的list集羣結點中的值,這裏定義爲tomcat1結點-->
<Engine name="Catalina" defaultHost="localhost"  jvmRoute="tomcat1">

<!--取消集羣結點相關的註釋,該句默認值註釋掉的,咱們須要配置集羣因此去掉註釋,讓其起做用-->
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>

修改後的tomcat-node2

<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector port="9999" protocol="AJP/1.3" redirectPort="8443" />

<!-- You should set jvmRoute to support load-balancing via AJP ie :
<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
-->
<Engine name="Catalina" defaultHost="localhost"  jvmRoute="tomcat2">

<!--For clustering-->
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>

說明:這裏的protocol="AJP/1.3",鏈接以及jvmRoute須要保證同咱們在Apache服務器中配置的works.properties一致.修改完後最好將service.xml文件的編碼設置爲utf-8格式.不然可能tomcat啓動會出錯.

4. 實例中咱們的兩個tomcat結點在同一臺機器上,因此還須要保證protocol="HTTP/1.1"的端口不一致.否則本地的兩個tomcat會起衝突

下面爲筆者實例中解決同一臺機器上多個tomcat服務器之間端口衝突作的修改.

Tomcat--node1

Tomcat-node2

<Server port="9995" shutdown="SHUTDOWN">
……
<Connector port="9990" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
……

說明:這裏的protocol="HTTP/1.1"配置的相關端口之間不能衝突,並且也不能同本機其它應用程序佔用的端口衝突.不然可能會報錯.

實例測試

1.在web.xml文件中增長

<distributable/>

2.編寫測試jsp代碼

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ page import="java.text.SimpleDateFormat"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>Tomcat集羣測試</title>
  </head>
  
  <body>
        服務器信息:

    <%
      String dtm = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date());
      System.out.println("["+request.getLocalAddr()+":"+ request.getLocalPort()+"]" + dtm);
      out.println("<br>["+request.getLocalAddr()+":" +request.getLocalPort()+"]" + dtm+"<br>"); 
    %>
    
    session分發:
    <%
        session.setAttribute("name","dennisit");
        System.out.println("[session分發] session id:"+session.getId());
        out.println("<br>[session分發] session id: " + session.getId()+"<br>");
    %>
  </body>
</html>

3.測試負載均衡與session分發

將項目部署到每一個集羣結點中,即實例中的tomcat_node1和tomcat_node2,依次移動Apache和tomcat服務器,tomcat服務器之間的啓動順序隨意.這裏Apache端口使用默認的80.

上面是在FireFox中運行項目後刷新3次執行的效果,能夠看到2個tomcat分發結點之間輪流負載.並且兩臺服務器上的session值是同樣的.說明session分發成功.

兩臺Tomcat服務器日誌打印輸出結果:

錯誤解決
問題:發生服務特定錯誤:1

右鍵個人電腦->管理->系統工具->時間查看器->應用程序,而後對應應用程序的右側能夠查看到錯誤日誌.

筆者錯誤:

The Apache service named  reported the following error:
>>> httpd.exe: Syntax error on line 484 of D:/Apache2.2/conf/httpd.conf: Syntax error on line 1 of D:/Apache2.2/conf/mod_jk.conf: Cannot load D:/Apache2.2/modules/mod_jk.so into server: \xd5\xd2\xb2\xbb\xb5\xbd\xd6\xb8\xb6\xa8\xb5\xc4\xb3\xcc\xd0\xf2\xa1\xa3     

錯誤緣由,這個文件要跟Apache版本對應.個人Apache版本爲2.2的,最初搞的爲 tomcat-connectors-1.2.37-windows-i386-httpd-2.0.x版本因此錯誤.

修復後啓動

附錄:

Apache與Tomcat的區別:

Apache是一個web服務器環境程序,能夠做爲web服務器使用。不過只支持靜態網頁,如(asp,php,cgi,jsp)等動態網頁的就顯得無能爲力。

若是想讓服務器也能處理動態頁面,那麼就須要Tomcat。

當處理靜態頁面時,Tomcat不如Apache迅速。Tomcat不象Apache同樣可配置(如:能夠做爲一個代理服務器,即loadbalaner)。

Tomcat不象Apache同樣強壯。

基於以上緣由,一個現實的網站使用一個Apache做爲Web服務器,爲網站的靜態頁面請求提供服務;並使用Tomcat服務器做爲一個Servlet/JSP插件,顯示網站的動態頁面。

Apache,Tomcat負載均衡和集羣:

對請求的處理又有兩種不一樣的方式:負載平衡、狀態複製(即集羣).

負載平衡:每臺服務器都是獨立的,只是對請求的負載進行平衡,而不對狀態(SESSION)進行復制。

狀態複製(集羣):先進行負載平衡,再在各服務器間複製應用狀態。

Apache+Tomcat構建企業級應用

1.Apache主要用來解析靜態文本,如html,tomcat也有此功能,但apache能大大提升效率,對於併發數較大的企業級應用,能更好的顯示Apache的高效率; 

2.Tomcat 用來解析jsp,servlet等,全部的客戶請求首先會發送到apache,若是請求是靜態文本則由apache解 析,並把結果返回給 客戶端,若是是動態的請求,如jsp,apache會把解析工做交給tomcat,由tomcat進行解析(這首先要二者現實整 合),tomcat解析完 成後,結果還是經過apache返回給客戶端,這樣就能夠達到分工合做,實現負載均衡,提升系統的性能!

搭建過程當中遇到的一些問題:

一、當Apache在非根目錄下時可能出現以下錯誤:

httpd: Syntax error on line 39 of D:/wwwroot/Apache24/conf/httpd.conf: ServerRoot must be a valid directory

該錯誤只需將httpd.conf下Define SRVROOT修改成Apache所在目錄。

#Define SRVROOT "/Apache24"
#指向對應Apache目錄
Define SRVROOT "D:/wwwroot/Apache24"

二、若集羣成功搭建後訪問頁面仍在Apache默認頁面:

查看httpd.conf下Virtual hosts是否已註釋,Apache2.4默認開啓,將Include conf/extra/httpd-vhosts.conf註釋。

三、ApacheMonitor啓動提示The requested operation has failed!

查看Apache24\logs\error.log下錯誤提示,或使用命令行httpd.exe -w -n "Apache2.4(Apache服務名)" -k start調試

服務安裝:httpd.exe -k install

相關文章
相關標籤/搜索