領先的易物網站-捨得網基於J2ee Resin實現的技術內幕

[color=red]全文轉自:http://blog.csdn.net/wanghao72214/category/510248.aspx[/color]


application server採用j2ee架構技術,使用了免費的resin2.1.17搭建,並採用自行開發的緩存系統進行負載均衡,webserver 採用了重量級的apache 和輕量級的lighttpd。動態內容交由apache處理,靜態內容(比如圖片、css、js)等交由lighttpd處理。


以下是主要配置參數和建議:

一、java應用服務器,建議用resin2.1.17,如果有錢,可以買一個resin3的license,否則resin3比resin2慢,也可以考慮使用Glassfish,這個和resin性能差別比較小,tomcat還是不行。
如果緩存需要使用特別大的內存,建議用64位操作系統。32位jdk理論上最多使用4G內存,實際上只能用3G,3G還要分成兩部分,一部分是native,剩下一部分纔是Xmx這個參數定義的,配置不好
就經常出錯,系統會停頓6-10秒,甚至jvm會因爲native內存不夠而崩潰(實際這種情況linux有的是剩餘內存),這裏我應用我的一些配置經驗,如下:(以下內容csdn死活審覈不過,瘋了)


1:串行垃圾回收,也就是默認配置,完成10萬request用時153秒,JVM參數配置如下:(略)

這種配置一般在resin啓動24小時內似乎沒有大問題,網站可以正常訪問,但查看日誌發現,在接近24小時時,Full GC執行越來越頻繁,大約每隔3分鐘就有一次Full GC,每次Full GC系統會停頓6秒左右,作爲一個網站來說,用戶等待6秒恐怕太長了,所以這種方式有待改善。MaxTenuringThreshold=7表示一個對象如果在救助空間移動7次還沒有被回收就放入年老代,GCTimeRatio=19表示java可以用5%的時間來做垃圾回收,1/(1+19)=1 /20=5%。

2:並行回收,完成10萬request用時117秒,配置如下:(略)
並行回收我嘗試過多種組合配置,似乎都沒什麼用,resin啓動3小時左右就會停頓,時間超過10 秒。也有可能是參數設置不夠好的原因,MaxGCPauseMillis表示GC最大停頓時間,在resin剛啓動還沒有執行Full GC時系統是正常的,但一旦執行Full GC,MaxGCPauseMillis根本沒有用,停頓時間可能超過20秒,之後會發生什麼我也不再關心了,趕緊重啓resin,嘗試其他回收策略。

3:併發回收,完成10萬request用時60秒,比並行回收差不多快一倍,是默認回收策略性能的2.5倍,配置如下:(略)
這個配置雖然不會出現10秒連不上的情況,但系統重啓3個小時左右,每隔幾分鐘就會有5秒連不上的情況,查看gc.log,發現在執行ParNewGC時有個promotion failed錯誤,從而轉向執行Full GC,造成系統停頓,而且會很頻繁,每隔幾分鐘就有一次,所以還得改善。UseCMSCompactAtFullCollection是表是執行Full GC後對內存進行整理壓縮,免得產生內存碎片,CMSFullGCsBeforeCompaction=N表示執行N次Full GC後執行內存壓縮。

4:增量回收,完成10萬request用時171秒,太慢了,配置如下 :(略)
似乎回收得也不太乾淨,而且也對性能有較大影響,不值得試。

5:併發回收的I-CMS模式,和增量回收差不多,完成10萬request用時170秒。
配置如下:(略)

採用了sun推薦的參數,回收效果不好,照樣有停頓,數小時之內就會頻繁出現停頓,什麼sun推薦的參數,照樣不好使。

6:遞增式低暫停收集器,還叫什麼火車式回收,不知道屬於哪個系,完成10萬request用時153秒。配置如下:(略)
該配置效果也不好,影響性能,所以沒試。

7:相比之下,還是併發回收比較好,性能比較高,只要能解決ParNewGC(並行回收年輕代)時的promotion failed錯誤就一切好辦了,查了很多文章,發現引起promotion failed錯誤的原因是CMS來不及回收(CMS默認在年老代佔到90%左右纔會執行),年老代又沒有足夠的空間供GC把一些活的對象從年輕代移到年老代,所以執行Full GC。CMSInitiatingOccupancyFraction=70表示年老代佔到約70%時就開始執行CMS,這樣就不會出現Full GC了。SoftRefLRUPolicyMSPerMB這個參數也是我認爲比較有用的,官方解釋是softly reachable objects will remain alive for some amount of time after the last time they were referenced. The default value is one second of lifetime per free megabyte in the heap,我覺得沒必要等1秒,所以設置成0。配置如下:略

8:第7的配置還有可能因爲救助空間不夠造成promotion failed,我索性把救助空間去掉,通過調整SurvivorRatio和MaxTenuringThreshold實現,設置如下,總之還是要根據實際情況做出適合的調整。下面是我的最終配置,已經非常穩定,如果改成64位系統,內存可以加大。但隔三差五重啓resin還是有必要的,Perm空間總會變滿的。

二、apache的一些配置和技巧。
安裝apache時根據情況帶幾個參數,網上也有其他優化參數,但估計性能差不了多少,如下
./configure --prefix=/usr/local/apache2.2.10 --enable-so --enable-deflate --enable-rewrite --enable-expires
我做過測試,apache自帶的mod_mem_cache不太好使,最大使用內存不到200M時就會有問題,內存使用量突然下降,所以
圖片服務器建議不要用apache,用lighttpd或者nginx會更好。lighttpd+memcached的方式我就沒配成功過,nginx+memcached能從緩存
裏獲取,但不能set到緩存,所以我用的是lighttpd+mod_mem_cache(需要把lighttpd打個補丁),稍後作詳細介紹。

apache簡單防DDOS攻擊的配置,需要從網上找一個mod_evasive20模塊,用/usr/local/apache/bin/apxs -cia mod_evasive20.c安裝,一般情況下沒有必要配置這玩意。
<IfModule mod_evasive20.c>
DOSHashTableSize 10000
DOSPageCount 2
DOSSiteCount 50
DOSPageInterval 1
DOSSiteInterval 1
DOSBlockingPeriod 10
DOSEmailNotify [email protected]
DOSLogDir /var/log/mod_dosevasive.log
</IfModule>

apache防sql注入攻擊的配置,需要安裝mod_security模塊
<IfModule mod_security.c>
SecFilterEngine On
SecFilterCheckURLEncoding On
SecFilterForceByteRange 32 126
SecFilterCheckUnicodeEncoding On
SecServerResponseToken Off
SecAuditEngine RelevantOnly
SecAuditLog logs/audit_log
SecFilterDebugLog logs/modsec_debug_log
SecFilterDebugLevel 0
SecFilterDefaultAction "deny,log,status:406"
SecFilter /etc/*passwd
SecFilter /bin/*sh
SecFilter "\.\./"
SecFilter "<( |\n)*script"
SecFilter "<(.|\n)+>"
SecFilter "delete[[:space:]]+from"
SecFilter "insert[[:space:]]+into"
SecFilter "select.+from"
SecFilter "union[[:space:]]+from"
SecFilter "drop[[:space:]]"
SecFilterSelective "HTTP_USER_AGENT|HTTP_HOST" "^$"
</IfModule>

加大apache最大連接數的配置,如果選擇的是preworker工作方式。preworker和worker的區別就不講了。apache2.0以上直接設置ServerLimit即可,apache2.0以前還要修改源代碼才能使修改
的ServerLimit生效,建議應用服務器用apache2.0吧,性能差不了多少。

<IfModule mpm_prefork_module>
ServerLimit 20000 #ServerLimit據說要放第一行
StartServers 50
MinSpareServers 50
MaxSpareServers 100
MaxClients 10000
MaxRequestsPerChild 10000
</IfModule>

壓縮傳輸的配置,這個做爲網站來說非常重要,它是不壓縮傳輸大小的20%左右,也就是說用戶訪問一個網站速度快了5倍,不配置不行,但是圖片不能做壓縮了。

<IfModule mod_deflate.c>
SetOutputFilter DEFLATE
DeflateCompressionLevel 3
DeflateFilterNote Input instream
DeflateFilterNote Output outstream
DeflateFilterNote Ratio ratio
LogFormat '"%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" "%r" %{outstream}n/%{instream}n (%{ratio}n%%)' deflate
# Netscape 4.x has some problems...
BrowserMatch ^Mozilla/4 gzip-only-text/html
# Netscape 4.06-4.08 have some more problems
BrowserMatch ^Mozilla/4\.0[678] no-gzip
# MSIE masquerades as Netscape, but it is fine
#BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
# NOTE: Due to a bug in mod_setenvif up to Apache 2.0.48
# the above regex won't work. You can use the following
# workaround to get the desired effect:
BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
# Don't compress images, java scripts and style sheets
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|js|css)$ no-gzip dont-vary

# Make sure proxies don't deliver the wrong content
# this needs mod_headers but it's very important
# so I don't add a IfModule around it
#Header append Vary User-Agent env=!dont-vary
#CustomLog logs/deflate_log.log deflate
#CustomLog "|/usr/local/cronolog/sbin/cronolog /usr/local/apache2.0.59_2/logs/www.shedewang.com.access.log.%Y%m%d" deflate env=!IMAG
</IfModule>

apache配置mod_mem_cache,這個模塊不太好使,建議不用
<IfModule mod_cache.c>
#CacheForceCompletion 100
CacheDefaultExpire 3600
CacheMaxExpire 86400
CacheLastModifiedFactor 0.1
CacheIgnoreNoLastMod on
<IfModule mod_mem_cache.c>
CacheEnable mem /
MCacheSize 2000000
MCacheMaxObjectCount 10000
MCacheMinObjectSize 1000
MCacheMaxObjectSize 512000
MCacheRemovalAlgorithm LRU
</IfModule>
</IfModule>

CacheEnable: 啓動 mod_cache,其後接兩個參數。第一個參數指定快取的種類,應設爲 mem (記憶體快取) 或 disk (磁碟快取) 之其一;第二個參數指定使用快取的 URI 路徑,如果對整個網站 (或虛擬主機) 進行快取,簡單指定爲根目錄(/) 即可。
CacheForceCompletion: 這個值指定當 HTTP request 被取消時,內容的產生動作要完成的百分比;預設是 60(%)。
CacheDefaultExpire: 指定快取的預設過期秒數;預設值是一小時 (3600)。
CacheMaxExpire: 指定快取最大的過期秒數;預設值是一天 (86400)。
CacheLastModifiedFactor: 用來從迴應裏 Last Modified 資訊算出 expire date。
計算方式是:expire period (過期時距) = 最後更新後至今的時間間距 * CacheLastModifiedFactor
而expire date = 目前時間 + expire period
不過無論如何,過期時間不能超過 CacheMaxExpire 的設定值。


配置mod_expires模塊

mod_expires可以減少10%左右的重複請求,讓重複的用戶對指定的頁面請求結果都CACHE在本地,根本不向服務器發出請求,這一點特別實用在圖片服務器上。

mod_expires的安裝配置:
<IfModule mod_expires.c>
# turn on the module for this directory
ExpiresActive on

# cache common graphics for 3 days
ExpiresByType image/jpg "access plus 365 days"
ExpiresByType image/gif "access plus 365 days"
ExpiresByType image/jpeg "access plus 365 days"
ExpiresByType image/png "access plus 365 days"

</IfModule>


四:圖片服務器的安裝
圖片服務器是相對比較容易的,也是最穩定的服務器了,我建議用lighttpd或者nginx,不要用apache。
lighttpd不加cache也可以撐到50-80m沒秒,如果比這個流量還大,建議用lighttpd+mod_mem_cache或者
lighttpd+memcached,但是後者我沒有配成功,啓動不了。nginx和memcached比較容易整合,但是又不能自動
set到memcached裏去,還要自己用php或者java程序把圖片放入到memcached裏去,不夠智能。我用的是lighttpd1.4.20+mod_mem_cache,可以
遲到4G多內存,比apache強多了。安裝lighttpd的mod_mem_cache補丁如下
tar -xzvf lighttpd-1.4.20.tar.gz
cp lighttpd-1.4.20.mod_mem_cache.patch lighttpd-1.4.20
patch -p0 < lighttpd-1.4.20.mod_mem_cache.patch
sh autogen.sh
./configure --prefix=/usr/local/lighttpd-1.4.20
make && make install

配置文件增加如下段:
server.modules = (
# "mod_rewrite",
# "mod_redirect",
# "mod_alias",
"mod_access",
# "mod_cml",
# "mod_trigger_b4_dl",
# "mod_auth",
# "mod_status",
# "mod_setenv",
# "mod_fastcgi",
# "mod_proxy",
# "mod_simple_vhost",
# "mod_evhost",
# "mod_userdir",
# "mod_cgi",
# "mod_compress",
# "mod_ssi",
# "mod_usertrack",
"mod_expire",
# "mod_secdownload",
# "mod_rrdtool",
"mod_accesslog",
"mod_mem_cache" ) #注意加上這個

#然後增加如下配置段
mem-cache.filetypes = ("application/x-javascript", "text/css", "text/html", "text/javascript", "image/jpg", "image/jpeg", "image/gif", "image/png", "image/bmp")

mem-cache.enable = "enable"

#4096M
mem-cache.max-memory = 4096

#512k
mem-cache.max-file-size = 512

#lru count
mem-cache.lru-remove-count = 100000

#1 day
mem-cache.expire-time = 1440


五:nginx可以做負載均衡,按照IP做負載均衡就不用管分佈式session的問題,這裏就不做講述了,需要的時候查查就行。

六:網上說的lighttpd+squid+apache可以怎麼怎麼加速網站,我配置了一下,根本沒用,第一層的lighttpd只要必須經過squid,即使squid的緩存裏有也會很慢,還沒有直接一個lighttpd快。
下面附上squid3.0配置成功的配置文件,可以實現緩存,如果沒有緩存可以往81這個端口轉發。
#visible_hostname www.abc.com
visible_hostname localhost
http_port 3128 vhost vport
cache_mem 2048 MB
maximum_object_size_in_memory 2048 KB
memory_replacement_policy lru
#cache_dir ufs /tmp 512 16 256
cache_dir ufs /usr/local/squid/var/cache 2048 16 256
max_open_disk_fds 0
minimum_object_size 0 KB
maximum_object_size 32768 KB
logformat combined %>a %ui %un [%tl] "%rm %ru HTTP/%rv" %Hs %<st "%{Referer}>h" "%{User-Agent}>h" %Ss:%Sh
access_log /usr/local/squid/var/logs/access_log combined
cache_log /usr/local/squid/var/logs/cache.log
pid_filename /usr/local/squid/var/logs/squid.pid
#cache_store_log none
cache_peer 127.0.0.1 parent 81 0 no-query no-digest originserver name=www
#cache_peer_domain www www.abc.com
cache_peer_domain localhost
cache_peer_access www allow all
http_access allow all
acl QUERY urlpath_regex .exe
cache deny QUERY
cache_effective_user nobody
cache_effective_group nobody
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章