服務器調優──提高併發量

        操作系統的中打開文件的最大句柄數受限所致,常常發生在很多個併發用戶訪問服務器的時候.因爲爲了執行每個用戶的應用服務器都要加載很多文件(new一個socket就需要一個文件句柄),這就會導致打開文件的句柄的缺乏.
解決:
儘量把類打成jar包,因爲一個jar包只消耗一個文件句柄,如果不打包,一個類就消耗一個文件句柄.
java的垃圾回收不能關閉網絡連接打開的文件句柄,如果沒有執行close()(例如:java.net.Socket.close())則文件句柄將一直存在,而不能被關閉.你也可以考慮設置socket的最大打開數來控制這個問題.
對操作系統做相關的設置,增加最大文件句柄數量。
Linux
在Linux內核2.4.x中需要修改源代碼,然後重新編譯內核才生效。編輯Linux內核源代碼中的 include/linux/fs.h文件,將 NR_FILE 由8192改爲65536,將NR_RESERVED_FILES 由10 改爲 128。編輯fs/inode.c 文件將MAX_INODE 由16384改爲262144。或者編輯 /etc/sysctl.conf  文件增加兩行 fs.file-max = 65536 和 fs.inode-max = 262144 。一般情況下,系統最大打開文件數比較合理的設置爲每4M物理內存256,比如256M.可以用lsof -p 看打開的文件句柄數.
Windows
最大文件句柄是16,384,你在任務管理器的性能這一項中可以看到當前打開的句柄數.

 

 


修改linux內核信息:

使用ulimit -n命令可以看到單個進程能夠打開的最大文件句柄數量(socket連接也算在裏面)。系統默認值1024。
vi /etc/security/limits.conf,加入如下內容:
*               hard    nofile          10240
vi /etc/profile,加入如下內容:
ulimit -n 10240
執行:
source /etc/profile
驗證:
ulimit -n
返回數值應該是10240
vi /etc/sysctl.conf
加入:

net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_tw_recycle=1

net.ipv4.tcp_fin_timeout = 30

 

說明:
  net.ipv4.tcp_syncookies = 1 表示開啓SYN Cookies。當出現SYN等待隊列溢出時,啓用cookies來處理,可防範少量SYN攻擊,默認爲0,表示關閉;
  net.ipv4.tcp_tw_reuse = 1 表示開啓重用。允許將TIME-WAIT sockets重新用於新的TCP連接,默認爲0,表示關閉;
  net.ipv4.tcp_tw_recycle = 1 表示開啓TCP連接中TIME-WAIT sockets的快速回收,默認爲0,表示關閉。

        net.ipv4.tcp_fin_timeout 修改系統默認的 TIMEOUT 時間

shmmax - 共享內存段的最大字節數,建議設大點,甚至可以大過物理內存的字節數
shmmin - 共享內存段的最小尺寸.
shmmni - 共享內存段的最大數目.
shmseg - 每個進程可分配的最大共享內存段數目.
shmall - 最大的併發共享內存段數目,比SGA還要大.
semmns - 信號燈的最大數量,跟ORACLE的PROCESS數有關.
semmsl - 每個信號燈集合中最多的信號燈數目.
設置Linux內核參數
配置 Linux 內核參數(2種方法),修改後不用重啓動更新: /sbin/sysctl -p
第一種:打開/etc/sysctl.conf
kernel.shmmax = 536870912
kernel.shmall = 2097152
kernel.shmmax = 2147483648            2G
kernel.shmmni = 4096
kernel.sem = 250 32000 100 128
fs.file-max = 65536
net.ipv4.ip_local_port_range = 1024     65000
net.core.rmem_default=262144
net.core.wmem_default=262144
net.core.rmem_max=262144
net.core.wmem_max=262144
第二種:打開終端
cat >> /etc/sysctl.conf
kernel.shmall = 2097152
  *
kernel.shmmni = 4096
kernel.sem = 250 32000 100 128
fs.file-max =
net.ipv4.ip_local_port_range = 1024     65000
net.core.rmem_default=262144
net.core.wmem_default=262144
net.core.rmem_max=262144
net.core.wmem_max=262144
EOF
這裏,對每個參數值做個簡要的解釋和說明。
    (1)shmmax:該參數定義了共享內存段的最大尺寸(以字節爲單位)。缺省爲32M,對於oracle來說,該缺省值太低了,通常將其設置爲2G。
    (2)shmmni:這個內核參數用於設置系統範圍內共享內存段的最大數量。該參數的默認值是 4096 。通常不需要更改。
    (3)shmall:該參數表示系統一次可以使用的共享內存總量(以頁爲單位)。缺省值就是2097152,通常不需要修改。
    (4)sem:該參數表示設置的信號量。
    (5)file-max:該參數表示文件句柄的最大數量。文件句柄設置表示在linux系統中可以打開的文件數量。
    修改好內核以後,執行下面的命令使新的配置生效。
[root @linux1 /root]# /sbin/sysctl -p
以 root 用戶身份運行以下命令來驗證您的設置:
/sbin/sysctl -a | grep shm
/sbin/sysctl -a | grep sem
/sbin/sysctl -a | grep file-max
/sbin/sysctl -a | grep ip_local_port_range
例如:
# /sbin/sysctl -a | grep shm
kernel.shmmni = 4096
kernel.shmall = 2097152
kernel.shmmax = 2147483648
kernel.shm-use-bigpages = 0
# /sbin/sysctl -a | grep sem
kernel.sem = 250        32000   100     128
# /sbin/sysctl -a | grep file-max
fs.file-max = 65536
# /sbin/sysctl -a | grep ip_local_port_range
net.ipv4.ip_local_port_range = 1024     65000
如果系統的參數設置的比上述參數值小,則編輯 /etc/sysctl.conf 文件,添加或更改這些參數。完成後,運行以下命令激活更改:
/sbin/sysctl -p


查看進程句柄數量:

如何知道當前進程打開了多少個文件句柄呢?下面一段小腳本可以幫你查看:lsof -n |awk '{print $2}'|sort|uniq -c |sort -nr|more  
  在系統訪問高峯時間以root用戶執行上面的腳本,可能出現的結果如下:# lsof -n|awk '{print $2}'|sort|uniq -c |sort -nr|more    131 24204   57 24244   57 24231   56 24264
  其中第一行是打開的文件句柄數量,第二行是進程號。得到進程號後,我們可以通過ps命令得到進程的詳細內容。ps -aef|grep 24204 mysql  24204 24162 99 16:15 ?    00:24:25 /usr/sbin/mysqld
  哦,原來是mysql進程打開最多文件句柄數量。但是他目前只打開了131個文件句柄數量,遠遠底於系統默認值1024。


用以下語句看了一下服務器的TCP狀態:
  netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
  返回結果如下:
  ESTABLISHED 1423
  FIN_WAIT1 1
  FIN_WAIT2 262
  SYN_SENT 1
  TIME_WAIT 962

 

 

apache2.x優化──提高併發量

引用:http://tech.ccidnet.com/art/737/20030527/47607_1.html

指定MPM的方法

  下面以Red Hat Linux 9爲平臺,說明在Apache 2.0中如何指定MPM (Apache採用2.0.45)。先解壓縮源代碼包httpd-2.0.45.tar.gz,生成httpd-2.0.45目錄(Apache 1.3源代碼包的命名規則是apache_1.3.NN.tar.gz,而2.0版則是httpd-2.0.NN.tar.gz,其中NN是次版本號)。

  進入httpd-2.0.45目錄,運行以下代碼:

$ ./configure --help|grep mpm

  顯示如下:

--with-mpm=MPM
Choose the process model for Apache to use.
MPM={beos|worker|prefork|mpmt_os2| perchild|leader|threadpool}

  上述操作用來選擇要使用的進程模型,即哪種MPM模塊。Beos、 mpmt_os2分別是BeOS和OS/2上缺省的MPM,perchild主要設計目的是以不同的用戶和組的身份來運行不同的子進程。這在運行多個需要 CGI的虛擬主機時特別有用,會比1.3版中的SuExec機制做得更好。leader和threadpool都是基於worker的變體,還處於實驗性 階段,某些情況下並不會按照預期設想的那樣工作,所以Apache官方也並不推薦使用。因此,我們主要闡述prefork和worker這兩種和性能關係 最大的產品級MPM ( 有關其它的MPM詳細說明,請參見Apache官方文檔:http://httpd.apache.org/docs-2.0/mod/)。

  prefork的工作原理及配置

  如果不用“--with-mpm”顯式指定某種MPM,prefork就是 Unix平臺上缺省的MPM。它所採用的預派生子進程方式也是Apache 1.3中採用的模式。prefork本身並沒有使用到線程,2.0版使用它是爲了與1.3版保持兼容性;另一方面,prefork用單獨的子進程來處理不 同的請求,進程之間是彼此獨立的,這也使其成爲最穩定的MPM之一。

  若使用prefork,在make編譯和make install安裝後,使用“httpd -l”來確定當前使用的MPM,應該會看到prefork.c(如果看到worker.c說明使用的是worker MPM,依此類推)。再查看缺省生成的httpd.conf配置文件,裏面包含如下配置段:

<IfModule prefork.c>
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 150
MaxRequestsPerChild 0
</IfModule>

  prefork的工作原理是,控制進程在最初建立“StartServers” 個子進程後,爲了滿足MinSpareServers設置的需要創建一個進程,等待一秒鐘,繼續創建兩個,再等待一秒鐘,繼續創建四個……如此按指數級增 加創建的進程數,最多達到每秒32個,直到滿足MinSpareServers設置的值爲止。這就是預派生(prefork)的由來。這種模式可以不必在 請求到來時再產生新的進程,從而減小了系統開銷以增加性能。

  MaxSpareServers設置了最大的空閒進程數,如果空閒進程數大於 這個值,Apache會自動kill掉一些多餘進程。這個值不要設得過大,但如果設的值比MinSpareServers小,Apache會自動把其調整 爲MinSpareServers+1。如果站點負載較大,可考慮同時加大MinSpareServers和MaxSpareServers。

  MaxRequestsPerChild設置的是每個子進程可處理的請求數。 每個子進程在處理了“MaxRequestsPerChild”個請求後將自動銷燬。0意味着無限,即子進程永不銷燬。雖然缺省設爲0可以使每個子進程處 理更多的請求,但如果設成非零值也有兩點重要的好處:

  ◆ 可防止意外的內存泄漏;

  ◆ 在服務器負載下降的時侯會自動減少子進程數。

  因此,可根據服務器的負載來調整這個值。筆者認爲10000左右比較合適。

  MaxClients是這些指令中最爲重要的一個,設定的是Apache可以同 時處理的請求,是對Apache性能影響最大的參數。其缺省值150是遠遠不夠的,如果請求總數已達到這個值(可通過ps -ef|grep http|wc -l來確認),那麼後面的請求就要排隊,直到某個已處理請求完畢。這就是系統資源還剩下很多而HTTP訪問卻很慢的主要原因。系統管理員可以根據硬件配置 和負載情況來動態調整這個值。雖然理論上這個值越大,可以處理的請求就越多,但Apache默認的限制不能大於256。如果把這個值設爲大於256,那麼 Apache將無法起動。事實上,256對於負載稍重的站點也是不夠的。在Apache 1.3中,這是個硬限制。如果要加大這個值,必須在“configure”前手工修改的源代碼樹下的src/include/httpd.h中查找 256,就會發現“#define HARD_SERVER_LIMIT 256”這行。把256改爲要增大的值(如4000),然後重新編譯Apache即可。在Apache 2.0中新加入了ServerLimit指令,使得無須重編譯Apache就可以加大MaxClients。下面是筆者的prefork配置段:

<IfModule prefork.c>
StartServers 10
MinSpareServers 10
MaxSpareServers 15
ServerLimit 2000
MaxClients 1000
MaxRequestsPerChild 10000
</IfModule>

  上述配置中,ServerLimit的最大值是20000,對於大多數站點已經足夠。如果一定要再加大這個數值,對位於源代碼樹下server/mpm/prefork/prefork.c中以下兩行做相應修改即可:

#define DEFAULT_SERVER_LIMIT 256
#define MAX_SERVER_LIMIT 20000

  worker的工作原理及配置

  相對於prefork,worker是2.0 版中全新的支持多線程和多進程混合模型的MPM。由於使用線程來處理,所以可以處理相對海量的請求,而系統資源的開銷要小於基於進程的服務器。但是, worker也使用了多進程,每個進程又生成多個線程,以獲得基於進程服務器的穩定性。這種MPM的工作方式將是Apache 2.0的發展趨勢。

  在configure -with-mpm=worker後,進行make編譯、make install安裝。在缺省生成的httpd.conf中有以下配置段:

<IfModule worker.c>
StartServers 2
MaxClients 150
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestsPerChild 0
</IfModule>

  worker的工作原理是,由主控制進程生成“StartServers”個子 進程,每個子進程中包含固定的ThreadsPerChild線程數,各個線程獨立地處理請求。同樣,爲了不在請求到來時再生成線程, MinSpareThreads和MaxSpareThreads設置了最少和最多的空閒線程數;而MaxClients設置了所有子進程中的線程總數。 如果現有子進程中的線程總數不能滿足負載,控制進程將派生新的子進程。

  MinSpareThreads和MaxSpareThreads的最大缺省值分別是75和250。這兩個參數對Apache的性能影響並不大,可以按照實際情況相應調節。

  ThreadsPerChild是worker MPM中與性能相關最密切的指令。ThreadsPerChild的最大缺省值是64,如果負載較大,64也是不夠的。這時要顯式使用 ThreadLimit指令,它的最大缺省值是20000。上述兩個值位於源碼樹server/mpm/worker/worker.c中的以下兩行:

#define DEFAULT_THREAD_LIMIT 64
#define MAX_THREAD_LIMIT 20000

  這兩行對應着ThreadsPerChild和ThreadLimit的限制數。最好在configure之前就把64改成所希望的值。注意,不要把這兩個值設得太高,超過系統的處理能力,從而因Apache不起動使系統很不穩定。

  Worker模式下所能同時處理的請求總數是由子進程總數乘以 ThreadsPerChild值決定的,應該大於等於MaxClients。如果負載很大,現有的子進程數不能滿足時,控制進程會派生新的子進程。默認 最大的子進程總數是16,加大時也需要顯式聲明ServerLimit(最大值是20000)。這兩個值位於源碼樹 server/mpm/worker/worker.c中的以下兩行:

#define DEFAULT_SERVER_LIMIT 16
#define MAX_SERVER_LIMIT 20000

  需要注意的是,如果顯式聲明瞭ServerLimit,那麼它乘以 ThreadsPerChild的值必須大於等於MaxClients,而且MaxClients必須是ThreadsPerChild的整數倍,否則 Apache將會自動調節到一個相應值(可能是個非期望值)。下面是筆者的worker配置段:

<IfModule worker.c>
StartServers 3
MaxClients 2000
ServerLimit 25
MinSpareThreads 50
MaxSpareThreads 200
ThreadLimit 200
ThreadsPerChild 100
MaxRequestsPerChild 0
</IfModule>

  通過上面的敘述,可以瞭解到Apache 2.0中prefork和worker這兩個重要MPM的工作原理,並可根據實際情況來配置Apache相關的核心參數,以獲得最大的性能和穩定

 

 

修改tomcat6.0的併發數:

  1. <Connector port="80" protocol="HTTP/1.1"  
  2.                maxHttpHeaderSize="8192"  
  3.                maxThreads="1000" minSpareThreads="75" maxSpareThreads="300"  
  4.                enableLookups="false" redirectPort="8443" acceptCount="200"  
  5.                connectionTimeout="50000" disableUploadTimeout="true"/>  


主要修改了maxThreads、acceptCount。


Google資料說“如果要加大併發連接數,應同時加大這兩個參數。web server允許的最大連接數還受制於操作系統的內核參數設置,通常Windows是2000個左右,Linux是1000個左右。”


2、 增加tomcat啓動初始內存設置;catalina.sh – 增加了參數內存設置
增加設置

  1. JAVA_OPTS="-server -Xms2048M -Xmx2048M -Xss128k -XX:+AggressiveOpts -XX:+UseParallelGC  -XX:+UseBiasedLocking"  
JAVA_OPTS="-server -Xms2048M -Xmx2048M -Xss128k -XX:+AggressiveOpts -XX:+UseParallelGC  -XX:+UseBiasedLocking"


增加了JVM初始分配的內存

資料:

Heap Size 最大不要超過可用物理內存的80%,一般的要將-Xms和-Xmx選項設置爲相同
堆內存分配
JVM初始分配的內存由-Xms指定,默認是物理內存的1/64;JVM最大分配的內存由-Xmx指定,默認是物理內存的1/4。默認空餘堆內存 小於40%時,JVM就會增大堆直到-Xmx的最大限制;空餘堆內存大於70%時,JVM會減少堆直到-Xms的最小限制。因此服務器一般設置-Xms、 -Xmx相等以避免在每次GC 後調整堆的大小。
非堆內存分配
JVM使用-XX:PermSize設置非堆內存初始值,默認是物理內存的1/64;由XX:MaxPermSize設置最大非堆內存的大小,默認是物理內存的1/4。
JVM內存限制(最大值)
首先JVM內存限制於實際的最大物理內存(廢話!呵呵),假設物理內存無限大的話,JVM內存的最大值跟操作系統有很大的關係。簡單的說就32位 處理器雖然可控內存空間有4GB,但是具體的操作系統會給一個限制,這個限制一般是2GB-3GB(一般來說Windows系統下爲1.5G-2G, Linux系統下爲2G-3G),而64bit以上的處理器就不會有限制了。


3、 響應處理的servlet在系統啓動時進行初始化,修改servlet load-on-strartup數值,可設0、1、2、3,值小的先初始化;

 

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章