摘要:無法形容,直接對產生了滿分好感于是直接打開源碼目錄全局搜,找到,如下一段注釋掉了上面這些,跑起來沒有問題,這樣的問題就解決了。那么查一下,有說設置注冊表的感覺并不是解決辦法實測也不能解決問題。
背景
我司的軟件在一個客戶處測試功能和性能,這個客戶比較特殊:
他們客戶端是很舊的java代碼,且要求不能改動,客戶端的主要業務簡單說就是上傳下載文件
他們提供了客戶端demo,http請求是用裸socket手動加http頭,寫死了http1.1,但又不帶host這個http頭
客戶要求中間必須經過一臺windows server服務器代理
后端的實際服務器是linux系統,用的是nginx
host header問題(此時先直連后端服務,不考慮代理)最開始是請求直接返400,nginx access log可以看到400但是沒有更多信息,error log則沒有任何信息打印,一開始另一位同事負責定位,我跟著一起用wireshark抓包看了很久,沒得出結論。后來我又看了一下,nginx error log默認的日志級別是crit,那么直接改到debug,看到這個信息:
那么問題就一目了然了,查了一下,這個header是http1.1要求必須帶的
且nginx嚴格遵守該協議,沒有提供可配置的方式忽略這個頭,如上圖按理說服務端不應該強行處理這種問題,但客戶要求最高,沒辦法
這時候好在,正好我們需要一層反向代理,那么,看看能不能找一個允許不帶該header的反向代理服務器實現,接下來可以暫時忽略這個問題,我們使用壓測工具測性能,壓測工具在這個header上是沒有問題的
代理布署及性能問題windows server系統的服務器,一開始我們直接用Nginx,但簡單測后就知道性能很差,搜了一下基本是說nginx和apache在windows上性能都沒啥希望,首推的基本還是微軟自家的IIS,于是我們配起了IIS,果然性能與直連后端相比基本沒有損耗,但是經過很長時間查資料,找不到配置忽略host header的方法,而且IIS的確不好用,配置比較難看懂,大家都不熟悉windows平臺,接下來只能另辟蹊徑
python:老本行,用twisted寫了個4行的反向代理,性能不如nginx,大概只有直連的1/6,時間緊迫,沒來得及分析,繼續嘗試其他語言
nodejs:在github找到個redbird庫,代碼也是只需要兩行,但性能跟python半斤八兩
java:撿了個undertow的框架,折騰挺久終于搞起來,倒是基本沒有性能損耗,于是就要解決header問題,但是這個版本的400返回沒帶提示信息,java框架源碼要反編譯看,倒也還好,但是沒有錯誤信息,不好直接搜代碼,只能看流程,比較難看,java接觸的也少
go:代碼倒是長一些,有三十來行,但是只用到了go的標準庫,性能不出意外也是等于直連,驚喜的來了,它的400帶了個錯誤信息提示:missing required Host header,當時那個幸福感。。。無法形容,直接對go產生了滿分好感
于是直接打開源碼目錄全局搜,找到src/net/http/server.go,如下一段
`
// hosts, haveHost := req.Header["Host"] isH2Upgrade := req.isH2Upgrade() // if req.ProtoAtLeast(1, 1) && (!haveHost || len(hosts) == 0) && !isH2Upgrade && req.Method != "CONNECT" { // return nil, badRequestError("missing required Host header") // } // if len(hosts) > 1 { // return nil, badRequestError("too many Host headers") // } // if len(hosts) == 1 && !httpguts.ValidHostHeader(hosts[0]) { // return nil, badRequestError("malformed Host header") // }
`
注釋掉了上面這些,跑起來沒有問題,這樣host header的問題就解決了。
但是到這還沒結束,壓測跑了一會兒發現請求全部失敗,看了一下報錯,socket爆了,在cmd里netstat查了一下,果然go進程接近2w的socket消耗,全部是TIME_WAIT狀態
本端主動關閉的socket,就會進入TIME_WAIT狀態,被對方關閉是CLOSE_WAIT。那么查一下windows socket time_wait,有說設置注冊表的
[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetservicesTcpipParameters]
"TcpTimedWaitDelay"=dword:0000001e
感覺并不是解決辦法?實測也不能解決問題。想想也知道關鍵應該是找到為什么go會頻繁關閉socket,那么google的關鍵字就應該是這樣了:go socket time_wait
搜索結果第一條stackoverflow的就是答案:https://stackoverflow.com/que...
在main函數里加上配置:
http.DefaultTransport.(*http.Transport).MaxIdleConns = 8192
http.DefaultTransport.(*http.Transport).MaxIdleConnsPerHost = 8192
這個值的含義見鏈接,簡單說就是允許保持的最大tcp連接數,默認值是2(待研究為什么要這樣默認),超過后會一直關socket再重開,我們壓測工具跑的是100并發,實際只需要這個值是200就夠了(因為往real server的那個方向還需要同樣的連接數 所以*2)
想想python應該也能做到無損耗的,暫時沒有再去研究,但從簡單使用來看,腳本語言畢竟是腳本語言,你大爺還是你大爺。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/40352.html
摘要:無法形容,直接對產生了滿分好感于是直接打開源碼目錄全局搜,找到,如下一段注釋掉了上面這些,跑起來沒有問題,這樣的問題就解決了。那么查一下,有說設置注冊表的感覺并不是解決辦法實測也不能解決問題。 背景 我司的軟件在一個客戶處測試功能和性能,這個客戶比較特殊: 他們客戶端是很舊的java代碼,且要求不能改動,客戶端的主要業務簡單說就是上傳下載文件 他們提供了客戶端demo,http請求是...
摘要:客戶端必須要進行一些特別的設置才能使用正向代理。正向代理還可以使用緩沖特性減少網絡使用率。反向代理的典型用途是將防火墻后面的服務器提供給用戶訪問。反向代理對外都是透明的,訪問者并不知道自己訪問的是一個代理。 一、相關概念 代理一般分為正向代理和反向代理,以下是他們的定義(以下內容引自網上) 正向代理,也就是傳說中的代理,他的工作原理就像一個跳板,簡單的說,我是一個用戶,我訪問不了某網...
摘要:一代理簡介代理代理服務正向代理和反向代理區別在于代理的對象不一樣。 一、代理簡介 1. 代理 showImg(https://segmentfault.com/img/remote/1460000015873425?w=556&h=248); 2. Nginx代理服務 showImg(https://segmentfault.com/img/remote/146000001587342...
閱讀 1325·2023-04-26 00:10
閱讀 2427·2021-09-22 15:38
閱讀 3745·2021-09-22 15:13
閱讀 3503·2019-08-30 13:11
閱讀 646·2019-08-30 11:01
閱讀 3028·2019-08-29 14:20
閱讀 3207·2019-08-29 13:27
閱讀 1724·2019-08-29 11:33