2012年8月9日 星期四

Tomcat Data Source 設定


Tomcat Data Source 設定

Data Source

DataSource的概念來自於當網站程式在操作資料庫之前,需要先跟資料庫取得一個連線,然後使用此連線做 query, insert, update, delete 等操作,操作完成後就將此連線歸還給資料庫。這種動作少的話還沒關係,但是一旦頻繁起來,因為跟資料庫取得連線需要時間,就會有效能的考量。所以就有人想說,何不先跟資料庫要求一定數量的連線,放在某個稱為Connection Pool的容器內,當網站程式需要操作資料庫時就跟此容器要求連線即可,用完時就將連線歸還予此容器,省卻每次都要跟資料庫要求連線的時間耗損,增進程式效率。
資料庫只要有JDBC的驅動程式,Tomcat就可以透過JDBC跟資料庫溝通,來取得連線。因此首先要確認使用的資料庫是否有實作JDBC的函式庫可以下載,接著就到$CATALINA_HOME\conf\server.xml 內設定 Global JNDI 資源,設定帳號,密碼,連線位置等相關資訊,最後到$CATALINA_HOME\conf\Catalina\localhost\你的Web應用程式名稱.xml,設定 ResourceLink,連結到剛剛設定的 Global JNDI 資源即可。

Tomcat 設定

server.xml

主要就是設定 server.xml 裡頭的 Global JNDI Resource
  1. <?xml version='1.0' encoding='utf-8'?>
  2. <Server port="8005" shutdown="SHUTDOWN">
  3. <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  4.  <!--略 --> 
  5.  <GlobalNamingResources>
  6.     <Resource name="cosmoDS" 
  7.       略..."/>
  8. </GlobalNamingResources>
  9.  <!--略 --> 
  10. </Server>
在 GlobalNamingResources 內定義一個 Resource 元素,Resource 內有一些值需要設定,簡易的設定如下
  1.     <Resource name="cosmoDS" 
  2.       auth="Container" 
  3.       description="Cosmo DB Connection JNDI"      
  4.       type="javax.sql.DataSource"
  5.       username="root"
  6.       password="mypass"
  7.       driverClassName="com.mysql.jdbc.Driver"
  8.       url="jdbc:mysql://127.0.0.1:3307/cosmo?zeroDateTimeBehavior=convertToNull&amp;noDatetimeStringSync=true" 
  9.       maxActive="100"
  10.       maxIdle="10"
  11.       maxWait="10000"/>
  • name: 資源名稱
  • auth: 填入"Container"
  • description: 說明
  • type: JNDI 型態,在這裡是DataSource,因此填入"javax.sql.DataSource"
  • username: DataBase登入帳號
  • password: DataBase登入密碼
  • driverClassName: JDBC Driver Class Name
  • url: 連線字串
  • maxActive: Pool 內所能容納 DB Connection 的最大數量,-1 表示無上限
  • maxIdle: Pool 內所能容納狀態為 idle 的 DB Connection 的最大數量,-1 表示無上限
  • maxWait: 等待 Connection 變為 available 的最大時間(ms),範例中為10秒,-1 表示無上限
簡易的設定會動,但是在實際上線時可能會遇到一些問題,最常見的就是 abandoned connection。當程式向 connection pool 要求一個 connection,使用完後卻沒有close,此 connection就會變為 abandoned ,它在 connection pool 內佔了一個位子,但是卻沒有程式可以再向 connection pool 要求此 connection 來用,假如這種情形持續發生,最後 abandoned connection 就會到達設定的 maxActive 數值,程式就當了,pool 內沒有任何一個 connection 可以再被使用。另外也有可以改善 performance 的方式,比如當 connection 放在 pool 過久時可以將它還給 DB,因為 DB 也是有設定連線數的上限;程式向 pool 要求 connection 時先測試此 connection 使否可用...等。
所以建議的設定為
  1. <Resource name="cosmoDS"
  2.           auth="Container"
  3.           description="Cosmo DB Connection JNDI"   
  4.           type="javax.sql.DataSource"
  5.           username="root"
  6.           password="mypass"
  7.           driverClassName="com.mysql.jdbc.Driver"
  8.           url="jdbc:mysql://127.0.0.1:3307/cosmo?zeroDateTimeBehavior=convertToNull&amp;noDatetimeStringSync=true"
  9.           maxActive="100"
  10.           maxIdle="10"
  11.           maxWait="10000"
  12.           initialSize="10"
  13.           removeAbandoned="true"
  14.           removeAbandonedTimeout="20"
  15.           logAbandoned="true"
  16.           validationQuery="select 1"
  17.           testOnBorrow="true"
  18.           testOnReturn="false"
  19.           timeBetweenEvictionRunsMillis="1800000"
  20.           minEvictableIdleTimeMillis="3600000"          
  21.           numTestsPerEvictionRun="10"          
  22.           testWhileIdle="true"
  23.           />
  • initialSize: 當 pool 初始化時會創建的 Connections 數量,預設為 0
  • removeAbandoned : 會刪除 abandoned Connections,預設為 0
  • removeAbandonedTimeout: 一個 Connection 變為 abandoned 後多少秒,此 Connection可以被移除
  • logAbandoned: log which code open connection but not close it, log in catalina.out
  • validationQuery: SQL query that can be used by the pool to validate connections before they are returned to the application
  • validationQueryTimeout: Timeout in seconds for the validation query to return. Default: -1 (infinite)
  • testOnBorrow: true or false: whether a connection should be validated using the validation query each time it is borrowed from the pool. Default: true
  • testOnReturn: true or false: whether a connection should be validated using the validation query each time it is returned to the pool. Default: false
  • timeBetweenEvictionRunsMillis: The number of milliseconds between consecutive runs of the evictor. Default: 30*60*1000 (30 minutes)
  • numTestsPerEvictionRun: The number of connections that will be checked for idleness by the evitor during each run of the evictor. Default: 3
  • minEvictableIdleTimeMillis: The idle time in milliseconds after which a connection can be removed from the pool by the evictor. Default: -1 (disabled)
  • testWhileIdle: true or false: whether a connection should be validated by the evictor thread using the validation query while sitting idle in the pool. Default: false

web application

假如你的web application名為 myapp,那麼就必須有一個相關的設定檔 $CATALINA_HOME/conf/Catalina/localhost/myapp.xml
  1. <Context path="/myapp" docBase="myapp" reloadable="true" crossContext="false">        
  2.     <ResourceLink name="myDS" global="cosmoDS" type="javax.sql.DataSource" />
  3. </Context>
ResourceLink 意思就是定一個此 web application 用的 resource,此 resource 連結自 global resource 的。在此例中就是定一個名為 myDS 的 resource ,連結自名為 cosmoDS 的 global resource, resource 的型態為 java.sql.DataSource。這樣的好處是數個不同 web applications 可以共用同一份 global resource 的設定,一旦 global resource 改了,所有 web applications 參考到的東西也就變了,你無需去每一個 web application 底下去修改其設定,這樣比較好維護,因為是有可能去修改其設定,比如說將資料庫由 mysql 改為 oralce ,或是資料庫搬家了, ip addresss 變了,套用上述的設定方式,你只需要去 server.xml 去修改 global resource 即可。

程式寫法

全部都設定好後,在程式中要取得connecton,寫法為
  1. Context inictx = new InitialContext();
  2. Context m_envctx = null;
  3. DataSource ds = null;
  4. Connection conn = null;
  5. Object tempObj = inictx.lookup("java:comp/env");
  6. if( null != tempObj)
  7.   m_envctx = (Context)tempObj;
  8. Object tempObj = null;
  9. try {
  10. 	tempObj = m_envctx.lookup("myDS");
  11. 	if(null!=tempObj)
  12. 	{
  13.   	  ds = (DataSource)tempObj;	  
  14. 	  conn = ds.getConnection();
  15. 	}				
  16.    } catch (Exception e) {
  17. 	e.printStackTrace();
  18.    }

MySQL 設定

  • 下載最新版的JDBC Driver
  • 將mysql-connector-java-x.x.x-bin.jar 放到 $CATALINA_HOME/lib/ 下
  • 設定 server.xml 的 Resource
  driverClassName="com.mysql.jdbc.Driver"
  url="jdbc:mysql://{ip address of DB}:{port number of DB}/{schema name}

MS SQL Sever 設定

  • 下載最新版的JDBC Driver
  • 將 sqljdbc4.jar 放到 $CATALINA_HOME/lib/ 下
  • 設定 server.xml 的 Resource
driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
url="jdbc:sqlserver://{ip address of DB};databaseName={schema name};" 

  • 查詢 MySQL 的 系統變數
 show variables;
其中 maxConnection 為可以允許的同時連線數量
  • 單純查詢指令為
 select @@global.max_connections; 
  • 修改指令為
  set @@global.max_connections = 1250;

沒有留言:

張貼留言