Tomcat多實例部署及其原理

導讀:
昨天在跟羣友作技術交流的時候,瞭解到,有不少大公司都是採用了高可用的,分佈式的,實例沉餘1+臺。可是在小公司的同窗也不少,他們反映並非全部公司都有那樣的資源來供你調度。每每公司只會給你一臺機器,由於有些應用掛了公司也不會有損失的,咱們每每一臺機器就能夠搞定。
可是,咱們也要爲咱們作出來的應用負責,畢竟東西作出來是爲了給人用的,若是作出來的東西常常掛了,談何使用,在前期,若是公司資源緊張的狀況下,能夠不能夠作高可用,多機器的沉餘部署。可是至少是在但機上有2個進程在跑。so,在這裏咱們就說說這個,如何作單機多實例的部署。
在這裏談談,在只有單機的資源下,如何把單機的資源壓榨出來,用好單機。html

自家的主頁: http://jbeacon.top/2016/11/19/yunwei/1/java

一、Tomcat部署的場景分析

一般,咱們對tomcat單機部署需求能夠分爲幾種:mysql

  • 單實例單應用 (一個tomcat 一個web應用)
  • 單實例多應用 (一個tomcat多個應用)
  • 多實例單應用 (多個tomcat都部署一個應用)
  • 多實例多應用 (多個tomcat部署多個不一樣的應用)

第一種場景:這是咱們開發中常常用到的,若是不要求週期性地維護tomcat版本,通常的作法是把打好的war包丟到webapps目錄下,而後執行startup.sh腳本,而且能夠在瀏覽器裏訪問就好了。
第二種場景:是把多個應用程序的war包放在同一個tomcat的webapps目錄,這樣一來,關閉和啓動tomca,或tomcat掛掉會影響全部項目。
第三種場景: 各個tomcat都運行同一個應用程序,對應地須要修改不一樣的監聽端口,這種方式一般會和apache httpd或者nginx整合使用,作一些負載均衡的處理。
第四種場景: 至關於第一種場景的複數形式,除了修改不一樣的監聽端口,沒有本質區別。linux

通常來講,多實例部署tomcat,能夠充分利用系統資源,不過這種方式,也有幾個方面須要考慮:
多實例tomcat的更新維護,例如對tomcat進行升級等操做,咱們須要考慮如何能「優雅」地對全部實例進行升級
儘可能不要影響應用程序,在更新tomcat時,一不當心就把conf目錄等所有覆蓋,因此儘可能要把配置文件和安裝目錄隔離
對於單應用來講,若是將war包分別置於各個tomcat的webapps目錄,那麼在發佈新版本的war時,可能會出現某個實例更新失敗,致使用戶在訪問時可能會訪問到不一樣版本的web app,所以,比較好的方式就是全部tomcat實例都統一指向同一個應用程序,這樣作,就能夠多個tomcat用一份應用源碼,簡單部署,單機高可用也能實現(要配合nginx).
本文重點闡述多實例應用的部署方案,可是爲了解決上述幾個問題,咱們須要先來了解一下tomcat的一些基本狀況。nginx

二、咱們的目標

 

tomcat架構

 

三、tomcat架構

總體架構圖

 

tomcat架構

 

這裏有一臺服務器,3臺tomcat服務,以及一臺tomcat的解構圖。web

分離目錄

目錄 做用
bin 主要存放腳本文件,例如比較經常使用的windows和linux系統中啓動和關閉腳本
conf 主要存放配置文件,其中最重要的兩個配置文件是server.xml和web.xml
lib 主要存放tomcat運行所依賴的包
logs 主要存放運行時產生的日誌文件,例如catalina.{date}.log等
temp 存放tomcat運行時產生的臨時文件,例如開啓了hibernate緩存的應用程序,會在該目錄下生成一些文件
webapps 部署web應用程序的默認目錄
work 主要存放由JSP文件生成的servlet(java文件以及最終編譯生成的class文件)

再介紹兩個tomcat中比較重要的概念(一般也是兩個系統變量)——CATALINA_HOME和CATALINA_BASE:redis

CATALINA_HOME:即指向Tomcat安裝路徑的系統變量
CATALINA_BASE:即指向活躍配置路徑的系統變量經過設置這兩個變量,就能夠將tomcat的安裝目錄和工做目錄分離,從而實現tomcat多實例的部署。
Tomcat官方文檔指出,CATALINA_HOME路徑的路徑下只須要包含bin和lib目錄,這也就是支持tomcat軟件運行的目錄,而CATALINA_BASE設置的路徑能夠包括上述全部目錄,不過其中bin和lib目錄並非必需的,缺省時會使用CATALINA_HOME中的bin和conf。如此,咱們就可使用一個tomcat安裝目錄部署多個tomcat實例,這樣的好處在於方便升級,就能夠在不影響tomcat實例的前提下,替換掉CATALINA_HOME指定的tomcat安裝目錄。sql

 

tomcat架構

 

tomcat serve.xml 配置結構
Container容器子容器間關係圖docker

tomcat架構

 

交互圖shell

tomcat架構

 

對比下Tomcat serve.xml 的配置

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

 

<?xml version="1.0" encoding="UTF-8"?>

<Server port="8005" shutdown="SHUTDOWN">

<Listener className="org.apache.catalina.startup.VersionLoggerListener" />

<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />

<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />

<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />

<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

<GlobalNamingResources>

<Resource name="UserDatabase" auth="Container"

type="org.apache.catalina.UserDatabase"

description="User database that can be updated and saved"

factory="org.apache.catalina.users.MemoryUserDatabaseFactory"

pathname="conf/tomcat-users.xml" />

</GlobalNamingResources>

<Service name="Catalina">

<Connector port="8080" protocol="HTTP/1.1"

connectionTimeout="20000"

redirectPort="8443" />

<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

<Engine name="Catalina" defaultHost="localhost">

<Realm className="org.apache.catalina.realm.LockOutRealm">

<Realm className="org.apache.catalina.realm.UserDatabaseRealm"

resourceName="UserDatabase"/>

</Realm>

<Host name="localhost" appBase="webapps"

unpackWARs="true" autoDeploy="true">

<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"

prefix="localhost_access_log" suffix=".txt"

pattern="%h %l %u %t &quot;%r&quot; %s %b" />

</Host>

</Engine>

</Service>

</Server>

 

四、實戰

端口配置

修改server.xml

在server.xml中配置了四個監聽端口,分別是:
Server Port:該端口用於監聽關閉tomcat的shutdown命令,默認爲8005.
Connector Port:該端口用於監聽HTTP的請求,默認爲8080.
AJP Port:該端口用於監聽AJP( Apache JServ Protocol )協議上的請求,一般用於整合Apache Server等其餘HTTP服務器,默認爲8009
Redirect Port:重定向端口,出如今Connector配置中,若是該Connector僅支持非SSL的普通http請求,那麼該端口會把https的請求轉發到這個Redirect Port指定的端口,默認爲8443

虛擬主機配置
再來講Host配置,Host就是所謂的虛擬主機,對應包含了一個或者多個web應用程序,默認的Host配置以下

 

1

 

<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">

 

其中:
name: 虛擬主機的名稱,一臺主機表示了徹底限定的域名或IP地址,默認爲localhost,同時也是惟一的host,進入tomcat的全部http請求都會映射到該主機上
appBase:web應用程序目錄的路徑,能夠是CATALINA_HOME的相對路徑,也能夠寫成絕對路徑,默認狀況下爲$CATALINA_HOME/webappsunpackWARs: 表示是否自動解壓war包
autoDeploy:所謂的熱部署,即在tomcat正在運行的狀況下,若是有新的war加入,則會當即執行部署操做
另外再介紹一個Host中的屬性—deployOnStartup:表示tomcat啓動時是否自動部署appBase目錄下全部的Web應用程序,默認爲true。這個屬性和autoDeploy會產生兩次部署的「反作用」:一次是tomcat啓動時就開始部署,第二次就是autoDeploy引發的熱部署。所以最好將autoDeploy置爲false
在部署多實例單應用的時候,默認的$CATALINA/webapps會由於tomcat安裝目錄升級產生沒必要要的麻煩,咱們考慮將appBase的目錄統一到另外的路徑下。

Context的配置
最後再說明一下Context的配置,它出如今Host配置內,一個Context的配置就表明了一個web應用程序,若是配置多應用程序,就須要在Host下配置多個Context,一個簡單的Context配置以下

 

1

 

<Context path="/some" docBase="someapp.war" >

 

path:表示訪問入口,例如,path=」/abc」,則訪問localhost:8080/abc時,就能夠訪問該Context對應的應用程序。若是path=」」,則直接用localhost:8080就能夠訪問
docBase:表示應用程序的解包目錄或者war文件路徑,是Host的appBase配置目錄的相對路徑,也能夠是直接寫成絕對路徑,可是不要將appBase的值,做爲docBase配置路徑的前綴,例如appBase=」somedir」,docBase=」somedir-someapp.war」,這樣的配置會致使部署錯誤
經過配置Host的appBase和Context的docBase兩個屬性,能夠將應用程序的文件和tomcat相關的目錄進行分離,這樣webapps目錄也就沒有做用了。

跟我來實施該方案

  • 如今假設咱們有一臺已經配置好Java環境的服務器:(我用的是阿里雲)
  • 我已經有一個已經完成的shop.war 應用程序

步驟1:
下載並解壓tomcat

tomcat架構

 

步驟2:
對Tomcat目錄做如下調整:
在tomcat安裝目錄下建立a.ttlsa.com、b.ttlsa.com,而且將conf、logs、webapp、temp、work目錄拷貝到這兩個目錄,而後tomcat安裝目錄只須要留下bin、a.ttlsa.com、b.ttlsa.com、lib這4個目錄便可。配置後的目錄結構以下:

tomcat架構

 

若是要度tomcat 進行升級,咱們只是須要對tomcat的lib 和 bin 目錄進行升級便可。

步驟3:
配置站點server.xml
配置a.ttlsa.com 

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

 

<?xml version="1.0" encoding="UTF-8"?>

<!-- 8005 改成8005 -->

<Server port="8005" shutdown="SHUTDOWN">

<Listener className="org.apache.catalina.startup.VersionLoggerListener" />

<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />

<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />

<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />

<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

<GlobalNamingResources>

<Resource name="UserDatabase" auth="Container"

type="org.apache.catalina.UserDatabase"

description="User database that can be updated and saved"

factory="org.apache.catalina.users.MemoryUserDatabaseFactory"

pathname="conf/tomcat-users.xml" />

</GlobalNamingResources>

<Service name="Catalina">

<Connector port="8081" protocol="HTTP/1.1"

connectionTimeout="20000"

redirectPort="8443" />

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

<Engine name="Catalina" defaultHost="localhost">

<Realm className="org.apache.catalina.realm.LockOutRealm">

<Realm className="org.apache.catalina.realm.UserDatabaseRealm"

resourceName="UserDatabase"/>

</Realm>

<!--

<Host name="localhost" appBase="webapps"

unpackWARs="true" autoDeploy="true">

<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"

prefix="localhost_access_log" suffix=".txt"

pattern="%h %l %u %t &quot;%r&quot; %s %b" />

</Host>

-->

<Host name="localhost" appBase="F:\data\www\a.ttlsa.com"

unpackWARs="true" autoDeploy="true"

xmlValidation="false" xmlNamespaceAware="false">

<Context path="" docBase="" reloadable="true">

<valve className="org.apache.catalina.valves.RemoteAddrValve" />

</Context>

</Host>

</Engine>

</Service>

</Server>

 

配置b.ttlsa.com

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

 

<?xml version="1.0" encoding="UTF-8"?>

<!-- 8005 改成8006 -->

<Server port="8002" shutdown="SHUTDOWN">

<Listener className="org.apache.catalina.startup.VersionLoggerListener" />

<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />

<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />

<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />

<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

<GlobalNamingResources>

<Resource name="UserDatabase" auth="Container"

type="org.apache.catalina.UserDatabase"

description="User database that can be updated and saved"

factory="org.apache.catalina.users.MemoryUserDatabaseFactory"

pathname="conf/tomcat-users.xml" />

</GlobalNamingResources>

<Service name="Catalina">

<Connector port="8082" protocol="HTTP/1.1"

connectionTimeout="20000"

redirectPort="8443" />

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

<Engine name="Catalina" defaultHost="localhost">

<Realm className="org.apache.catalina.realm.LockOutRealm">

<Realm className="org.apache.catalina.realm.UserDatabaseRealm"

resourceName="UserDatabase"/>

</Realm>

<!--

<Host name="localhost" appBase="webapps"

unpackWARs="true" autoDeploy="true">

<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"

prefix="localhost_access_log" suffix=".txt"

pattern="%h %l %u %t &quot;%r&quot; %s %b" />

</Host>

-->

<Host name="localhost" appBase="F:\data\www\a.ttlsa.com"

unpackWARs="true" autoDeploy="true"

xmlValidation="false" xmlNamespaceAware="false">

<Context path="" docBase="" reloadable="true">

<valve className="org.apache.catalina.valves.RemoteAddrValve" />

</Context>

</Host>

</Engine>

</Service>

</Server>

 

建立多實例啓動腳本

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

 

# description: 啓動tomcat多實例.#

. /etc/init.d/functions

RETVAL=$?

# tomcat實例目錄

export CATALINA_BASE="$PWD"

# tomcat安裝目錄

export CATALINA_HOME="/usr/local/tomcat-7.0.50"

# 可選

export JVM_OPTIONS="-Xms128m -Xmx1024m -XX:PermSize=128m -XX:MaxPermSize=512m"

case "$1" in

start)

if [ -f $CATALINA_HOME/bin/startup.sh ];then

echo $"Start Tomcat"

$CATALINA_HOME/bin/startup.sh

fi

;;

stop)

if [ -f $CATALINA_HOME/bin/shutdown.sh ];then

echo $"Stop Tomcat"

$CATALINA_HOME/bin/shutdown.sh

fi

;;

*)

echo $"Usage: $0 {start|stop}"

exit 1

;;

esac

exit $RETVAL

 

這段shell 腳本比較簡單,主要是設置環境變量,接受命令參數 RETVAL=?,來執行不一樣的命令。RETVAL=start/stop等exportCATALINABASE=」?,來執行不一樣的命令。RETVAL=start/stop等exportCATALINABASE=」PWD」 表示設置當前路徑爲 CATALINA_BASE 的環境變量,通常狀況下CATALINA_BASE 和 CATALINA_HOME 是默認同樣的。

啓動腳本賦權限

 

1

 

# chmod a+x tomcat.sh

 

五、啓動測試

啓動/關閉a.ttlsa.com

 

1

2

3

4

5

6

 

啓動

# cd /usr/local/tomcat-7.0.50/a.ttlsa.com/

# ./tomcat.sh start

關閉

# cd /usr/local/tomcat-7.0.50/a.ttlsa.com/

# ./tomcat.sh stop

 

啓動/關閉b.ttlsa.com

 

1

2

3

4

5

6

 

啓動

# cd /usr/local/tomcat-7.0.50/a.ttlsa.com/

# ./tomcat.sh start

關閉

# cd /usr/local/tomcat-7.0.50/a.ttlsa.com/

# ./tomcat.sh stop

 

備註:必定須要cd到tomcat.sh的當前目錄下執行才能夠

在win7 下,須要建立在a.ttlsa.com 和b.ttlsa.com下面建立 startup.bat 來啓動

 

1

2

3

4

5

6

 

@echo off

set JAVA_HOME=D:\Program Files\Java\jdk1.8.0_112

set PATH=%JAVA_HOME%\bin;%PATH%

set CATALINA_BASE=%CD%

cd E:\tomcat-8.5.6\bin

catalina.bat start

這段是在win7 下雲的bat腳本,於shell腳本同理,set CATALINA_BASE=%CD% 也是設置環境變量,CD 能夠獲取當前的路徑。

shell 腳本入門參考:http://sishuok.com/forum/blogPost/list/5655.html

六、結果

單個Tomcat應用多個tomcat實例的配置到此,就結束了。
此外,咱們在這裏的基礎上進行系統的擴展,好比若是個人Tomcat應用掛掉了,個人整個應用都將不可用了,咱們應該如何處理?
咱們能夠把Tomcat複製多份,在單機的狀況下,開多一個Tomcat進程,在配合Nginx 來配置,就能實現Tomcat的自動切換,這些內容,有空再寫。

若是須要操做多個實例顯得比較麻煩,你們能夠自行寫統一的腳本。

 

tomcat架構

 

tomcat架構

 

Linux 下的實現基本一致。

這樣的好處是,顯而易見的,這樣能開啓Tomcat的多個進程,即多臺tomcat,掛了也不太怕,還有其餘tomcat應用支撐,代碼實例咱們發版本的時候,只須要發佈一份,實例代碼易於維護。
可是,咱們網站的域名和端口通常是同一採用80端口,統一的域名,而如今咱們開啓tomcat只能一個使用80端口,顯然是不合適的·,爲此咱們會引入負載均衡的nginx來配置。
nginx 採用80 端口,tomcat分別採用8080, 8081, 8082 這樣就能讓咱們的程序穩定的運行。
這樣,咱們就能進最大的限度來壓榨單機的性能,保證應用程序的穩定的運行。
而然,單機否則有單機的瓶頸,畢竟單機中的cpu 已經各類硬件的限制,會大大影響實例程序的跑動,在這時,就再也不是單機能抗的動的了,咱們須要分析程序的瓶頸在那?數據庫,那就把數據庫單獨分出去,單獨一臺機器,是文件圖片服務器,就把他分出去。若是是應用程序太大,就要考慮把應用實例進行拆解爲不一樣哦那個的組件,單獨部署,這就是分佈式部署。
固然,這都是後話,只有程序複雜到必定的程度,並體量很大的話,纔會作這種架構的演變,成本和技術投入的難度也會相應的變大。
本章,只侷限於如何玩好單機的基礎上來討論,對於分佈式的那塊,筆者能力有限,尚且還不能徹底駕馭,不作分享。

七、nginx+tomcat熱備

在上面的配置的基礎上,咱們在進一步進行擴展,進行實例的均衡和熱備。
能夠在一個服務器掛了的狀況下連到另一個,那怎麼弄呢?
其實很簡單,在upstream中的local_tomcat中配置多一個server。
在上面,個人a.ttlsa.com 和 b.ttlsa.com 都是訪問 F:\data\www\a.ttlsa.com 下的源碼的index.jsp 頁面,
爲了能觀察,nginx 的keepAlive 的效果,我作一下修改:
a.ttlsa.com —> F:\data\www\a.ttlsa.com index.jsp 中文字是 1
b.ttlsa.com —> F:\data\www\b.ttlsa.com index.jsp 中文字是 2

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

 

upstream local_tomcat {

server localhost:8081 weight=1;

server localhost:8082 weight=5;

}

server {

listen 80;

server_name localhost:8081;

#charset koi8-r;

#access_log logs/host.access.log main;

#location / {

# root html;

# index index.html index.htm;

#}

location / {

proxy_pass http://local_tomcat;

}

 

tomcat架構

 

在一般的狀況下,咱們通常是指向一份源碼就足夠了,而且設置權值,減輕應用的壓力。同時也不會出現單點的狀況。

補充:nginx.con 配置

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

 

#user nobody;

worker_processes 1;

events {

worker_connections 1024;

}

http {

include mime.types;

default_type application/octet-stream;

sendfile on;

#tcp_nopush on;

#keepalive_timeout 0;

keepalive_timeout 65;

#gzip on;

upstream local_tomcat {

server localhost:8081 weight=1;

server localhost:8082 weight=5;

}

server {

listen 80;

server_name localhost;

#charset koi8-r;

#access_log logs/host.access.log main;

#location / {

# root html;

# index index.html index.htm;

#}

location / {

proxy_pass http://local_tomcat;

}

error_page 500 502 503 504 /50x.html;

location = /50x.html {

root html;

}

}

}

綜上:咱們作到了多臺tomcat 可是咱們也能作到tomcat的簡單升級,而且實現實例的負載均衡,已經應用的主備,在也不用擔憂應用掛掉而睡不了覺了。
缺點:nginx依然存在單點的問題。

本次的實驗資源供下載:http://download.csdn.net/detail/a82793510/9687715

經驗之談

若是是在資源有限的狀況下,已經選擇了單機,證實不是有錢荏,我通常會把上面的權去掉,在這樣咱們就能夠在一臺tomcat應用服務器掛掉的狀況下,纔會訪問備機Tomcat應用服務器。
若是隻是應用的狀況下,這樣已經足夠了。用基於IP分發的策略已經能解決絕大部分需求。

資源進一步極端化

如今,咱們在這臺單機上已經部署了一個應用app1, 假設如今我司實在是資源太緊缺了,咱們又要在這臺機子上,部署另一個應用app2。
那麼如今咱們就要對Nginx 和 Tomcat 進行改動。
改動通常分爲2種方法:2級域名改動 或 2級目錄改動。
先來在上面的基礎上說說二級目錄改動:
按照咱們上面的,咱們的目標的架構:咱們已經部署了一個應用程序:some.war ,如今我要採用二級目錄方式部署另外的一個應用程序:app.war。
那麼我會在上面的基礎上作以下的修改:localhost 能夠修改成本身的域名。

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

 

<Host name="localhost/some" appBase="F:\data\www\a.ttlsa.com"

unpackWARs="true" autoDeploy="true"

xmlValidation="false" xmlNamespaceAware="false">

<Context path="" docBase="" reloadable="true">

<valve className="org.apache.catalina.valves.RemoteAddrValve" />

</Context>

</Host>

<Host name="localhost/app" appBase="F:\data\www\b.ttlsa.com"

unpackWARs="true" autoDeploy="true"

xmlValidation="false" xmlNamespaceAware="false">

<Context path="" docBase="" reloadable="true">

<valve className="org.apache.catalina.valves.RemoteAddrValve" />

</Context>

</Host>

另外的一臺的service.xml 也一樣如此配置。
nginx中的localhost 能夠修改成本身的域名 如 mp.hello.io

 

1

2

3

4

5

 

server {

listen 80;

server_name localhost; // 能夠修改成本身的域名

}

二級域名的改動,
前提:咱們有一個頂級域名:如 hello.io 這樣的一個頂級域名:
那麼,咱們如今能夠這樣作:
如今萬網中配置一下咱們的二級域名,如som.hello.io和app.hello.io 都要在萬網中指向咱們的服務器Ip 地址。
在增長二級域名的狀況下,咱們能夠新增2個是實例。
把Nginx修改成這樣的配置:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

 

#user nobody;

worker_processes 1;

events {

worker_connections 1024;

}

http {

include mime.types;

default_type application/octet-stream;

sendfile on;

#tcp_nopush on;

#keepalive_timeout 0;

keepalive_timeout 65;

#gzip on;

upstream local_tomcat01 {

server localhost:8081;

server localhost:8082;

}

upstream local_tomcat02 {

server localhost:8083;

server localhost:8084;

}

server {

listen 80;

server_name some.hello.io;

#charset koi8-r;

#access_log logs/host.access.log main;

#location / {

# root html;

# index index.html index.htm;

#}

location / {

proxy_pass http://local_tomcat02;

}

error_page 500 502 503 504 /50x.html;

location = /50x.html {

root html;

}

}

server {

listen 80;

server_name app.hello.io;

#charset koi8-r;

#access_log logs/host.access.log main;

#location / {

# root html;

# index index.html index.htm;

#}

location / {

proxy_pass http://local_tomcat02;

}

error_page 500 502 503 504 /50x.html;

location = /50x.html {

root html;

}

}

此外,修改一下,Tomcat 的端口就能夠了,同時80 81, 指向一個實例,83 84 指向另一個實例(appBase中指定)。這樣就能夠作到程序的主備操做。

備註:service_name 的名稱能夠是ip 地址。
nginx在配置upstream時,有兩個參數:
ip_hash(同一IP一直使用同一臺server服務)
weight(server的使用權重,數值越大,nginx分發的請求越多)

經過配合這兩個參數,能粗糙地解決session共享的問題。
對於一些不是太依賴session的應用,或者只有用戶登陸時保存,那麼我認爲能夠用Cookies代替。
即便真的要Session共享,我認爲手動寫代碼保存到Memcached比爲Tomcat加插件好,這樣能得到更好的可控性。
並且我不用Tomcat,用Redis,這個msm就用不上啦,不過我會按照個人思想實現session共享,呵呵,我的愚見!

 

tomcat架構

 

最後咱們的架構是這樣的。在這樣的解構下,咱們不管是修改成 二級目錄 亦或是二級域名,咱們運維都只是要作很小的改動就能切換。配置和源碼分離的結構,對咱們之後的擴展爲分佈式應用,仍是依然是單機的傳統結構都是進能夠攻退以守。
留有餘地,惟一不足就是nginx的單點問題,不過就單機體系來講已經夠用了。

集羣

上面不架構已是屬於在單機上作了一個簡單的集羣了,要實現Tomcat。
要多臺機器,只要修改上面Nginx的分發的Ip 就可,可是會話共享是一個很大的問題,可是,用基於IP分發的策略已經能解決絕大部分需求。
這裏已經脫離了咱們單機應用的主題,之後有機會探討。

參考文章:
http://www.cnblogs.com/tq03/p/3507658.html
http://www.itnose.net/detail/6658488.html
http://www.ttlsa.com/tomcat/config-multi-tomcat-instance/
http://www.cnblogs.com/_popc/p/4167516.html
http://www.itnose.net/detail/6485584.html
http://www.itnose.net/detail/6521677.html
http://www.itnose.net/detail/6448554.html
http://www.aikaiyuan.com/7907.html
http://blog.csdn.net/cclovett/article/details/26377269 (nginx)
http://www.roncoo.com/article/detail/125185

相關文章
相關標籤/搜索