Session Management in Tomcat on Azure

想把Web應用程式搬上雲端,且想運用到雲端的優勢(這是重點),至少必須做出三個抉擇, Language,Database,Session Manager,
本文討論如何使用Table Storage Service或是memcached作為Session Manager

Session Management in Tomcat on Azure

 

/黃忠成

 

 

Web 應用程式上Azure的三部曲

 

  想把Web應用程式搬上雲端,且想運用到雲端的優勢(這是重點),至少必須做出三個抉擇。

 

使用的資料庫

 

  傳統的SQL Server、Oracle類型的資料庫本身就不適用於雲端環境,更確切的說,硬搬上去也無法享用到雲端平台的優勢!

因此應用程式在搬上雲端前,得先選擇使用哪個可享用雲端平台優勢的資料庫。以Windows Azure平台而言,

Table Storage Service及SQL Azure都是選項,然而以中大型應用程式而言,SQL Azure是較為妥善的選擇。

 

PS: 如果想把SQL Lite或是Oracle搬上Windows Azure也不是不可能,但就算搬上去了,也只是把原本放在本地端的資料庫系統搬到Windows Azure平台上而已,

無法享用雲端平台的無限運算資源及空間優勢。

 

使用的程式語言

 

  接著必須選擇的是使用的程式語言,這點在Windows Azure平台上沒有太大問題,因為只要能夠跑在Windows OS下的程式語言,在Windows Azure上理論上都能跑起來。

 

Session

 

   在雲端平台中,應用程式並不受限於只執行在一台電腦(VM)中,開發者可以依據需求設定多台電腦(VM)同時執行同一個應用程式,就Web應用程式而言,

這時前端會有個Load Balance機制,平均的將訪客分散到這些應用程式,以達到負載平衡的目的。

   在常用的Round-Robin手法(Windows Azure目前採用這個),當應用程式同時執行於兩個電腦(VM)中,第一個訪客會被導向A電腦(VM),

第二個訪客則會被導向至B電腦(VM)。在這種情況下,Web應用程式常運用的Session技術就會受到考驗,因為多數的Session技術後端的儲存體多半是記憶體,

以前例而言,第一個訪客被導向至A電腦(VM),而程式在Session存入資料,此時該資料是存在於A電腦(VM)的記憶體中,稍後訪客再進行下一步動作時,

會因為Round-Robin機制被導向於B電腦(VM),而B電腦(VM)記憶體中並不存在這些Session資料,此時就會發生Session遺失(其實應該說,根本就不存在)的問題。

要解決這個問題,就得選擇記憶體以外的Session的儲存體,在Windows Azure中可選用的非記憶體Session儲存體很多,例如: ASP.NET Caching Services、

AppFabric Caching、Storage Services、SQL Azure。但對於Java Web應用程式,選擇就只剩下Storage Services、SQL Azure,

因為ASPNET Caching Services與AppFabric Caching並未提供方便的API,Java用起來會相當吃力。

 不過先前一開始就有提到,只要是能夠跑在Windows OS上的應用程式,在Windows Azure裡理論上都是跑得起來的,這也代表著除了

Storage Services、SQL Azure外,Java Web應用程式還有memcached可以使用。

 

 

處理Session-Using Table Storage Service

 

   這其實不難,首先請至以下網址下載相關的Session Manager。

 

https://github.com/atomus/TomcatAzureSessionManager

 

這個Session Manager可以讓Tomcat將Session儲存在Table Storage Services中,開發者要做的就只是把這個lib\deploy目錄下的所有.jar

複製到Tomcat的lib中,接著修改conf\context.xml,設定Session Manager。

 

<Context>

……………….

    <Manager className="uk.co.atomus.session.manager.AtomusManager"

accountKey="<your account key>"

            accountName="<your account>"

            tableName="tomcatSessions"

            partitionKey="AzureSessionDemo"/>

…………….

</Context>

這樣一來,就能讓Tomcat使用Table Storage Service作為Session的儲存體,也就能解決因為多台電腦(VM)執行同一個應用程式而導致的Session遺失問題。

PS: 這個TomcatAzureSessionManager只能運作在真正的Table Storage Service下,也就是說不能跑在Storage模擬器哦。

 

 

處理Session-Using Memcached

 

   除了使用Table Storage Services外,在Windows Azure平台中也可以選用memcached這個有名的Cache Services,首先必須要取得memcached的

Windows 64-bit版本(Windows Azure平台是64-bit的,要用32-bit也可以,但會受限於4GB限制),這可以由以下網址取得。

 

http://www.urielkatz.com/projects/memcached-win64/memcached-win64.zip

 

解開後會有兩個檔案,請於Eclipse開啟一個Windows Azure Project,將這兩個檔案放到approot目錄下,如圖1。

圖1

接著修改startup.cmd如下。

 

@REM *** This script will run whenever Windows Azure starts this role instance.

@REM *** This is where you can describe the deployment logic of your server, JRE and applications.

@REM *** See this project's samples directory for ready made examples.

 

echo deploy starting

cmd/c start memcached.exe d

exit 0

再修改run.cmd如下。

 

@REM Sample run script that exits to trigger a role recycle when java.exe stops running.

@REM If java.exe is not running to begin with, it will assume this is not a Java app deployment and keep it permanently alive.

@REM Customize this script to define your own monitoring and role recycle logic.

 

@ECHO OFF

util\whileproc.cmd memcached.exe

PS: run.cmd這個檔案很有趣,whileproc.cmd會監測memcached.exe是否在執行中,如果不在執行中的話,就代表VM有問題,

此時Windows Azure平台會進行容錯動作,例如重啟VM或是重新執行memcached。

 

最後調整Worker Role所使用的Port,Memcached預設是使用11211。

圖2

接下來只要把這個Azure Project產生的檔案部署到Windows Azure平台後,你就擁有一個跑在Windows Azure上的memcached Server。

最後是Tomcat部分的設定,要使用memcached做為Session Manager,必須到以下網址下載Session Manager。

 

http://code.google.com/p/memcached-session-manager/

 

注意,memcached-session-manager-1.6.1.jar及memcached-session-manager-tc7-1.6.1.jar都要下載並放到Tomcat的lib目錄下。完成後修改conf\context.xml如下。

 

<?xmlversion="1.0"encoding="UTF-8"?>

<Context>


……

   

    <ManagerclassName="de.javakaffee.web.msm.MemcachedBackupSessionManager"     memcachedNodes="b0ce6ff3018448c58bbf6c06c996d803.cloudapp.net:11211" requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"/>

…………

</Context>

memcachedNodes中要放置memcached server的URL,也就是先前部署至Windows Azure那個,完成後Build All並佈署到Windows Azure平台即可。

 

PS:Memcached支援cluster型態的環境,詳細請參照http://code.google.com/p/memcached-session-manager/

中的說明

 

完全部署後的結果如下圖

          不不

 

 

使用Internal Port

 

   Windows Azure平台上的應用程式可以選用兩種Port,一種是Public Port,可接受來自任何地方的連線,一種是Internal Port,只能夠接受來自Windows Azure平台內的連線,

以memcached Server來說,後者自然是比較適用的,因為只有我們的應用程式才會用到,在Eclipse可透過Endpoint頁面來設定Worker Role所使用的Port類別。

圖3