這裏的雲計算多租戶是指一個web應用,多個數據庫。每個租戶對應着一個數據庫。 java
數據庫方面,簡單分爲一個基本庫,記錄着基本信息與租戶的信息,還有租戶數據庫配置信息。N個租戶庫,這N個租戶庫,可能分佈在一臺服務器上,也可能分佈在N臺服務器上,可能二者兼有。因此在基本庫中的租戶的數據庫所在服務器信息(下面稱爲數據源信息)與數據庫信息。 mysql
Play的數據源配置,在conf/application.conf中,如:web
jpa.dialect=org.hibernate.dialect.MySQLDialect db.url=jdbc:mysql://basedbip:3306/pop?autoReconnect=true&useUnicode=true&characterEncoding=utf-8 db.driver=com.mysql.jdbc.Driver db.user=root db.pass=root db=pop db_01.url=jdbc:mysql://anotherdbip:3306/pop?autoReconnect=true&useUnicode=true&characterEncoding=utf-8 db_01.driver=com.mysql.jdbc.Driver db_01.user=root db_01.pass=root db_01=pop01
由於Play是無狀態的輕框架,因此要保持某個租戶下面的單個用戶一次會話中不一樣時間不一樣連接請求的庫信息同樣,就必須有相應的切庫邏輯。同時須要有必要的切庫憑證數據。 redis
咱們能夠在登錄的時候,將用戶的登錄信息與之對應租戶的數據庫信息封裝成一個對象,以該登錄信息對象爲value,用戶本次會話的sessionid爲Key,存放在緩存之中,如redis。 sql
每次請求來臨的時候,根據sessionid,從緩存中獲取登錄信息對象,若是沒有,則可認爲該用戶沒有登錄,將其指向登錄頁面(這裏須要設定白名單,將登錄的連接排除)。 若是有對象,則將數據庫信息取出,利用setCurrentConfigName切換數據源數據庫
JPA.setCurrentConfigName(dbconfigname);
利用user切換數據庫緩存
JPA.em().createNativeQuery("use "+dbname).executeUpdate();
從而達到了切庫功能,在這個地方,不能使用@before註解,由於play框架會對請求參數中的對象參數數據進行JPA查詢分裝,而這個處理時機在處理@before以前,詳細的請參考: Play 1.x框架學習之七:多數據庫切換與源碼修改 ( Databases Switch And Modify Source Code) 服務器
若是修改Play源碼以後,就可就行自由切庫。 session
有一個地方須要注意的是,若是用戶表數據不是存放在基礎庫而是在租戶庫中,這時候就須要一個原始的切庫憑據(若是沒有,則沒法到相應的租戶庫獲取用戶數據進行登陸校驗),這裏提供兩種解決方法,一是能夠在登錄的時候讓用戶多填寫一個與租戶相關的憑證,也能夠根據不一樣的租戶,提供不一樣的url入口,來達到相同的結果,這樣的用戶體驗較第一種好。
app