Java生產環境下性能監控與調優詳解


1:JVM字節碼指令與 javap
javap <options> <classes>
cd monitor_tuning/target/classes/org/alanhou/monitor_tuning/chapter8/
javap -verbose Test1.class > Test1.txt 即可保存字節碼文件
會有三個部分組成
操作數棧
LineNumberTable
LocalVariableTable

i++和++i 的執行效果完全相同 多了一個壓入棧頂操作
for(int i=0;i<10;i++) {}
for(int i=0;i<10;++i) {} 執行效果一樣

 

2:

public static void f1() {
String src = "";
for(int i=0;i<10;i++) {
//每一次循環都會new一個StringBuilder 然后在src.append("A");
src = src + "A";
}
System.out.println(src);
}
public static void f2() {
//只要一個StringBuilder
StringBuilder src = new StringBuilder();
for(int i=0;i<10;i++) {
src.append("A");
}
System.out.println(src);
}

 

3:

public static String f1() {
String str = "hello";
try{
return str;
}
finally{
str = "imooc";
}
} 返回 hello 但會執行finally 中的代碼

 

4:字符串拼接都會在編譯階段轉換成stringbuilder

5:字符串去重

字符串在任何應用中都占用了大量的內存。尤其數包含獨立UTF-16字符的char[]數組對JVM內存的消耗貢獻最多——因為每個字符占用2位。

內存的30%被字符串消耗其實是很常見的,不僅是因為字符串是與我們互動的最好的格式,而且是由於流行的HTTP API使用了大量的字符串。使用Java 8 Update 20,我們現在可以接觸到一個新特性,叫做字符串去重,該特性需要G1垃圾回收器,該垃圾回收器默認是被關閉的。

字符串去重利用了字符串內部實際是char數組,並且是final的特性,所以JVM可以任意的操縱他們。

 

對於字符串去重,開發者考慮了大量的策略,但最終的實現采用了下面的方式:

無論何時垃圾回收器訪問了String對象,它會對char數組進行一個標記。它獲取char數組的hash value並把它和一個對數組的弱引用存在一起。只要垃圾回收器發現另一個字符串,而這個字符串和char數組具有相同的hash code,那么就會對兩者進行一個字符一個字符的比對。

如果他們恰好匹配,那么一個字符串就會被修改,指向第二個字符串的char數組。第一個char數組就不再被引用,也就可以被回收了。

這整個過程當然帶來了一些開銷,但是被很緊實的上限控制了。例如,如果一個字符未發現有重復,那么一段時間之內,它會不再被檢查。

 

那么該特性實際上是怎么工作的呢?首先,你需要剛剛發布的Java 8 Update 20,然后按照這個配置: -Xmx256m -XX:+UseG1GC 去運行下列的代碼:

public class LotsOfStrings {     private static final LinkedList<String> LOTS_OF_STRINGS = new LinkedList<>();     public static void main(String[] args) throws Exception {     int iteration = 0;     while (true) {       for (int i = 0; i < 100; i++) {         for (int j = 0; j < 1000; j++) {           LOTS_OF_STRINGS.add(new String("String " + j));         }       }       iteration++;       System.out.println("Survived Iteration: " + iteration);       Thread.sleep(100);     }   } }

這段代碼會執行30個迭代之后報OutOfMemoryError。

現在,開啟字符串去重,使用如下配置去跑上述代碼:

-Xmx256m -XX:+UseG1GC -XX:+UseStringDeduplication -XX:+PrintStringDeduplicationStatistics

此時它已經可以運行更長的時間,而且在50個迭代之后才終止。

6:

ArrayLIst  底層是數組  擴容會拷貝
hashmap 底層也是數組+ 鏈表 擴容 重新計算key 負載因子是 0.75

linklist底層是雙向鏈表
1. 盡量重用對象,不要循環創建對象,比如:for 循環字符串拼接(不在 for中使用+拼接,先new 一個StringBuilder再在 for 里 append)

2. 容器類初始化的地時候指定長度

List<String> collection = new ArrayLIst<String>(5);

Map<String, String> map = new HashMap<String, String>(32);

3. ArrayList(底層數組)隨機遍歷快,LinkedList(底層雙向鏈表)添加刪除快

4. 集合遍歷盡量減少重復計算

5. 使用 Entry 遍歷 Map可以同時取出key和value

6. 大數組復制使用System.arraycopy 底層是native實現的

7. 盡量使用基本類型而不是包裝類型

public class Test03 {

public static void main(String[] args) {
Integer f1 = 100, f2 = 100, f3 = 150, f4 = 150;

System.out.println(f1 == f2);
System.out.println(f3 == f4);
}
}

如果不明就里很容易認為兩個輸出要么都是true要么都是false。首先需要注意的是f1、f2、f3、f4四個變量都是Integer對象引用,所以下面的==運算比較的不是值而是引用。裝箱的本質是什么呢?當我們給一個Integer對象賦一個int值的時候,會調用Integer類的靜態方法valueOf,如果看看valueOf的源代碼就知道發生了什么。
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
簡單的說,如果整型字面量的值在-128到127之間,那么不會new新的Integer對象,而是直接引用常量池中的Integer對象,所以上面的面試題中f1==f2的結果是true,而f3==f4的結果是false。
8. 不要手動調用 System.gc()

9. 及時消除過期對象的引用,防止內存泄漏
public string pop()
{
string currentValue=object[size];
//object[size]=null;如果不添加這句話就會造成內存泄漏
size--;
return currentValue;
}

10. 盡量使用局部變量,減小變量的作用域 方便出了作用域盡快垃圾回收

11. 盡量使用非同步的容器ArraryList vs. Vector

12. 盡量減小同步作用范圍, synchronized 方法 vs. 代碼塊


public class SynchronizedTest {
public static void main(String[] args) {
}
public synchronized void f1() {//在this對象上加鎖
System.out.println("f1");
}
public void f2() {//在this對象上加鎖
synchronized(this) {
System.out.println("f2");
}
}
public static synchronized void f3() {//在類上加鎖
System.out.println("f3");
}
public static void f4() {//在類上加鎖
synchronized(SynchronizedTest.class) {
System.out.println("f4");
}
}
}

13. 用ThreadLocal 緩存線程不安全的對象,SimpleDateFormat 緩存重量的對象避免重新構造
@SuppressWarnings("rawtypes")
private static ThreadLocal threadLocal = new ThreadLocal() {
protected synchronized Object initialValue() {
return new SimpleDateFormat(DATE_FORMAT);
}
};

14. 盡量使用延遲加載

15. 盡量減少使用反射,必須用加緩存,反射比較影響性能

16. 盡量使用連接池、線程池、對象池、緩存

17. 及時釋放資源, I/O 流、Socket、數據庫連接

18. 慎用異常,不要用拋異常來表示正常的業務邏輯,異常也是比較重的對象要記錄堆棧信息

19. String 操作盡量少用正則表達式 比如replaceAll是用正則 比較耗費性能 replace就不是用正則

20. 日志輸出注意使用不同的級別

21. 日志中參數拼接使用占位符
log.info("orderId:" + orderId); 不推薦 會用字符串拼接
log.info("orderId:{}", orderId); 推薦 用占位符 不會進行字符串拼接


7:JVM的參數類型

標准參數(各版本中保持穩定)

-help

-server -client

-version -showversion

-cp -classpath

 

X 參數(非標准化參數)

-Xint:解釋執行

-Xcomp:第一次使用就編譯成本地代碼

-Xmixed:混合模式,JVM 自己決定是否編譯成本地代碼

示例:

java -version(默認是混合模式)

Java HotSpot(TM) 64-Bit Server VM (build 25.40-b25, mixed mode)

java -Xint -version

Java HotSpot(TM) 64-Bit Server VM (build 25.40-b25, interpreted mode)

 

XX 參數(非標准化參數)

主要用於 JVM調優和 debug

  • Boolean類型

格式:-XX:[+-]<name>表示啟用或禁用 name 屬性
如:-XX:+UseConcMarkSweepGC
-XX:+UseG1GC
  • 非Boolean類型

格式:-XX:<name>=<value>表示 name 屬性的值是 value
如:-XX:MaxGCPauseMillis=500
-xx:GCTimeRatio=19
-Xmx -Xms屬於 XX 參數
-Xms 等價於-XX:InitialHeapSize
-Xmx 等價於-XX:MaxHeapSize
-xss 等價於-XX:ThreadStackSize

查看

 

-XX:+PrintFlagsInitial 查看jvm初始值

-XX:+PrintFlagsFinal 查看jvm最終值

-XX:+UnlockExperimentalVMOptions 解鎖實驗參數

-XX:+UnlockDiagnosticVMOptions 解鎖診斷參數

-XX:+PrintCommandLineFlags 打印命令行參數

輸出結果中=表示默認值,:=表示被用戶或 JVM 修改后的值

示例:java -XX:+PrintFlagsFinal -version

 

補充:測試中需要用到 Tomcat,CentOS 7安裝示例如下

1
2
3
4
5
6
sudo  yum -y  install  java-1.8.0-openjdk*
wget  http: //mirror .bit.edu.cn /apache/tomcat/tomcat-8/v8 .5.32 /bin/apache-tomcat-8 .5.32. tar .gz
tar  -zxvf apache-tomcat-8.5.32. tar .gz 
mv  apache-tomcat-8.5.32 tomcat
cd  tomcat /bin/
sh startup.sh

pid 可通過類似 ps -ef|grep tomcat或 jps來進行查看

jps

查看java進程 -l 可以知道完全類名

jinfo

jinfo -flag MaxHeapSize <pid>

jinfo -flags <pid>  手動賦過值的參數

 

jstat

可以查看jvm的統計信息 如類加載。垃圾回收信息,jit編譯信息

詳情參考 jstat 官方文檔

jstat 使用示例

類加載

# 以下1000表每隔1000ms 即1秒,共輸出10次
jstat -class <pid> 1000 10

垃圾收集

-gc, -gcutil, -gccause, -gcnew, -gcold

jstat -gc <pid> 1000 10

以下大小的單位均為 KB

 

 

S0C, S1C, S0U, S1U: S0和 S1的總量和使用量

EC, EU: Eden區總量與使用量

OC, OU: Old區總量與使用量

MC, MU: Metacspace區(jdk1.8前為 PermGen)總量與使用量

CCSC, CCSU: 壓縮類區總量與使用量

YGC, YGCT: YoungGC 的次數與時間

FGC, FGCT: FullGC 的次數與時間

GCT: 總的 GC 時間

JIT 編譯

-compiler, -printcompilation

一個對象默認分配在堆上面 但是有個指針指向class默認是64位長指針,可以設置為用32位存儲在壓縮類空間
非堆區 即對應於虛擬機規范中的方法區 是操作系統本地內存 獨立於jvm堆區之外 jdk8后面叫metaspace jdk8前面叫performancespace
codecache 存儲的是jit即時編譯的代碼 以及native代碼

jmap+MAT

詳情參考jmap 官方文檔

內存溢出演示:

https://start.spring.io/生成初始代碼

最終代碼:monitor_tuning

為快速產生內存溢出,右擊 Run As>Run Configurations, Arguments 標簽VM arguments 中填入

-Xmx32M -Xms32M

訪問 http://localhost:8080/heap

Exception in thread "http-nio-8080-exec-2" Exception in thread "http-nio-8080-exec-1" java.lang.OutOfMemoryError: Java heap space
java.lang.OutOfMemoryError: Java heap space

-XX:MetaspaceSize=32M -XX:MaxMetaspaceSize=32M(同時在 pom.xml 中加入 asm 的依賴)

訪問 http://localhost:8080/nonheap

Exception in thread "main" java.lang.OutOfMemoryError: Metaspace
Exception in thread "ContainerBackgroundProcessor[StandardEngine[Tomcat]]" java.lang.OutOfMemoryError: Metaspace

內存溢出自動導出

-XX:+HeapDumpOnOutOfMemoryError

-XX:HeapDumpPath=./

右擊 Run As>Run Configurations, Arguments 標簽VM arguments 中填入

-Xmx32M -Xms32M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./

可以看到自動在當前目錄中生成了一個java_pid660.hprof文件

java.lang.OutOfMemoryError: GC overhead limit exceeded
Dumping heap to ./java_pid660.hprof ...

另一種導出溢出也更推薦的方式是jmap

option: -heap, -clstats, -dump:<dump-options>, -F

jmap -dump:format=b,file=heap.hprof <pid>

 

jmap 導出溢出文件

MAT下載地址:http://www.eclipse.org/mat/

找開上述導出的內存溢出文件即可進行分析,如下圖的溢出源頭分析:

Memory Analyzer 內存溢出分析

  1. Histogram可以列出內存中的對象,對象的個數以及大小。
  2. Dominator Tree可以列出那個線程,以及線程下面的那些對象占用的空間。

Histogram

    

  • Class Name : 類名稱,java類名

  • Objects : 類的對象的數量,這個對象被創建了多少個

  • Shallow Heap :一個對象內存的消耗大小,不包含對其他對象的引用

  • Retained Heap :是shallow Heap的總和,也就是該對象被GC之后所能回收到內存的總和

Dominator Tree

我們可以看到ibatis占了較多內存

快速找出某個實例沒被釋放的原因,可以右健 Path to GC Roots-->exclue all phantom/weak/soft etc. reference :

 
 

得到的結果是:

 
 

從表中可以看出 PreferenceManager -> … ->HomePage這條線路就引用着這個 HomePage實例。用這個方法可以快速找到某個對象的 GC Root,一個存在 GC Root的對象是不會被 GC回收掉的.

jstack

詳情參考 jstack 官方文檔

jstack <pid>  打印jvm內部所有的線程

 jstack 15672 >15673.txt  導出當前進程文件

可查看其中包含java.lang.Thread.State: WAITING (parking),JAVA 線程包含的狀態有:

NEW:線程尚未啟動

RUNNABLE:線程正在 JVM 中執行

BLOCKED:線程在等待監控鎖(monitor lock)

WAITING:線程在等待另一個線程進行特定操作(時間不確定)

TIMED_WAITING:線程等待另一個線程進行限時操作

TERMINATED:線程已退出

 
           

此時會生成一個monitor_tuning-0.0.1-SNAPSHOT.jar的 jar包,為避免本地的 CPU 消耗過多導致死機,建議上傳上傳到虛擬機進行測試

nohup java -jar monitor_tuning-0.0.1-SNAPSHOT.jar &

訪問 http://xx.xx.xx.xx:12345/loop(端口12345在application.properties文件中定義)

 

top 是查詢所有進程的cpu 占用率
top還可以用來顯示一個進程中各個線程CPU的占用率:top -p <pid> -H
top命令如下

 

top -p <pid>  -H 命令如下 看的是7930的進程
 
           

使用 jstack <pid>可以導出追蹤文件,文件中 PID 在 jstack 中顯示的對應 nid 為十六進制(命令行可執行 print '%x' <pid>可以進行轉化,如1640對應的十六進制為668)

"http-nio-12345-exec-3" #18 daemon prio=5 os_prio=0 tid=0x00007f10003fb000 nid=0x668 runnable [0x00007f0fcf8f9000]
   java.lang.Thread.State: RUNNABLE
	at org.alanhou.monitor_tuning.chapter2.CpuController.getPartneridsFromJson(CpuController.java:77)
...

訪問http://xx.xx.xx.xx:12345/deadlock(如上jstack <pid>導出追蹤記錄會發現如下這樣的記錄)

 


Java stack information for the threads listed above: =================================================== "Thread-5": at org.alanhou.monitor_tuning.chapter2.CpuController.lambda$deadlock$1(CpuController.java:41) - waiting to lock <0x00000000edcf3470> (a java.lang.Object) - locked <0x00000000edcf3480> (a java.lang.Object) at org.alanhou.monitor_tuning.chapter2.CpuController$$Lambda$337/547045985.run(Unknown Source) at java.lang.Thread.run(Thread.java:748) "Thread-4": at org.alanhou.monitor_tuning.chapter2.CpuController.lambda$deadlock$0(CpuController.java:33) - waiting to lock <0x00000000edcf3480> (a java.lang.Object) - locked <0x00000000edcf3470> (a java.lang.Object) at org.alanhou.monitor_tuning.chapter2.CpuController$$Lambda$336/1704575158.run(Unknown Source) at java.lang.Thread.run(Thread.java:748) Found 1 deadlock.
查看后台日志,都是使用tail -f catalina.out命令來查看

jvisualvm 圖形化工具
插件安裝Tools>Plugins>Settings根據自身版本(java -version)更新插件中心地址,各版本查詢地址:
http://visualvm.github.io/pluginscenters.html
建議安裝:Visual GC, BTrace Workbench
概述 監控可以堆dump 線程可以線程dump 抽樣器可以對cpu和內存進行抽樣調查
 
           

以上是本地的JAVA進程監控,還可以進行遠程的監控,在上圖左側導航的 Applications 下的 Remote 處右擊Add Remote Host...,輸入主機 IP 即可添加,在 IP 上右擊會發現有兩種連接 JAVA 進程進行監控的方式:JMX, jstatd

bin/catalina.sh(以192.168.0.5為例)

JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9004 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.net.preferIPv4Stack=true -Djava.rmi.server.hostname=192.168.0.5"

啟動tomcat,

啟動tomcat服務
方式一:直接啟動 ./startup.sh
方式二:作為服務啟動 nohup ./startup.sh &
查看tomcat運行日志
tail -f catalina.out
tomcat設置jvm參數
修改文件 apache-tomcat-9.0.10/bin下catalina.bat文件

以 JMX 為例,在 IP 上右擊點擊Add JMX Connection...,輸入 IP:PORT

Add JMX Connection

以上為 Tomcat,其它 JAVA 進程也是類似的,如:

nohup java -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9005 -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.net.preferIPv4Stack=true -Djava.rmi.server.hostname=192.168.0.5 -jar monitor_tuning-0.0.1-SNAPSHOT.jar &

 

 BTrace

BTrace 可以動態地向目標應用程序的字節碼注入追蹤代碼,使用的技術有 JavaCompilerApi, JVMTI, Agent, Instrumentation+ASM

使用方法:JVisualVM中添加 BTrace 插件

方法二:btrace <pid> <trace_script>

btrace只能調試本地進程
btrace修改后的字節碼不能被還原
pom.xml 中添加 btrace-agent, btrace-boot, btrace-client的依賴


攔截構造方法
攔截同名方法

攔截返回值

攔截行號
攔截異常信息
攔截復雜類型
攔截正則表達式
攔截環境參數信息




常用參數:

-Xms -Xmx

-XX:NewSize -XX:MaxNewSize

-XX:NewRatio -XX:SurvivorRatio

-XX:MetaspaceSize -XX:MaxMetaspaceSize 以下幾個參數通常這樣只設置這個值即可

-XX:+UseCompressedClassPointers

-XX:CompressedClassSpaceSize

-XX:InitialCodeCacheSize

-XX:ReservedCodeCacheSize


Tomcat 遠程 Debug

JDWP

bin/startup.sh 修改最后一行(添加 jpda)

exec "$PRGDIR"/"$EXECUTABLE" jpda start "$@"

bin/catalina.sh 為便於遠程調試進行如下修改

JPDA_ADDRESS="localhost:8000"
# 修改為
JPDA_ADDRESS="54321"

若發現54321端口啟動存在問題可嘗試bin/catalina.sh jpda start


使用 Eclipse 遠程調試,右擊 Debug As > Debug Configurations... > Remote Java Application > 右擊 New 新建
普通java進程可以這樣配置 
java -jar -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=10001 access-10000.jar

tomcat-manager 監控

1.conf/tomcat-users.xml添加用戶

  <role rolename="tomcat"/>
  <role rolename="manager-status"/>
  <role rolename="manager-gui"/>
  <user username="tomcat" password="123456" roles="tomcat,manager-gui,manager-status"/>

2.conf/Catalina/localhost/manager.xml配置允許的遠程連接

<?xml version="1.0" encoding="UTF-8"?>
<Context privileged="true" antiResourceLocking="false"
        docBase="$(catalina.home)/webapps/manager">
  <Valve className="org.apache.catalina.valves.RemoteAddrValve"
        allow="127\.0\.0\.1" />
</Context>

遠程連接將allow="127\.0\.0\.1"修改為allow="^.*$",瀏覽器中輸入http://127.0.0.1:8080/manage或對應的 IP,用戶名密碼為tomcat-users.xml中所設置的

3.重啟 Tomcat 服務

Tomcat Manager

psi-probe 監控

下載地址:https://github.com/psi-probe/psi-probe,

下載后進入psi-probe-master目錄,執行:

mvn clean package -Dmaven.test.skip

將 web/target/probe.war放到 Tomcat 的 webapps 目錄下,同樣需要conf/tomcat-users.xml和conf/Catalina/localhost/manager.xml中的配置(可保持不變),啟動 Tomcat 服務

瀏覽器中輸入http://127.0.0.1:8080/probe或對應的 IP,用戶名密碼為tomcat-users.xml中所設置的

PSI Probe演示


Tomcat 調優

線程優化(webapps/docs/config/http.html):

maxConnections

acceptCount

maxThreads

minSpareThreads

配置優化(webapps/docs/config/host.html):

autoDeploy

enableLookups(http.html)

reloadable(context.html)

protocol="org.apache.coyote.http11.Http11AprProtocol"

Session 優化:

如果是 JSP, 可以禁用 Session


Nginx 性能監控與調優

Nginx 安裝

添加 yum 源(/etc/yum.repos.d/nginx.repo)

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basesearch/
gpgcheck=0
enabled=1

安裝及常用命令

yum install -y nginx
systemctl status|start|stop|reload|restart nginx
nginx -s stop|reload|quit|reopen nginx 啟動nginx
cat default.conf | grep -v "#' > default2.conf 移除配置文件中的注釋 並生成新的配置文件
nginx -V
nginx -t

配置反向代理 setenforce 0

ngx_http_stub_status 監控連接信息

 

 

location = /nginx_status {
    stub_status on;
    access_log off;
    allow 127.0.0.1;
    deny all;
}

可通過curl http://127.0.0.1/nginx_status 進行查看或注釋掉 allow 和 deny 兩行使用 IP 進行訪問

ngxtop監控請求信息

 

查看官方使用方法:https://github.com/lebinh/ngxtop

 

# 安裝 python-pip
yum install epel-release
yum install python-pip
# 安裝 ngxtop
pip install ngxtop

使用示例

指定配置文件:ngxtop -c /etc/nginx/nginx.conf

查詢狀態是200:ngxtop -c /etc/nginx/nginx.conf -i 'status == 200'

查詢訪問最多 ip:ngxtop -c /etc/nginx/nginx.conf -g remote_addr

ngxtop查詢訪問最多 ip

 

Nginx 優化

增加工作線程數和並發連接數

worker_processes  4; # 一般CPU 是幾核就設置為幾
events {
    worker_connections  1024; # 每個進程打開的最大連接數,包含了 Nginx 與客戶端和 Nginx 與 upstream 之間的連接
    multi_accept on; # 可以一次建立多個連接
    use epoll;
}

啟用長連接

upstream server_pool{
    server localhost:8080 weight=1 max_fails=2 fail_timeout=30s;
    server localhost:8081 weight=1 max_fails=2 fail_timeout=30s;
    keepalive 300; # 300個長連接
}
location / {
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_pass http://server_pool;
}

啟用緩存壓縮

gzip on;
gzip_http_version 1.1;
gzip_disable "MSIE [1-6]\.(?!.*SV1)";
gzip_proxied any;
gzip_types text/plain text/css application/javascript application/x-javascript application/json application/xml application/vnd.ms-fontobject application/x-font-ttf application/svg+xml application/x-icon;
gzip_vary on;
gzip_static on;

操作系統優化

# 配置文件/etc/sysctl.conf
sysctl -w net.ipv4.tcp_syncookies=1 # 防止一個套接字在有過多試圖連接到時引起過載
sysctl -w net.core.somaxconn=1024 # 默認128,連接隊列
sysctl -w net.ipv4.tcp_fin_timeout=10 # timewait 的超時時間
sysctl -w net.ipv4.tcp_tw_reuse=1 # os 直接使用 timewait的連接
sysctl -w net.ipv4.tcp_tw_recycle=0 # 回收禁用

# /etc/security/limits.conf
*               hard    nofile            204800
*               soft    nofile             204800
*               soft    core             unlimited
*               soft    stack             204800

其它優化

sendfile	on; # 減少文件在應用和內核之間拷貝
tcp_nopush	on; # 當數據包達到一定大小再發送
tcp_nodelay	off; # 有數據隨時發送

 




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM