1. 程式人生 > >web專案叢集時共享session方案實踐。

web專案叢集時共享session方案實踐。

web專案在叢集負載均衡時一個主要的問題就是如何共享session 。  讓多臺機器之間的資料統一。  不能出現使用者在A機器上面登入成功, 之後訪問到B機器的時候提示未登入。

如果使用nginx來實現負載均衡, 它提供了一種hash ip的策略, 將同一個ip的每次請求都轉發到同一臺伺服器上面。   這樣的話, 就不需要共享session了。  但是這樣的壞處是無法讓負載更好的均衡, 可能出現某些機器負載高,有些機器負載低的情況。  所以還是不建議使用這種方式。

下面想到一種負載均衡的思路,就是使用專門一臺快取伺服器來儲存session資訊。  

無論在哪臺伺服器登入之後,都將使用者的登入資訊儲存在快取伺服器中。 然後給客戶端設定一個cookie來標識使用者的身份。 來取代jsessionid

快取伺服器可以使用membercached  /  redis 等記憶體資料庫。  

由於前幾天剛好學習了hessian 。 所以決定自己來實現一個快取伺服器 , 並提供介面給其他專案使用。(只簡單的提供了put、get兩個方法)

例項場景

專案1  : cookie-server   快取伺服器

專案2  :cookie-web     普通web專案,實現了登入用例

首先來完成cookie-server (maven)專案。

1、建立cookie-cacheserver-client模組, 用於定義Hessian介面。  一些公共的VO / DTO 物件。

首先定義用於存取資料的介面 CacheService

package cookie.chacheserver.client;

public interface CacheService {

	Object getByKey(Object key) ;
	
	boolean put(Object key ,  Object value) ;
	
}

然後定義一個LoginUser物件,來表示使用者登入資訊
package cookie.chacheserver.client;

import java.io.Serializable;

public class LoginUser implements Serializable {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = -2958174180520979633L;
	private String userId ;
	private String nick  ;
	
	public String getUserId() {
		return userId;
	}
	public void setUserId(String userId) {
		this.userId = userId;
	}
	public String getNick() {
		return nick;
	}
	public void setNick(String nick) {
		this.nick = nick;
	}
	
}

ok 。 cookie-cacheserver-client 模組完成

2、建立cookie-cacheserver-service模組 , 實現cookie-cacheserver-client模組中定義的service

package cookie.cacheserver.service;

import java.util.concurrent.ConcurrentHashMap;

import cookie.chacheserver.client.CacheService;

public class CacheServiceImpl implements CacheService{
	
	private static final ConcurrentHashMap<Object, Object> cacheMap = 
			new ConcurrentHashMap<Object, Object>() ;

	
	public Object getByKey(Object key) {
		return cacheMap.get(key) ;
	}

	public boolean put(Object key, Object value) {
		cacheMap.put(key, value) ;
		return cacheMap.containsKey(key) ;
	}

	
	
}

cookie-cacheserver-service 完成。

3、 建立cookie-cacheserver模組, 來當做 cacheserver的web模組。  來提供服務。

主要來配置hessian通過web的方式啟動。  程式碼不貼了。  可以直接下載專案來看。  專案在文章最後會給出下載連結。

專案結構如圖:


快取伺服器已經完成了 。 

接下來做一個web專案。  該專案有主要幾個功能{

1、通過login.jsp頁面進行登入, 通過Login sevlet完成。

       Login Servlet 內判斷使用者Id與nick是否符合要求,如果符合要求,就登入成功,並將使用者資訊儲存到快取伺服器上。  然後給瀏覽器設定一個cookie。 將使用者登入標識存入cookie  , 然後跳轉到 index servlet 。 在index servlet中會根據使用者cookie中的標識去快取伺服器取出使用者的登入資訊。  然後將資訊展示在index.jsp中。

}

專案就隨便取了個名字cookie-weba , 專案結構如下


專案程式碼下載地址:專案原始碼

兩個專案已經打成war包了。 可以部署到tomcat直接執行。  下載地址:war包

注意:在部署時,最好是將cookie-cacheserver.war 與 cookie-weba.war 分開部署到伺服器上面。  

我是在同一臺機器上面測試了。  使用了三個tomcat , 可以將每個tomcat的埠設定成不同 。 

tomcat1  使用8080埠來啟動 cookie-cacheserver.war

tomcat2 使用8082埠來啟動cookie-weba.war

tomcat3 使用8083埠,也來啟動cookie-weba.war

登入成功後。 訪問tomcat3的專案。 http://localhost:8083/cookie-webb/index.do  , 如果沒有登入, 將會跳轉到login.jsp頁面 。 如果已經登入,就會到index.jsp展示登入資訊。

登入規則是:nike必須以userId字串為開頭。  nick.startsWith(id)