標籤:
首先,我們明確目標,做Tomcat叢集的目的是為了提供更高的負載能力,把訪問均攤到不同的伺服器上。
直觀地來說,就是訪問test.localhost.com時,nignx會隨機將訪問請求分發到tomcat1,tomcat2,為了保持session同步,使用memcached去管理session。
為此我們準備的配置清單是: windows x 1 nginx x 1 memcached x 1 tomcat x 2 mysql x 1
部署的架構圖如下:
首先,我準備了一個Java Web項目、tomcat 6、jdk6。
Step1
先將項目部署到tomcat,因為要用到兩個tomcat,當然地要把其中一個tomcat的連接埠修改一下。
Step2
下載安裝nginx,http://kevinworthington.com/nginx-for-windows/。
在host裡準備一個測試網域名稱。開啟C:\Windows\System32\drivers\etc\host, 添加網域名稱映射
127.0.0.1 test.local.com
開啟nginx的根目錄,在conf裡添加test.conf,內容大概如下。
upstream test.local.com { server 127.0.0.1:8080 weight=1; server 127.0.0.1:8083 weight=1; } server { listen 80; server_name test.local.com; error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } root /data/projects/ycp/bill; # - rewrite: if( path ~ "^/assets/(.*)" ) goto "/public/assets/$1" # location ~ ^/static/assets/(.*)$ # { #alias /data/projects/payment/web/public/assets/$1; # access_log off; # #expires 3d; # } location / { index index.html index.htm index.jsp; } location ~ .* { # proxy_pass_header Server; proxy_set_header Host $http_host; # proxy_redirect off; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Scheme $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; add_header Pragma "no-cache"; proxy_pass http://test.local.com; } rewrite ^/admin/?$ /admin/login redirect; # for rewrite rewrite ^/(channel|admin|mobile|api|web)/(.*)$ /public/index.php/$2 last; #redirect to mobile wap #rewrite ^$ /m redirect; #rewrite ^/$ /mobile/user redirect; }
然後將test.conf引入到nginx.conf裡面
include ycp-test.conf;
此時,我們可以啟動nginx和tomcat,訪問http://test.local.com,試試效果。
Step3
上一步,我們配好了nginx叢集,但是tomcat的session還沒有集到一起。接下來我們會用memcached管理session。
下載安裝memcached。http://blog.couchbase.com/memcached-windows-64-bit-pre-release-available
點擊這裡直接下載
ps: memcached官網
解壓放某個盤下面,比如在c:\memcached
在CMD下輸入 “c:\memcached\memcached.exe -d install” 安裝。
再輸入:“c:\memcached\memcached.exe -d start” 啟動。NOTE: 以後memcached將作為windows的一個服務每次開機時自動啟動。這樣伺服器端已經安裝完畢了。
啟動時可添加其他參數
-p 監聽的連接埠
-l 串連的IP地址, 預設是本機
-d start 啟動memcached服務
-d restart 重起memcached服務
-d stop|shutdown 關閉正在啟動並執行memcached服務
-d install 安裝memcached服務
-d uninstall 卸載memcached服務
-u 以的身份運行 (僅在以root啟動並執行時候有效)
-m 最大記憶體使用量,單位MB。預設64MB
-M 記憶體耗盡時返回錯誤,而不是刪除項
-c 最大同時串連數,預設是1024
-f 塊大小增長因子,預設是1.25
-n 最小分配空間,key+value+flags預設是48
-h 顯示協助
另外,我們可以用telnet操作memcached
windows如果本來沒有telnet命令的話,可以在控制台-程式和功能-啟動或關閉Windows功能裡面勾選telnet用戶端
telnet 127.0.0.1 11211 stats
可得到描述Memcached伺服器運行情況的參數。如:
ps:網上給出的一些參數解釋
- pid: memcached服務進程的進程ID
- uptime: memcached服務從啟動到當前所經過的時間,單位是秒。
- time: memcached伺服器所在主機當前系統的時間,單位是秒。
- version: memcached組件的版本。這裡是我當前使用的1.2.6。
- pointer_size:伺服器所在主機作業系統的指標大小,一般為32或64.
- curr_items:表示當前緩衝中存放的所有緩衝對象的數量。不包括目前已經從緩衝中刪除的對象。
- total_items:表示從memcached服務啟動到目前時間,系統儲存過的所有對象的數量,包括目前已經從緩衝中刪除的對象。
- bytes:表示系統儲存緩衝對象所使用的儲存空間,單位為位元組。
- curr_connections:表示當前系統開啟的串連數。
- total_connections:表示從memcached服務啟動到目前時間,系統開啟過的串連的總數。
- connection_structures:表示從memcached服務啟動到目前時間,被伺服器分配的串連結構的數量,這個解釋是協議文檔給的,具體什麼意思,我目前還沒搞明白。
- cmd_get:累積擷取資料的數量,這裡是3,因為我測試過3次,第一次因為沒有序列化對象,所以擷取資料失敗,是null,後邊有2次是我用不同對象測試了2次。
- cmd_set:累積儲存資料的樹立數量,這裡是2.雖然我儲存了3次,但是第一次因為沒有序列化,所以沒有儲存到緩衝,也就沒有記錄。
- get_hits:表示擷取資料成功的次數。
- get_misses:表示擷取資料失敗的次數。
- evictions:為了給新的資料項目釋放空間,從緩衝移除的緩衝對象的數目。比如超過緩衝大小時根據LRU演算法移除的對象,以及到期的對象。
- bytes_read:memcached伺服器從網路讀取的總的位元組數。
- bytes_written:memcached伺服器發送到網路的總的位元組數。
- limit_maxbytes:memcached服務緩衝允許使用的最大位元組數。這裡為67108864位元組,也就是是64M.與我們啟動memcached服務設定的大小一致。
- threads:被請求的背景工作執行緒的總數量。
我們還可以用Java操作memcached
首先下載相關的jar包 Memcached-Java-Client
然後編寫用戶端
package net.bill.commons.util; import org.springframework.stereotype.Component; import com.danga.MemCached.MemCachedClient; import com.danga.MemCached.SockIOPool; @Component public class OCSUtil { private static OCSUtil session; public static OCSUtil getSession() { if (session == null) { synchronized(OCSUtil.class){ if(session==null){ session=new OCSUtil(); } } } return session; } /** * memcached用戶端 */ private MemCachedClient memcache = null; public OCSUtil(){ if (memcache == null) { memcache =new MemCachedClient(); String [] addr ={"127.0.0.1:11211"}; Integer [] weights = {3}; SockIOPool pool = SockIOPool.getInstance(); pool.setServers(addr); pool.setWeights(weights); pool.setInitConn(5); pool.setMinConn(5); pool.setMaxConn(200); pool.setMaxIdle(1000*30*30); pool.setMaintSleep(30); pool.setNagle(false); pool.setSocketTO(30); pool.setSocketConnectTO(0); pool.initialize(); } } public void setAttribute(String key, Object value){ memcache.set(key, value, 1000); } public Object getAttribute(String key){ return memcache.get(key); } public void removeAttribute(String key){ memcache.delete(key); } }
再編寫測試代碼
package net.test.modules; import net.bill.commons.util.OCSUtil; import net.bill.modules.pojo.User; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; public class OCSTest extends BaseTest { @Autowired OCSUtil session; /** * 通過spring注入獲得用戶端 */ @Test public void test1() { session.setAttribute("user", new User("13355558888")); System.out.println(session.getAttribute("user")); } /** * 通過靜態方法獲得用戶端(單例) */ @Test public void test2() { OCSUtil session = OCSUtil.getSession(); System.out.println(session.getAttribute("user")); } }
要注意的是,User類必須實現Serializable介面,進行序列化。因為memcached的value類型是String。
接下來我要用memcached替換tomcat的session
在這之前,可以先看一下memcached-session-manager,或中文翻譯的memcached-session-manager配置
session的序列化方案官方推薦的有4種
- kryo-serializer
- javolution-serializer
- xstream-serializer
- flexjson-serializer
我使用的是最簡單的一種,就是javolution-serializer。這個只要Java中存入session的對象實現Serializable就可以了。
然後下載以下jar包,並放在tomcat\lib\裡
- memcached-session-manager-1.8.3.jar
- memcached-session-manager-tc6-1.8.3.jar
- spymemcached-2.11.1.jar
在tomcat\conf\context.xml, 裡加上以下配置:
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager" memcachedNodes="n1:127.0.0.1:11211" username="root" password="" sticky="false" sessionBackupAsync="false" lockingMode="uriPattern:/path1|/path2" requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$" />
啟動tomcat,可以看見日誌輸出以下資訊:
資訊: -------- - MemcachedSessionService finished initialization: - sticky: false - operation timeout: 1000 - node ids: [n1] - failover node ids: [] - storage key prefix: null --------
Step4
現在可以測一下是否成功。
- 啟動tomcat1
- 訪問test.local.com,並登入
- 啟動tomcat2,關閉tomcat1
- 查看登入資訊是否還在
測試通過的話,就基本上沒問題了。
windows+nginx+memcached+tomcat做負載平衡