1.建立連接超時時間,單位毫秒【它會同時配置protocol的KeepAliveTimeout和protocol的ConnectionTimeout兩個參數】
server.connection-timeout=20000
2.Http服務(Tcp協議Socket服務)的最大連接數(其實可以有更大,畢竟一台機子上可以有6萬多個TCP端口
【注意請求來了是直接會占用maxConnections不會說先到backlog里排隊再分配connections,因為自己這邊吧backlog設置成30,maxConnections 3W,那么如果都要先在backlog里排隊等待分配,顯然
開啟3000個線程且循環8次肯定backlog被撐爆了會拒絕接受連接,但是並沒有報錯,說明連接請求是直接連接而不是需要先在backlog里】
server.tomcat.max-connections=10000
3.Http服務(Tcp服務)連接的backlog(類似線程池里的等待隊列)【好吧,Jmeter報錯Address already in use: connect是JMeter自己報的錯誤,即JMeter所在的系統也是不允許一個進程同時使用很多端口的
,所以開了keepalive超過這么多的請求數的時候就被拒絕了,而關了keepalive則不會出現這個問題,因為請求結束就釋放了端口所以不會造成超過這么多次請求的情況,windows可以通過配置注冊表解決:https://www.cnblogs.com/zhengna/p/10640620.html】
【有用,這邊設置maxConnections是50,然后backlog是3W,而有3000個線程且循環10次,如果backlog沒用百分百掛了;不過由於maxConnections很小,所以maxThreads再大也沒用,因為最多就是同時處理50個請求,因此最多只需要50個線程;
所以線程數量可以和maxConnections保持一定的比例,它倆是很關聯的;這里的吞吐量就是這個意思,處理3W個請求,但是由於maxConnections的原因只能一點一點處理,所以處理完畢花費了很久,因此tps很低】
【反正和三個配置有關,超時設置,keepalive設置和Linux允許進程最大連接數;因為如果有keepalive那么會導致進程占用的連接得不到釋放,最終就出現了地址被占用的情況】
server.tomcat.accept-count=3000
4.tomcat處理請求時的線程池的最大線程數【注意,這個最好不要超過800,最大也就2000的樣子,因為線程切換是會花費時間的,盡管增大了最大線程數可以防止同時來了很多請求導致處理很多請求沒法得到線程處理的問題,但是線程數太大即便每個請求都得到了處理但是由於切換太頻繁會浪費很多時間有時候tps反而更小;具體配多少還是要看qps是多少,然后請求的接口是CPU密集型還是IO密集型,IO等待多久都是有關系的,因此很難確定一個不變的正確的值;我這邊反正是同時開啟3000個請求循環10次,用800個線程和2000個線程最終的tps差不多;然后換成400的maxThreads tps居然比800的稍微高一點,200的和800的差不多,從測試結果來看400比較合適】
server.tomcat.max-threads=400
5.tomcat處理請求時的線程池最大核心線程數(八核的用9就夠了,一般是核數+1)
server.tomcat.min-spare-threads=17
6.處理請求超時時間(即接口內部的業務處理不能超過這個時間),單位毫秒【好吧,這個配置也不像網上說的是請求處理超時時間,我這邊在接口里sleep了足夠的秒數也沒看報錯,還是說這個只適用於特殊請求的超時?(看名字好像是異步請求)】
# 似乎是AsyncContext asyncContext = httpServletRequest.startAsync();這種方式處理接口請求的時候的超時?【經過測試也不是,所以這是個bug?】
spring.mvc.async.request-timeout=20000
注意上面這個參數沒有找到在代碼里配置對應的配置值,它不是protocol.setKeepAliveTimeout(..)的配置值,也不是connector.setAsyncTimeout(..)的配置值,不知道對應什么代碼配置;
還可以通過@Bean ServletWebServerFactory servletContainerFactory() {...}里面的connector和protocol來配置【由於用的是tomcat,所以是創建TomcatServletWebServerFactory】,可以通過TomcatWebServer來驗證;
但是這種方式配置的maxThreads和minSpareThreads和maxConnections和acceptCount均沒有生效【莫非ServletWebServerFactory要換成EmbeddedServletContainerFactory?】(但是用的protocol確實是自定義配置的protocol,然而這四個屬性被什么地方的代碼給重置了);
再進一步看了代碼,protocol.setMaxThreads(..)其實是對其內部的endpoint.setMaxThreads,get也是這樣,所以說是這個protocol內部引用的endpoint發生了改變?導致之前的set無效?
在TomcatServletWebServerFactory的配置過程里:
1.connector的protocol的keepAliveTimeout默認值是60000(60秒)【這個應該是客戶端請求如果設置可keepalive為True,即保持長連接,則服務端http1.1版本以上是默認支持的,這里則是配置服務端對客戶端請求如果沒有數據過來繼續保持長連接的時間】
2.protocol的maxKeepAliveRequests默認值是100【沒有找到對應的配置key】【這個則是允許同時保持長連接的連接數/請求數】
3.protocol的maxThreads默認值是200(但是設置沒有生效,版本是SpringBoot2.1.6.RELEASE)
4.protocol的minSpareThreads默認值是10(設置未生效)
5.protocol的maxConnections默認值是10000(設置未生效)
6.protocol的connectionTimeout默認值是60000(設置未生效)
7.connector的asyncTimeout默認值是30000(這個是用request.startAsync()方式處理請求時的超時時間)【沒有找到對應的配置key】
這些配置里沒有找到和spring.mvc.async.request-timeout對應的配置;
注意,可以用@Bean ServletWebServerFactory ...和application.properties共同配置來實現所有配置完成:
1.之前如果只用application.properties配置server.connection-timeout會同時生效於ConnectionTimeout和KeepAliveTimeout,如果在代碼里配置了則KeepaliveTimeout以代碼里的為准,但是connectionTimeout還是按配置的為准(哪怕代碼里配置了)
2.connector的asyncTimeout在配置文件里沒法配置,可以用代碼配置;
3.protocol的maxKeepaliveRequests在配置文件里也沒法配置,也可以用代碼配置;
重要:SpringBoot里用的ApplicationContext是ServletWebServerApplicationContext,通過這個可以獲取到WebServer對象,然后通過它來測試自己做的一些配置是否成功;
注意,連接超時是指發送了連接請求沒有回應才是連接超時,在backlog里並不會造成連接超時;
連接超時是服務端能設置,客戶端也能設置的,它們的值可以不同,比如客戶端是10秒,發現心跳包10秒都沒有回應,那么客戶端主動拋異常,而服務端如果是8s,那么它也是會發送心跳包給客戶端的超時沒有回應也是拋異常;
tps就是吞吐量,即每秒處理的請求數量(包括響應),如820.7/sec表示某次壓力測試下(開啟了多少線程,每個線程循環多少次)平均每秒處理完畢多少請求;(這個其實如果是多台電腦一起發起請求tps會更高一點)
這里的測試結果不能看第一輪,因為第一輪項目剛啟動所以會比較慢;
