天天看點

Tomcat實作session保持的三種方式、使用msm方式搭建jsp網站

Tomcat簡單的來說類似于php的功能,主要實作java程式的編譯,最後呈現給使用者的是html格式的代碼,使用使用者可以在浏覽器中通路。Tomcat是Java語言研發的,是以依賴于java的虛拟機(jvm)。

實作的原理如下圖,會話保持使用前端的排程器實作。例如:使用Ngnix排程時,使用ip_hash算法就可以實作。

<a href="http://guoting.blog.51cto.com/attachment/201410/27/8886857_1414410273xJwo.png" target="_blank"></a>

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

69

70

71

72

73

74

75

76

77

78

79

80

<code>作業系統: CentOS 6,5</code>

<code>目标主機:172.16.10.122  172.10.10.133</code>

<code>第一步:安裝Java虛拟機 </code>

<code>### 獲得jdk軟體 jdk-6u31-linux-x64-rpm.bin 這裡說明:對應的jdk版本有bin版本和rpm版本,</code>

<code>可以根據自己的需要下載下傳。下載下傳位址是:</code>

<code>### 安裝步驟</code>

<code>chmod</code> <code>+x jdk-6u31-linux-x64-rpm.bin</code>

<code>.</code><code>/jdk-6u31-linux-x64-rpm</code><code>.bin</code>

<code>## cat /etc/profile.d/java.sh </code>

<code>export</code> <code>JAVA_HOME=</code><code>/usr/java/latest</code>

<code>export</code> <code>PATH=</code><code>/usr/java/latest/bin/</code><code>:$PATH</code>

<code>### </code>

<code>source</code> <code>/etc/profile</code><code>.d</code><code>/java</code><code>.sh </code>

<code>第二步:安裝tomcat</code>

<code>### 獲得tomcat軟體 apache-tomcat-7.0.55.tar.gz </code>

<code>tar</code> <code>xf ache-tomcat-7.0.55.</code><code>tar</code><code>.gz -C </code><code>/usr/local</code>

<code>ln</code> <code>-sv apache-tomcat-7.0.55 tomcat</code>

<code>### cat /etc/profile.d/tomcat.sh </code>

<code>export</code> <code>CATALINA_HOME=</code><code>/usr/local/tomcat</code>

<code>export</code> <code>PATH=$CATALINA_HOME</code><code>/bin</code><code>:$PATH</code>

<code>###</code>

<code>第三步:添加測試站點,站點的目錄數如下:</code>

<code>### tree /usr/local/tomcat/webapps/test/</code>

<code>/usr/local/tomcat/webapps/test/</code>

<code>|-- WEB-INF</code>

<code>|   |-- classes</code>

<code>|   `-- lib</code>

<code>`-- index.jsp</code>

<code>3 directories, 1 </code><code>file</code>

<code># 3個目錄WEB-INF classes lib 1個檔案 </code>

<code># 檔案内容:172.16.10.122</code>

<code>&lt;%@ page language=</code><code>"java"</code> <code>%&gt;</code>

<code>&lt;html&gt;</code>

<code>  </code><code>&lt;</code><code>head</code><code>&gt;&lt;title&gt;TomcatA&lt;</code><code>/title</code><code>&gt;&lt;</code><code>/head</code><code>&gt;</code>

<code>  </code><code>&lt;body&gt;</code>

<code>    </code><code>&lt;h1&gt;&lt;font color=</code><code>"red"</code><code>&gt;TomcatA.example.com&lt;</code><code>/h1</code><code>&gt;</code>

<code>    </code><code>&lt;table align=</code><code>"centre"</code> <code>border=</code><code>"1"</code><code>&gt;</code>

<code>      </code><code>&lt;</code><code>tr</code><code>&gt;</code>

<code>        </code><code>&lt;td&gt;Session ID&lt;</code><code>/td</code><code>&gt;</code>

<code>    </code><code>&lt;% session.setAttribute(</code><code>"example.com"</code><code>,</code><code>"example.com"</code><code>); %&gt;</code>

<code>        </code><code>&lt;td&gt;&lt;%= session.getId() %&gt;&lt;</code><code>/td</code><code>&gt;</code>

<code>      </code><code>&lt;</code><code>/tr</code><code>&gt;</code>

<code>        </code><code>&lt;td&gt;Created on&lt;</code><code>/td</code><code>&gt;</code>

<code>        </code><code>&lt;td&gt;&lt;%= session.getCreationTime() %&gt;&lt;</code><code>/td</code><code>&gt;</code>

<code>     </code><code>&lt;</code><code>/tr</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>/table</code><code>&gt;</code>

<code>  </code><code>&lt;</code><code>/body</code><code>&gt;</code>

<code>&lt;</code><code>/html</code><code>&gt;</code>

<code># 檔案内容:172.16.10.133</code>

<code>  </code><code>&lt;</code><code>head</code><code>&gt;&lt;title&gt;TomcatB&lt;</code><code>/title</code><code>&gt;&lt;</code><code>/head</code><code>&gt;</code>

<code>    </code><code>&lt;h1&gt;&lt;font color=</code><code>"blue"</code><code>&gt;TomcatB.example.com&lt;</code><code>/h1</code><code>&gt;</code>

<code>第四步:啟動tomcat</code>

<code>catalina.sh start</code>

<a href="http://guoting.blog.51cto.com/attachment/201410/27/8886857_1414410274w7uZ.png" target="_blank"></a>

<a href="http://guoting.blog.51cto.com/attachment/201410/27/8886857_1414410278jFR9.png" target="_blank"></a>

<a href="http://guoting.blog.51cto.com/attachment/201410/27/8886857_1414410284ZXe0.png" target="_blank"></a>

<code>目标主機:172.16.10.1</code>

<code>第一步:安裝Ngnix</code>

<code>### 可以使用源碼編譯安裝,也可使用rpm方式安裝(需配置好epel源)這裡使用 rpm方式安裝。</code>

<code>yum </code><code>install</code> <code>ngnix -y</code>

<code>第二步:配置Ngnix前端排程</code>

<code>### cat /etc/nginx/conf.d/default.conf 主要配置如下:</code>

<code>upstream www.tomcat.org {</code>

<code>    </code><code>ip_hash;</code>

<code>    </code><code>server 172.16.10.122:8080;</code>

<code>    </code><code>server 172.16.10.133:8080;</code>

<code>}</code>

<code>server {</code>

<code>    </code><code>listen       80;</code>

<code>    </code><code>server_name  www.tomcat.org;</code>

<code>    </code><code>location / {</code>

<code>        </code><code>proxy_pass http:</code><code>//www</code><code>.tomcat.org;</code>

<code>        </code><code>index  index.jsp index.html index.htm;</code>

<code>    </code><code>}</code>

<a href="http://guoting.blog.51cto.com/attachment/201410/27/8886857_1414410286vaZ1.png" target="_blank"></a>

這是通過ip_hash排程方法實作的。思考如下問題:這樣做還能減輕後端tomcat的壓力嗎??

解決辦法:将session資訊在每個Tomcat節點上儲存一份,做成tomcat叢集(session叢集)。

實作架構不變。

<code>### 在 /usr/local/tomcat/conf/server.xml 的&lt;Host&gt; &lt;/Host&gt;内部以下内容添加:</code>

<code>目标主機:172.16.10.122 172.16.10.133</code>

<code>&lt;Cluster className=</code><code>"org.apache.catalina.ha.tcp.SimpleTcpCluster"</code>

<code>         </code><code>channelSendOptions=</code><code>"8"</code><code>&gt;</code>

<code>  </code><code>&lt;Manager className=</code><code>"org.apache.catalina.ha.session.DeltaManager"</code>

<code>           </code><code>expireSessionsOnShutdown=</code><code>"false"</code>

<code>           </code><code>notifyListenersOnReplication=</code><code>"true"</code><code>/&gt;</code>

<code>  </code><code>&lt;Channel className=</code><code>"org.apache.catalina.tribes.group.GroupChannel"</code><code>&gt;</code>

<code>    </code><code>&lt;Membership className=</code><code>"org.apache.catalina.tribes.membership.McastService"</code>

<code>                </code><code>address=</code><code>"228.10.10.14"</code>

<code>                </code><code>port=</code><code>"45564"</code>

<code>                </code><code>frequency=</code><code>"500"</code>

<code>                </code><code>dropTime=</code><code>"3000"</code><code>/&gt;</code>

<code>    </code><code>&lt;Receiver className=</code><code>"org.apache.catalina.tribes.transport.nio.NioReceiver"</code>

<code>              </code><code>address=</code><code>"172.16.10.122/172.16.10.133"</code>  

<code>               </code><code># 注意此選項預設是auto,這裡需要配置。每個節點配置自己的ip位址,</code>

<code>               </code><code># 意思是接收session心跳消息的位址</code>

<code>              </code><code>port=</code><code>"4000"</code>

<code>              </code><code>autoBind=</code><code>"100"</code>

<code>              </code><code>selectorTimeout=</code><code>"5000"</code>

<code>              </code><code>maxThreads=</code><code>"6"</code><code>/&gt;</code>

<code>    </code><code>&lt;Sender className=</code><code>"org.apache.catalina.tribes.transport.ReplicationTransmitter"</code><code>&gt;</code>

<code>      </code><code>&lt;Transport className=</code><code>"org.apache.catalina.tribes.transport.nio.PooledParallelSender"</code><code>/&gt;</code>

<code>    </code><code>&lt;</code><code>/Sender</code><code>&gt;</code>

<code>    </code><code>&lt;Interceptor className=</code><code>"org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"</code><code>/&gt;</code>

<code>    </code><code>&lt;Interceptor className=</code><code>"org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"</code><code>/&gt;</code>

<code>  </code><code>&lt;</code><code>/Channel</code><code>&gt;</code>

<code>  </code><code>&lt;Valve className=</code><code>"org.apache.catalina.ha.tcp.ReplicationValve"</code>

<code>         </code><code>filter=</code><code>""</code><code>/&gt;</code>

<code>  </code><code>&lt;Valve className=</code><code>"org.apache.catalina.ha.session.JvmRouteBinderValve"</code><code>/&gt;</code>

<code>  </code><code>&lt;Deployer className=</code><code>"org.apache.catalina.ha.deploy.FarmWarDeployer"</code>

<code>            </code><code>tempDir=</code><code>"/tmp/war-temp/"</code>

<code>            </code><code>deployDir=</code><code>"/tmp/war-deploy/"</code>

<code>            </code><code>watchDir=</code><code>"/tmp/war-listen/"</code>

<code>            </code><code>watchEnabled=</code><code>"false"</code><code>/&gt;</code>

<code>  </code><code>&lt;ClusterListener className=</code><code>"org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"</code><code>/&gt;</code>

<code>  </code><code>&lt;ClusterListener className=</code><code>"org.apache.catalina.ha.session.ClusterSessionListener"</code><code>/&gt;</code>

<code>&lt;</code><code>/Cluster</code><code>&gt;</code>

<code>### 在相應應用程式的web.xml中添加&lt;distributable\&gt;; 也可以全局添加</code>

<code>cp</code> <code>/usr/local/tomcat/webapps/test/WEB-INF/web</code><code>.xml </code><code>/usr/local/tomcat/webapps/test/WEB-INF/</code>

<code># 編輯 /usr/local/tomcat/webapps/test/WEB-INF/web.xml 在 &lt;web-app&gt; 中添加:</code>

<code>&lt;distributable/&gt;;</code>

這裡主要是使用輪詢排程,不使用ip_hash排程。隻需将配置檔案中的ip_hash去掉即可。

配置完成後,重新開機tomcat即可。

<a href="http://guoting.blog.51cto.com/attachment/201410/27/8886857_1414410288Q76e.png" target="_blank"></a>

從結果中可以知道,實作了session保持。

<a href="http://guoting.blog.51cto.com/attachment/201410/27/8886857_1414410296CqcY.png" target="_blank"></a>

<a href="http://guoting.blog.51cto.com/attachment/201410/27/8886857_1414410298OIXr.png" target="_blank"></a>

思考如下問題? 這種方式的session保持是通過每個節點儲存一份session資訊,但是:但叢集節點很多時,這些seesion資訊可能是很大級别的。此時,各個節點之間的session複制反而成了影響系統性能的瓶頸。

解決辦法: 使用session伺服器,将seession資訊統一儲存到緩存伺服器中。

試驗拓撲圖如下:

<a href="http://guoting.blog.51cto.com/attachment/201410/27/8886857_1414410299Oclw.png" target="_blank"></a>

tomcat實作此功能要借助于msm(Memcached-Session-Management)子產品可以實作。需要下載下傳jar包, javolution、memcached-session-manager-tc7、spymemcached、memcached-session-manager、msm-javolution-serializer 。将這些jar包拷貝到/usr/local/tomcat/lib/目錄下,支援msm功能。這些包可以再Google Code中找到。

下載下傳時要注意:要與tomcat的版本相對應。

<code>作業系統:CentOS 6.5</code>

<code>目标主機:172.16.10.1 172.16.10.9</code>

<code>yum </code><code>install</code> <code>memcached -y</code>

<code>service memcached start</code>

<code>## 在試驗一的基礎上,繼續配置</code>

<code>&lt;Context path=</code><code>"/test"</code> <code>docBase=</code><code>"/usr/local/tomcat/webapps/test/"</code> <code>reloadable=</code><code>"true"</code><code>&gt;</code>

<code>         </code><code>&lt;Manager className=</code><code>"de.javakaffee.web.msm.MemcachedBackupSessionManager"</code>

<code>                  </code><code>memcachedNodes=</code><code>"n1:172.16.10.9:11211,n2:172.16.10.1:11211"</code>

<code>                  </code><code>failoverNodes=</code><code>"n1"</code>

<code>                  </code><code>requestUriIgnorePattern=</code><code>".*\.(ico|png|gif|jpg|css|js)$"</code>

<code>              </code><code>transcoderFactoryClass=</code><code>"de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory"</code>

<code>         </code><code>/&gt;        </code>

<code>&lt;</code><code>/Context</code><code>&gt;</code>

結果示例:

<a href="http://guoting.blog.51cto.com/attachment/201410/27/8886857_1414410301O467.png" target="_blank"></a>

對于前端排程器也可使用apache和haproxy反向代理器。

tomcat + memcacahed + nginx + mysql + nfs 實作jsp格式的論壇。試驗拓撲圖如下:

<a href="http://guoting.blog.51cto.com/attachment/201410/27/8886857_1414410306QEXf.png" target="_blank"></a>

<code>#### 配置 NFS 伺服器</code>

<code>mkdir</code> <code>/tomcatdata</code>

<code># 編輯 /etc/exports,添加:</code>

<code>/tomcatdata</code> <code>172.16.0.0</code><code>/16</code><code>(rw)</code>

<code>service nfs start</code>

<code>### 配置 mysql</code>

<code>yum </code><code>install</code> <code>mysql-server -y </code>

<code>servive mysqld start</code>

<code>mysql&gt; CREATE DATABASE jcenter1;</code>

<code>mysql&gt; GRANT ALL ON jcenter1.* TO jcenter@</code><code>'172.16.%.%'</code> <code>IDENTIFIED BY </code><code>'jcenter'</code><code>;</code>

<code>mysql&gt; FLUSH PRIVILEGES;</code>

<code>目标主機: 172.16.10.122 172.16.10.133</code>

<code>第一步:搭建站點</code>

<code>mkdir</code> <code>/tomcat/webapps/</code>

<code>mount</code> <code>-t nfs 172.16.10.1:</code><code>/tomcatdata</code> <code>/tomcat/webapps/</code>

<code># 擷取jsp程式 JavaCenter_Home_2.0_GBK.tar.bz2 java程式代碼</code>

<code>tar</code> <code>-xf JavaCenter_Home_2.0_GBK.</code><code>tar</code><code>.bz2 -C </code><code>/tomcat/webapps/</code>

<code>cd</code> <code>/tomcat/webapps/</code>

<code>ln</code> <code>-sv JavaCenter_Home_2.0_GBK jct</code>

<code># 配置 JavaCenter:/tomcatdata/jct/config.properties</code>

<code># 主要修改以下:</code>

<code># 資料庫伺服器位址(一般為本地localhost或127.0.0.1)</code>

<code>dbHost = 172.16.10.1</code>

<code># 資料庫伺服器端口号(一般為3306)</code>

<code>dbPort = 3306</code>

<code># 資料庫使用者名</code>

<code>dbUser = jcenter</code>

<code># 資料庫密碼</code>

<code>dbPw = jcenter</code>

<code># 資料庫名</code>

<code>dbName = jcenter1</code>

<code>第二步:配置tomcat</code>

<code>&lt;Host name=</code><code>"www.tomcat.org"</code>  <code>appBase=</code><code>"/tomcat/webapps"</code>

<code>      </code><code>unpackWARs=</code><code>"true"</code> <code>autoDeploy=</code><code>"true"</code><code>&gt;</code>

<code>   </code><code>&lt;Context path=</code><code>"/jct"</code> <code>docBase=</code><code>"jct"</code> <code>/&gt;</code>

<code>       </code><code>&lt;Manager className=</code><code>"de.javakaffee.web.msm.MemcachedBackupSessionManager"</code>

<code>                </code><code>memcachedNodes=</code><code>"n1:172.16.10.9:11211,n2:172.16.10.1:11211"</code>

<code>                </code><code>failoverNodes=</code><code>"n2"</code>

<code>                </code><code>requestUriIgnorePattern=</code><code>".*\.(ico|png|gif|jpg|css|js)$"</code>

<code>        </code><code>transcoderFactoryClass=</code><code>"de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory"</code>

<code>       </code><code>/&gt;            </code>

<code>    </code><code>&lt;</code><code>/Context</code><code>&gt;</code>

<code>&lt;</code><code>/Host</code><code>&gt;</code>

<code># 當然msm所依賴的jar包要拷貝到對應的目錄下</code>

<code>重新啟動tomcat.</code>

<a href="http://guoting.blog.51cto.com/attachment/201410/27/8886857_14144103091aZ0.png" target="_blank"></a>

<a href="http://guoting.blog.51cto.com/attachment/201410/27/8886857_1414410314IxUO.png" target="_blank"></a>

<a href="http://guoting.blog.51cto.com/attachment/201410/27/8886857_1414410319ex7R.png" target="_blank"></a>

<a href="http://guoting.blog.51cto.com/attachment/201410/27/8886857_1414410323WgcE.png" target="_blank"></a>

至此,配置基本完成。

本文轉自 羊木狼 51CTO部落格,原文連結:http://blog.51cto.com/guoting/1568583,如需轉載請自行聯系原作者