文章很長,建議收藏起來,慢慢讀! 瘋狂創客圈為小伙伴奉上以下珍貴的學習資源:
- 瘋狂創客圈 經典圖書 : 《Netty Zookeeper Redis 高並發實戰》 面試必備 + 大廠必備 + 漲薪必備
- 瘋狂創客圈 經典圖書 : 《SpringCloud、Nginx高並發核心編程》 面試必備 + 大廠必備 + 漲薪必備
- 瘋狂創客圈 價值1000元 百度網盤資源大禮包 隨便取 GO->【博客園總入口 】
- 獨孤九劍 Netty靈魂實驗 : 本地 100W連接 高並發實驗,瞬間提升Java內力
價值連城:2021春招月薪過5萬 面試題 總系列
搞定下面這些面試題,2021春招月薪過5萬(猛!) | 阿里、京東、美團、頭條.... 隨意挑、橫着走!!! |
---|---|
Java基礎 | |
1: JVM面試題(史上最強、持續更新、吐血推薦) | https://www.cnblogs.com/crazymakercircle/p/14365820.html |
2:Java基礎面試題(史上最全、持續更新、吐血推薦) | https://www.cnblogs.com/crazymakercircle/p/14366081.html |
3:死鎖面試題(史上最強、持續更新) | [https://www.cnblogs.com/crazymakercircle/p/14323919.html] |
4:設計模式面試題 (史上最全、持續更新、吐血推薦) | https://www.cnblogs.com/crazymakercircle/p/14367101.html |
5:架構設計面試題 (史上最全、持續更新、吐血推薦) | https://www.cnblogs.com/crazymakercircle/p/14367907.html |
還有 10 幾篇 篇價值連城 的面試題 | 具體..... 請參見【 瘋狂創客圈 高並發 總目錄 】 |
萬字長文: 瘋狂創客圈 springCloud 高並發系列
springCloud 高質量 博文 | |
---|---|
nacos 實戰(史上最全) | sentinel (史上最全+入門教程) |
springcloud + webflux 高並發實戰 | Webflux(史上最全) |
SpringCloud gateway (史上最全) | |
還有 10 幾篇 萬字長文 的高質量 博文 | 具體..... 請參見【 瘋狂創客圈 高並發 總目錄 】 |
1錯誤信息
Connection reset by peer
nginx的錯誤日志中會出現
Connection reset by peer) while reading response header from upstream, client: 1.1.1.1, server: 102.local, request: "GET / HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000
日志查看方法
這個錯誤是在nginx的錯誤日志中發現的,為了更全面的掌握nginx運行的異常,強烈建議在nginx的全局配置中增加
error_log logs/error.log notice;
這樣,就可以記錄nginx的詳細異常信息。
2 原因一:連接已經被上游close。
服務端確實已經關閉了連接: upstream發送了RST,將連接重置。
errno = 104 錯誤表明你在對一個對端socket已經關閉的的連接調用write或send方法,在這種情況下,調用write或send方法后,對端socket便會向本端socket發送一個RESET信號,在此之后如果繼續執行write或send操作,就會得到errno為104,錯誤描述為connection reset by peer。
如果對方socket已經執行了close的操作,本端socket還繼續在這個連接上收發數據,就會觸發對端socket發送RST報文。按照TCP的四次握手原理,這時候本端socket應該也要開始執行close的操作流程了,而不是接着收發數據。
- 比如,當后端為php程序時,如果php運行較慢,並超出php-fpm.conf的request_terminate_timeout設置的秒數。request_terminate_timeout用於設置當某個php腳本運行最長時間,若超出php-fpm進程管理器強行中止當前程序,並關閉fastcgi和nginx的網絡連接,然后nginx中就會出現Connection reset by peer的錯誤了。
也就是說,產生這個錯誤的原因是:php 程序的運行時間超出request_terminate_timeout設置的值。
在php-fpm環境下,在php的安裝目錄的etc/php-fpm.conf中有此值的設置項,可將其設置為0或更大的值。這樣將php的request_terminate_timeout設置為較大的值或0,可減少因php腳本執行時行過長導致nginx產生Connection reset by peer錯誤。
- 比如,當后端為java 程序時,
java 的也類似,不能Java端主動關閉連接。 如果上游的tomcat 或者 netty 已經關閉連接, 那么nginx 肯定就是 Connection reset by peer
3 原因二:數據長度不一致
發送端和接收端事先約定好的數據長度不一致導致的,接收端被通知要收的數據長度小於發送端實際要發送的數據長度。
4 原因三: FastCGI 緩存小,timeout太小。
nginx的buffer太小,timeout太小。主要指php的環境,nginx如果要解析php腳本語言,就必須通過配置fastcgi模塊來提供對php支持。
問題概述:圖片bit 64生成數據流太大,導致小程序分享彈窗的二維碼圖片生成失敗
nginx http模塊添加以下參數配置:
fastcgi_buffer_size 128k;
fastcgi_buffers 4 128k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
后台報錯:
排查:
Client------>nginx------->h5------>nginx---------->client
客戶端通過h5的nginx頁面點擊,nginx反向代理到h5 [無異常]
h5通過客戶端請求調取相應接口 [無異常]
接口返回數據通過nginx展示給客戶端 [異常]
Ps: 圖片通過bit 64解析生成返回給客戶端,由於數據長度太長導致
解決方法:
調整nginx配置文件參數,修改后參數:
fastcgi_buffer_size 256k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
先簡單的說一下 Nginx 的 buffer 機制,對於來自 FastCGI Server 的 Response,Nginx 將其緩沖到內存中,然后依次發送到客戶端瀏覽器。緩沖區的大小由 fastcgi_buffers 和 fastcgi_buffer_size 兩個值控制。
比如如下配置:
fastcgi_buffers 8 4K;
fastcgi_buffer_size 4K;
fastcgi_buffers 控制 nginx 最多創建 8 個大小為 4K 的緩沖區,而 fastcgi_buffer_size 則是處理 Response 時第一個緩沖區的大小,不包含在前者中。所以總計能創建的最大內存緩沖區大小是 84K+4K = 36k。而這些緩沖區是根據實際的 Response 大小動態生成的,並不是一次性創建的。比如一個 8K 的頁面,Nginx 會創建 24K 共 2 個 buffers。
當 Response 小於等於 36k 時,所有數據當然全部在內存中處理。如果 Response 大於 36k 呢?fastcgi_temp 的作用就在於此。多出來的數據會被臨時寫入到文件中,放在這個目錄下面。同時你會在 error.log 中看到一條類似 warning。
顯然,緩沖區設置的太小的話,Nginx 會頻繁讀寫硬盤,對性能有很大的影響,但也不是越大越好,沒意義,呵呵!
FastCGI緩沖設置主要參數
fastcgi_buffers 4 64k
這個參數指定了從FastCGI進程到來的應答,本地將用多少和多大的緩沖區讀取,假設一個PHP或JAVA腳本所產生頁面大小為256kb,那么會為其分配4個64kb的緩沖來緩存;若頁面大於256kb,那么大於256kb的部分會緩存到fastcgi_temp指定路徑中,這並非是個好辦法,內存數據處理快於硬盤,一般該值應該為站點中PHP或JAVA腳本所產生頁面大小中間值,如果站點大部分腳本所產生的頁面大小為256kb,那么可把值設置為16 16k,4 64k等。
fastcgi_buffer_size=64k
讀取fastcgi應答第一部分需要多大緩沖區,該值表示使用1個64kb的緩沖區讀取應答第一部分(應答頭),可以設置為fastcgi_buffers選項緩沖區大小。
fastcgi_connect_timeout=300
連接到后端fastcgi超時時間,單位秒,下同。
fastcgi_send_timeout=300
向fastcgi請求超時時間(這個指定值已經完成兩次握手后向fastcgi傳送請求的超時時間)
fastcgi_reAd_timeout=300
接收fastcgi應答超時時間,同理也是2次握手后。
5 原因四: proxy_buffer緩存小
原因就是請求的頭文件過大導致502錯誤
解決方法就是提高頭部的緩存
http{
client_header_buffer_size 5m;
location / {
proxy_buffer_size 128k;
proxy_busy_buffers_size 192k;
proxy_buffers 4 192k;
}
}
原因五:沒有設置keepalive
ngx_http_upstream_check_module這個模塊,在使用tcp檢測后端狀態時,只進行了TCP的三次握手,沒有主動斷開這個連接,而是等待服務端來斷開。當后端是nginx或者tomcat時(linux上),超時后后端會發fin包關閉這個連接。這個錯誤日志recv() failed (104: Connection reset by peer)是在后端為IIS的情況下拋出的,抓包發現IIS並不會發fin包來斷開鏈接,而是在超時后發RST包重置連接,所以導致了這個問題。
從這個問題也反應出ngx_http_upstream_check_module這個模塊還是需要完善下檢測機制的,如果是在檢測后端狀態后主動關閉這個連接,應該就不會出現connect reset這個問題
通過修改源代碼已經解決了該問題
static ngx_check_conf_t ngx_check_types[] = {
{ NGX_HTTP_CHECK_TCP,
ngx_string("tcp"),
ngx_null_string,
0,
ngx_http_upstream_check_peek_handler,
ngx_http_upstream_check_peek_handler,
NULL,
NULL,
NULL,
0,
1 },
將最后一行的1改為0即可,根據數據結構分析可得知,這個1代表啟用keepalived,所以客戶端才不會主動斷開連接,因為這是tcp的端口連通性檢查,不需要keepalived,將其改為0禁止keepalived即可。
修改之后的代碼如下:
static ngx_check_conf_t ngx_check_types[] = {
{ NGX_HTTP_CHECK_TCP,
ngx_string("tcp"),
ngx_null_string,
0,
ngx_http_upstream_check_peek_handler,
ngx_http_upstream_check_peek_handler,
NULL,
NULL,
NULL,
0,
0 },
原因六:設置lingering_close
即使你禁用了 http keepalive,nginx 仍然會嘗試處理 HTTP 1.1 pipeline 的請求。你可以配置
lingering_close off 禁用此行為,但這不是推薦的做法,因為會違反 HTTP 協議。見
http://nginx.org/en/docs/http/ngx_http_core_module.html#lingering_close
nginx快速定位異常
錯誤信息 | 錯誤說明 |
---|---|
"upstream prematurely(過早的) closed connection" | 請求uri的時候出現的異常,是由於upstream還未返回應答給用戶時用戶斷掉連接造成的,對系統沒有影響,可以忽略 |
"recv() failed (104: Connection reset by peer)" | (1)服務器的並發連接數超過了其承載量,服務器會將其中一些連接Down掉; (2)客戶關掉了瀏覽器,而服務器還在給客戶端發送數據; (3)瀏覽器端按了Stop |
"(111: Connection refused) while connecting to upstream" | 用戶在連接時,若遇到后端upstream掛掉或者不通,會收到該錯誤 |
"(111: Connection refused) while reading response header from upstream" | 用戶在連接成功后讀取數據時,若遇到后端upstream掛掉或者不通,會收到該錯誤 |
"(111: Connection refused) while sending request to upstream" | Nginx和upstream連接成功后發送數據時,若遇到后端upstream掛掉或者不通,會收到該錯誤 |
"(110: Connection timed out) while connecting to upstream" | nginx連接后面的upstream時超時 |
"(110: Connection timed out) while reading upstream" | nginx讀取來自upstream的響應時超時 |
"(110: Connection timed out) while reading response header from upstream" | nginx讀取來自upstream的響應頭時超時 |
"(110: Connection timed out) while reading upstream" | nginx讀取來自upstream的響應時超時 |
"(104: Connection reset by peer) while connecting to upstream" | upstream發送了RST,將連接重置 |
"upstream sent invalid header while reading response header from upstream" | upstream發送的響應頭無效 |
"upstream sent no valid HTTP/1.0 header while reading response header from upstream" | upstream發送的響應頭無效 |
"client intended to send too large body" | 用於設置允許接受的客戶端請求內容的最大值,默認值是1M,client發送的body超過了設置值 |
"reopening logs" | 用戶發送kill -USR1命令 |
"gracefully shutting down", | 用戶發送kill -WINCH命令 |
"no servers are inside upstream" | upstream下未配置server |
"no live upstreams while connecting to upstream" | upstream下的server全都掛了 |
"SSL_do_handshake() failed" | SSL握手失敗 |
"ngx_slab_alloc() failed: no memory in SSL session shared cache" | ssl_session_cache大小不夠等原因造成 |
"could not add new SSL session to the session cache while SSL handshaking" | ssl_session_cache大小不夠等原因造成 |
參考:
https://github.com/alibaba/tengine/issues/901
https://my.oschina.net/u/1024107/blog/1838968
https://blog.csdn.net/zjk2752/article/details/21236725
http://nginx.org/en/docs/http/ngx_http_core_module.html#lingering_close
https://blog.csdn.net/crj121624/article/details/79956283t/u/1024107/blog/1838968
https://blog.csdn.net/zjk2752/article/details/21236725
http://nginx.org/en/docs/http/ngx_http_core_module.html#lingering_close
https://blog.csdn.net/crj121624/article/details/79956283
回到◀瘋狂創客圈▶
瘋狂創客圈 - Java高並發研習社群,為大家開啟大廠之門