基於Nginx+Tomcat集羣的Session共享
(如果啓用了防火牆請開發配置中用到的端口)
在Linux環境下
第一步:下載對應的nginx 和 tomcat 包並解壓、安裝、配置(此步驟之前文章有提過,在此省略。。)
#user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; error_log logs/error.log info; pid logs/nginx.pid; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; #隱藏nginx的版本號 server_tokens off; #自定義日誌格式 log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' 'upstream_response_time $upstream_response_time $upstream_addr' '"$http_user_agent" "$http_x_forwarded_for"'; #access_log logs/access.log combined; #access日誌存放路徑和格式 access_log logs/access.log main; #提升文件傳輸性能 sendfile on; #tcp_nopush on; #設置客戶端能夠請求的單個文件大小 client_max_body_size 300m; keepalive_timeout 75; #proxy參數 #跟後端服務器連接的超時時間,發起握手等候響應超時時間 proxy_connect_timeout 5; #連接成功後,等候後端服務器的響應時間 proxy_read_timeout 600; #後端服務器數據回傳時間 proxy_send_timeout 600; #代理請求緩存區 proxy_buffer_size 16k; #同上,告訴nginx保存單個用的幾個buffer、最大用多空間 proxy_buffers 4 64k; #如果系統很忙時可以申請更大的proxy_buffers,官方推薦*2 proxy_busy_buffers_size 128k; proxy_temp_file_write_size 128k; #開啓壓縮功能 gzip on; gzip_min_length 1k; gzip_buffers 4 16k; gzip_http_version 1.1; gzip_comp_level 2; #壓縮級別從低到高1-9 gzip_types text/plain application/x-javascript text/css application/xml; gzip_vary on; #設置負載均衡池,此處是測試環境中的2個Tomcat的IP地址和端口號。 upstream tomcat_pool { server 192.168.1.198:8081; server 192.168.1.198:8082; } server { listen 80; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; location / { root /usr/local/nginx/html/dist; index views/index.html; } location /api/v1 { proxy_pass http://tomcat_pool; } #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } # proxy the PHP scripts to Apache listening on 127.0.0.1:80 # #location ~ \.php$ { # proxy_pass http://127.0.0.1; #} # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # #location ~ \.php$ { # root html; # fastcgi_pass 127.0.0.1:9000; # fastcgi_index index.php; # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; # include fastcgi_params; #} # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # #location ~ /\.ht { # deny all; #} } # another virtual host using mix of IP-, name-, and port-based configuration # #server { # listen 8000; # listen somename:8080; # server_name somename alias another.alias; # location / { # root html; # index index.html index.htm; # } #} # HTTPS server # #server { # listen 443 ssl; # server_name localhost; # ssl_certificate cert.pem; # ssl_certificate_key cert.key; # ssl_session_cache shared:SSL:1m; # ssl_session_timeout 5m; # ssl_ciphers HIGH:!aNULL:!MD5; # ssl_prefer_server_ciphers on; # location / { # root html; # index index.html index.htm; # } #} }
Tomcat在linux的基本配置
第一處端口修改:Xml代碼
<!-- 修改port端口:18005, 5個tomcat不能重複,端口隨意,別太小。本文測試中的5個tomcat設置分別爲:18005,18006,18007,18008,18009-->
<Server port="18005" shutdown="SHUTDOWN">
第二處端口修改:xml代碼
<!-- port="18081" tomcat監聽端口,隨意設置,別太小 本文檔中,5個tomcat分別設置爲:8801-8443;8802-8444;8803-8445;8804-8446;8805-8447.-->
<Connector port="8801" protocol="HTTP/1.1"
maxThreads="1500"
maxSpareThreads="500"
minSpareThreads="100"
acceptCount="1000"
enableLookups="false"
connectionTimeout="20000"
redirectPort="8443"
URIEncoding="UTF-8" />
第三處端口修改:XML代碼
<!-- 本文檔中,5個tomcat分別設置爲:8005-8443;8006-8444;8007-8445;8008-8446;8009-8447.-->
<Connector port="8005" protocol="AJP/1.3" redirectPort="8443" />
Engine元素增加jvmRoute屬性:xml代碼
<!-- 本文檔中,5個tomcat分別設置爲:node1,node2,node3,node4,node5.-->
<Engine name="Catalina" defaultHost="localhost" jvmRoute="node1">
集羣配置
Tomcat集羣配置主要是在conf目錄下的server.xml中的<Engine>添加以下代碼:
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8">
<Manager className="org.apache.catalina.ha.session.DeltaManager"
expireSessionsOnShutdown="false"
notifyListenersOnReplication="true"/>
<Channel className="org.apache.catalina.tribes.group.GroupChannel">
<--此處可以不做修改,Tomcat集羣的默認組播地址就是228.0.0.4,默認端口爲:45564-->
<Membership className="org.apache.catalina.tribes.membership.McastService"
address="228.0.0.4"
port="45564"
frequency="500"
dropTime="3000"/>
<--此處需要根據需要進行修改,address爲Tomcat所在主機的IP地址,port爲接收組播消息的端口,默認爲4000到5000,可以在該範圍內隨意設置。確保集羣內端口號唯一即可。-->
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="10.0.5.43"
port="4001"
autoBind="100"
selectorTimeout="5000"
maxThreads="6"/>
<Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
<Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender" />
</Sender>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor"/>
</Channel>
<Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/>
<Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
<Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
tempDir="/tmp/war-temp/"
deployDir="/tmp/war-deploy/"
watchDir="/tmp/war-listen/"
watchEnabled="false"/>
<ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>
最後,在需要進行session共享的應用中WEB-INF目錄下的web.xml中添加屬性。否則將不會實現Tomcat集羣應用中的session數據共享。
<distributable/>
上述代碼的詳細說明:
1、Cluster
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8">
1)Tomcat集羣主元素,在這個元素裏面可以配置集羣的所有詳細信息
2)className 主要的集羣類,當前只提供了 org.apache.catalina.ha.tcp.SimpleTcpCluste作爲實現類
3)channelSendOptionssession發送方式,默認值是8,這個標識確定通過SimpleTcpCluste如何發送消息
4)Channel.SEND_OPTIONS_SYNCHRONIZED_ACK = 0x0004
Channel.SEND_OPTIONS_ASYNCHRONOUS = 0x0008
Channel.SEND_OPTIONS_USE_ACK = 0x0002
如果使用(ASYNCHRONOUS)加(USE_ACK)方式來發送消息,那麼值應該是10(8+2)或者0x000B
如果使用(SYNCHRONIZED_ACK)加(USE_ACK)方式來發送消息,那麼值應該是6(4+2)或者0x0006
2、Manager
<Manager className="org.apache.catalina.ha.session.BackupManager"
expireSessionsOnShutdown="false"
notifyListenersOnReplication="true"
mapSendOptions="6"/>
1)管理tomcat之間的session複製
2)className當前有兩個實現類:org.apache.catalina.ha.session.DeltaManager和org.apache.catalina.ha.session.BackupManager
3)DeltaManager複製併發送Session數據到集羣下所有的節點,這個實現類被證明非常可靠、運行得非常好。不過有個侷限性就是集羣的節點類型要相同,而且要部署相同的應用程序
4)expireSessionsOnShutdown當一個web程序被結束時,tomcat分發銷燬命令到每個Session,並通知所有session listener執行。當集羣下某個節點被停止時,如果想銷燬所有節點下的的Session,設置爲true,默認爲false
5)notifyListenersOnReplication如果設置爲true,當session屬性被複制和移動的時候,session listener被通知
3、Channel
<Channel className="org.apache.catalina.tribes.group.GroupChannel">
Channel是Apache Tribes的主組件,channel管理一組子組件,並和它們一起組成了tomcat實例間的通訊框架。在tomcat集羣中,DeltaManager通過SimpleTcpCluster調用channel來實現信息傳遞,而BackupManager自己調用channel以及子組件這些組件來實現信息傳遞。ReplicatedContext也會調用channel傳遞context屬性。
4、Membership
<Membership className="org.apache.catalina.tribes.membership.McastService"
address="228.0.0.4"
port="45564"
frequency="500"
dropTime="3000"/>
MemberShip組件自動檢索發現集羣裏的新節點或已經停止工作的節點,併發出相應的通知。默認使用組播(Multicast)實現。
5、Receiver
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="auto"
port="5000"
selectorTimeout="100"
maxThreads="6"/>
負責監聽接收其他節點傳送過來的數據。默認使用non-blocking TCP Server sockets。
6、Sender
<Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
<Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
</Sender>
管理從一個節點發送到另外一個節點的出站連接和數據信息,允許信息並行發送。默認使用TCP Client Sockets。
7、Interceptor
<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/> <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/> <Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor"/>
Channel通過Interceptor堆棧進行消息傳遞,在這裏可以自定義消息的發送和接收方式,甚至MemberShip的處理方式。
8、Value
<Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
filter=".*\.gif|.*\.js|.*\.jpeg|.*\.jpg|.*\.png|.*\.htm|.*\.html|.*\.css|.*\.txt"/>
1)Value在調用Http Request 鏈中起着攔截器的作用,用來決定什麼情況下數據需要被複制。
org.apache.catalina.ha.tcp.ReplicationValve,ReplicationValue在Http Request結尾判斷當前數據是否需要被複制。
2)Filter內容爲url或者文件結尾,當訪問鏈接配置filter時,不論實際session有沒有改變,集羣會認爲session沒有任何變化,從而不會複製和發送改變的session屬性。
9、Deployer
<DeployerclassName="org.apache.catalina.ha.deploy.FarmWarDeployer"
tempDir="/tmp/war-temp/"
deployDir="/tmp/war-deploy/"
watchDir="/tmp/war-listen/"
watchEnabled="false"/>
使集羣支持farmed deployment
10、ClusterListener
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
Clusterlistener用來追蹤信息發送和接收。
ClusterSessionListener用來監聽集羣組件接收信息,當使用DeltaManager的時候,信息被集羣接收,並通過ClusterSessionListener傳遞給Session Manager。