1 起因最近對(duì)新開發(fā)的web系統(tǒng)進(jìn)行了壓力測(cè)試,發(fā)現(xiàn)tomcat默認(rèn)配置下壓到600人的并發(fā)登錄首頁響應(yīng)速度就有比較嚴(yán)重的影響,一輪出現(xiàn)2000多個(gè)的500和502錯(cuò)誤。我把登錄的時(shí)間統(tǒng)計(jì)做了一下,把服務(wù)器處理總時(shí)間打印出來,看了一下發(fā)現(xiàn)有個(gè)別響應(yīng)確實(shí)在20秒,但平均時(shí)間和lr測(cè)試出來的還是相差很遠(yuǎn)。所以可以斷定不是程序處理處理花費(fèi)了這么多時(shí)間,由于在局域網(wǎng)測(cè)試,所以也可以排除網(wǎng)絡(luò)問題。這就把問題圈定在tomcat的請(qǐng)求響應(yīng)能力上了。先把tomcat線程數(shù)提升到1000,發(fā)現(xiàn)500和502的報(bào)錯(cuò)降到幾十個(gè),但是響應(yīng)時(shí)間上還沒什么提高。后來啟動(dòng)了2個(gè)tomcat,用nginx做負(fù)載均衡,響應(yīng)時(shí)間下降了40%,兩個(gè)tomcat的處理時(shí)長都保持在1秒左右。 看來tomcat性能確實(shí)是系統(tǒng)的一個(gè)瓶頸,很有必要假設(shè)多個(gè)服務(wù)器來加強(qiáng)響應(yīng)能力。之前由于只是測(cè)試登錄,多個(gè)tomcat還不用共享session,但真正使用時(shí)是必須要能一起工作的?,F(xiàn)記錄一下負(fù)載均衡的安裝配置過程。
2 解決方案的選擇多個(gè)tomcat要一起協(xié)同工作有幾種辦法,可以考慮的方案有以下幾個(gè): 1. 使用tomcat自帶的cluster方式,多個(gè)tomcat見自動(dòng)實(shí)時(shí)復(fù)制session信息,配置起來很簡(jiǎn)單。但這個(gè)方案的效率比較低,在大并發(fā)下表現(xiàn)并不好。 2. 利用nginx的基于訪問ip的hash路由策略,保證訪問的ip始終被路由到同一個(gè)tomcat上,這個(gè)配置更簡(jiǎn)單。但是我們的應(yīng)用很可能是某一個(gè)局域網(wǎng)大量用戶同時(shí)登錄,這樣負(fù)載均衡就沒什么作用了。 3. 利用memcached把多個(gè)tomcat的session集中管理,這是最直接的解決方案,但是操作起來也最為復(fù)雜。 我們的系統(tǒng)既要求性能,又要比較好的利用上負(fù)載均衡,所以第3個(gè)方案是首選。接下來就是安裝搭建之路了。
3 安裝配置3.1 memcached的安裝1)先下載libevent-1.4.14b-stable.tar.gz和memcached-1.4.7.tar.gz的源碼包,前者是后者的依賴包,就是一個(gè)事件驅(qū)動(dòng)的包。 2)安裝非常順利,還是經(jīng)典的那幾個(gè)編譯安裝命令: tar zxvf libevent-1.4.14b-stable.tar.gz cd libevent-1.4.14b-stable ./configure --prefix=/usr/local/libevent-1.4.14b make make install tar zxvf memcached-1.4.7.tar.gz cd memcached-1.4.7 ./configure --prefix=/usr/local/memcached-1.4.7 --with-libevent=/usr/local/libevent-1.4.14b/ make make install 3)啟動(dòng)memcached: ./bin/memcached -d -m 256 -u root -p 11211 -c 1024 -P /tmp/memcached.pid
3.2 memcached-session-manager配置讓tomcat調(diào)用memcached來存儲(chǔ)session早就是一個(gè)很成熟的解決方案了,開源的msm就可以解決這個(gè)問題。比較折騰的就是要用到的jar包,官方文檔說的也比較含糊,我這里用的是kryo的序列化方案,所以用到的包多一些,分別是: kryo-1.03.jar kryo-serializers-0.8.jar memcached-2.5.jar(我在官方看最新已經(jīng)到2.7了,但是msm官方說用2.5,可能新包沒測(cè)試過,特別是2.6版本changelog里面提到api有調(diào)整,還是不要亂升的好) memcached-session-manager-1.5.1.jar memcached-session-manager-tc7-1.5.1.jar minlog-1.2.jar msm-kryo-serializer-1.5.1.jar reflectasm-0.9.jar 以上這些包都放在$CATALINA_HOME/lib目錄下。 另外提一下,官方給出的4種序列化方案,其中kryo是效率最高的,具體比較看http://code.google.com/p/memcached-session-manager/wiki/SerializationStrategies。
接下來是修改tomcat的配置文件$CATALINA_HOME/conf/context.xml,調(diào)整成新的session存儲(chǔ)方式。配置文件中加入以下內(nèi)容: <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager" memcachedNodes="n1:127.0.0.1:11211" sticky="false" lockingMode="auto" sessionBackupAsync="false" sessionBackupTimeout="1000" transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory" />
在$CATALINA_HOME/conf/logging.properties文件中添加de.javakaffee.web.msm.level=FINE,就可以在catalina.out的日志中看到詳細(xì)的session存取情況。
另外在Manager配置中加上requestUriIgnorePattern=".*\.(png|gif|jpg|css|js)$",用chrome瀏覽器測(cè)試發(fā)現(xiàn)居然sessionID會(huì)突然變掉,然后就被攔截器給跳回首頁了。去掉就一切正常,但攔截器只會(huì)去檢測(cè)action的,按理說應(yīng)該完全沒關(guān)系,望高人指點(diǎn)!
3.3 nginx配置nginx非常簡(jiǎn)單,只要在upstream里面多配置幾個(gè)server就可以了,這里把我的配置貼出來: #user nobody; worker_processes 16; events { use epoll; worker_connections 65535; } http { include mime.types; default_type application/octet-stream; #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' # '$status $body_bytes_sent "$http_referer" ' # '"$http_user_agent" "$http_x_forwarded_for"'; #access_log logs/access.log main; client_header_buffer_size 32k; large_client_header_buffers 4 32k; client_max_body_size 8m; client_body_buffer_size 128k; sendfile on; tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65; gzip on; gzip_types text/javascript text/plain text/css application/xml application/x-javascript; gzip_disable "MSIE [1-6]\.(?!.*SV1)"; proxy_connect_timeout 300; proxy_send_timeout 300; proxy_read_timeout 300; proxy_buffer_size 16k; proxy_buffers 4 32k; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Connection Close; server_names_hash_max_size 1024; server_names_hash_bucket_size 1024; # Default cache parameters for use by virtual hosts # Set the cache path to tmpfs mounted disk, and the zone name # Set the maximum size of the on disk cache to less than the tmpfs file system size proxy_cache_path ./cache levels=1:2 keys_zone=pscms:100m max_size=800m; proxy_temp_path ./proxy; #配置后端服務(wù)器信息 upstream web_server { #ip_hash; server localhost:8080 max_fails=3 fail_timeout=30s; server localhost:8180 max_fails=3 fail_timeout=30s; } server { listen 8888; ## listen for ipv4 #listen [::]:80 default ipv6only=on; ## listen for ipv6 server_name localhost; charset utf-8; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log logs/host.access.log main; #access_log off; location ~ .*\.(jsp|action)?$ { proxy_set_header Host $http_host; proxy_redirect off; proxy_pass http://web_server; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|js|css)$ { #如果后端的服務(wù)器返回502、504、執(zhí)行超時(shí)等錯(cuò)誤,自動(dòng)將請(qǐng)求轉(zhuǎn)發(fā)到upstream負(fù)載均衡池中的另一臺(tái)服務(wù)器,實(shí)現(xiàn)故障轉(zhuǎn)移。 proxy_next_upstream http_502 http_504 error timeout invalid_header; proxy_cache pscms; #進(jìn)行緩存,使用Web緩存區(qū)cache_one proxy_cache_valid 200 304 1h; #對(duì)不同的HTTP狀態(tài)碼設(shè)置不同的緩存時(shí)間 proxy_cache_valid 301 302 5m; proxy_cache_valid any 1m; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Accept-Encoding ""; #(或是后臺(tái)服務(wù)器關(guān)閉gzip),這樣這臺(tái)機(jī)器才不會(huì)緩存被壓縮的文件,造成亂碼 proxy_ignore_headers "Cache-Control" "Expires"; #這段配置加上后,proxy_cache就能支持后臺(tái)設(shè)定的expires。 proxy_pass http://web_server; expires 15m; } location / { proxy_set_header Host $http_host; proxy_redirect off; proxy_pass http://web_server; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } }
參考文檔: 1. http://code.google.com/p/memcached-session-manager/wiki/SetupAndConfiguration 2. http://wangrui./blog/500921
修改記錄: 2011年9月3日 修改了nginx配置文件的gzip_types,增加對(duì)css和js的壓縮
|
|