《後端服務性能優化指南》java
目錄mysql
1、 服務器操做系統 2linux
2、 web服務器/反向代理服務器(nginx) 2nginx
3、 應用服務器(tomcat) 2web
4、 應用日誌配置 2spring
5、 數據庫(mysql) 3sql
6、 數據庫鏈接池 3數據庫
7、 Restfull服務調用 4apache
1、服務器操做系統後端
一、全局全部進程共享上限
查看系統配置最大句柄數 cat /proc/sys/fs/file-nr
修改: /etc/sysctl.conf
fs.file-max = 100000
net.ipv4.ip_conntrack_max = 100000
net.ipv4.netfilter.ip_conntrack_max = 100000
二、單進程最大句柄數
服務器默認配置爲1024
查看最大進程數 ulimit -u
查看進程最大句柄數 ulimit -n
修改:/etc/security/limits.conf
* soft nofile = 32768
* hard nofile = 65536
對全部用戶單線程最大可打開句柄,軟限制32768,硬限制65536;
三、tcp鏈接存活時間,關閉鏈接時等待時間
修改/etc/sysctl.conf,添加以下幾行:
#系統默認的TIMEOUT時間
net.ipv4.tcp_fin_timeout=30
#啓重用,容許將TIME_WAIT sockets從新用於新的TCP鏈接 默認爲0表示關閉
net.ipv4.tcp_tw_reuse=1
#開啓TCP鏈接中TIME_WAIT sockets的快速回收 默認爲0 表示關閉
net.ipv4.tcp_tw_recycle=1
四、使用uname -a命令查看系統內核版本,請確保linux系統內核版本高於2.6.28, 今後版本開始linux支持高效異步IO模型epoll,jdk的NIO開發包中含有對當 前操做系統版本號的判斷(linux>2.6時調用epoll的native方法),java nio所 用的IO模型的實現方式由操做系統決定。
2、web服務器/反向代理服務器(nginx)
nginx.conf配置文件:
五、nginx單個工做進程最大創建外部鏈接數
worker_connections 16000
六、nginx進程最大可打開句柄數
worker_rlimit_nofile 65535
七、nginx工做進程數
worker_processes 8 [通常設置爲CPU核數的雙倍]
3、應用服務器(tomcat)
一、請將connector配置爲NIO模式,並設置合適的最大鏈接數(springboot內嵌的tomcat默認就是NIO,最大鏈接數max-connections默認10000)
二、調整tomcat工做線程數與排隊隊列長度
server.tomcat.max-threads=800
server.tomcat.accept-count=200
4、應用日誌配置
一、應用日誌目前最佳實踐爲sl4j + logback,代碼中應使用sl4j日誌門面,禁止直接使用log4j等具體實現。
二、在某些高併發服務應考慮作日誌異步優化,減小IO阻塞時間、提升CPU利用率:
<appender name="syslog"
class="ch.qos.logback.core.rolling.RollingFileAppender">
......
</appender>
<appender name="ASYNC_ROLLING_FILE" class="ch.qos.logback.classic.AsyncAppender">
<queueSize>256</queueSize>
<includeCallerData>true</includeCallerData>
<appender-ref ref="syslog"/>
</appender>
<root level="INFO">
<!-- <appender-ref ref="STDOUT"/> -->
<appender-ref ref="ASYNC_ROLLING_FILE"/>
</root>
Logback提供的AsyncAppender使用內置的隊列實現異步日誌輸出,默認256,爲保證性能,超過該長度80%則開始丟棄error以外的日誌。
屬性名 |
類型 |
默認值 |
描述 |
queueSize |
int |
256 |
內置BlockingQueue的最大容量 |
discardingThreshold |
int |
-1 |
默認狀況下,當blockingQueue的容量高於閾值時(80%),會丟棄ERROR如下級別的日誌,若是不但願丟棄日誌(既每次都是全量保存),那能夠設置爲0,可是若是隊列滿的時候,會丟棄全部插入隊列的日誌信息,因此建議設置爲-1(默認值)。 如正常日誌能夠丟棄,那能夠極大的提高性能,並保存關鍵的ERROR日誌。
|
includeCallerData |
boolean |
false |
提取調用者數據的代價是至關昂貴的。爲了提高性能,默認狀況下,當event被加入到queue時,event關聯的調用者數據不會被提取。默認狀況下,只有"cheap"的數據,如線程名。好比日誌中的代碼行號若是須要輸出則應將該值設爲true。實測includeCallerData=true會帶來必定性能降低,但高併發下仍遠比同步日誌方式的tps要高。 |
5、數據庫(mysql)
在作壓力測試的時候,發現了數據庫鏈接數的限制,以及一些比較長慢查詢,如下的配置主要解決這方面的問題
如下的數據庫參數在/etc/my.cnf 中進行修改,數據庫重啓以後生效。
一、 數據庫的最大鏈接數以及用戶最大鏈接數的設置以下,
max_connections=1000(默認151)
max_user_connections=1000
2、查詢過程當中生成的臨時表的大小能夠經過tmp_table_size進行設置, max_heap_table_size在作鏈接查詢的時候用到。參數max_heap_table_size比tmp_table_size小時,則系統會把max_heap_table_size的值做爲最大的內存臨時表的上限,大於這個時,改寫硬盤,增長heap表的大小,可達到提升聯接查詢速度的效果。
如:
tmp_table_size=200M(默認16M)
max_heap_table_size=500M(默認16M)
3、read_buffer_size:是MySQL讀入緩衝區大小,對錶進行順序掃描的請求將分配一個讀入緩衝區,MySQL會爲它分配一段內存緩衝區。read_buffer_size變量控制這一緩衝區的大小。若是對錶的順序掃描請求很是頻繁,而且如認爲頻繁掃描進行得太慢,能夠經過增長該變量值以及內存緩衝區大小提升其性能。
以下的設置:
sort_buffer_size = 8M
read_buffer_size =8M
read_rnd_buffer_size = 8M
join_buffer_size,這個是跟join table 關聯的,如:join_buffer_size = 8M。
6、數據庫鏈接池
以tomcat-jdbc鏈接池爲例,其餘鏈接池如dbcp、c3p0、druid等相似;
一、core portal user identity幾個應用的數據庫鏈接池參數修改:user最大鏈接maxActive、最大空閒maxIdle 300,最小空閒minIdle、初始數initialSize 60;portal\core\identity:最大鏈接、最大空閒100, 最小空閒、初始數20;其餘應用初始5最大20
二、在生產環境請關閉testOnBorrow和testOnReturn(設置爲false),失效鏈接主要經過testWhileIdle保證。
7、 Restfull服務調用
一、熱點服務不容許直接使用jdk自帶的java.net.URLConnection進行http client調用
二、推薦使用apache httpclient,okhttp等鏈接池模式的http庫進行rest服務調用,減小反覆創建鏈接的開銷。基於spring技術棧的應用比較好的實踐方式是使用restTemplate來配置上述實現方式。
三、Apache HttpClient Fluent API底層實現基於自家的httpclient鏈接池模式,其中代碼寫死了maxTotal和maxPerRoute全部請求會使用一個公共的鏈接池,總共200鏈接,每一個destination最多100個鏈接。在高併發狀況下會出現瓶頸,不推薦熱點應用使用。