摘要:无法形容,直接对产生了满分好感于是直接打开源码目录全局搜,找到,如下一段注释掉了上面这些,跑起来没有问题,这样的问题就解决了。那么查一下,有说设置注册表的感觉并不是解决办法实测也不能解决问题。
背景
我司的软件在一个客户处测试功能和性能,这个客户比较特殊:
他们客户端是很旧的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应该也能做到无损耗的,twisted库不知道有什么多余操作,有时间应该裸写一个反向代理看看。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/73608.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...
阅读 610·2021-11-22 15:32
阅读 2709·2021-11-19 09:40
阅读 2272·2021-11-17 09:33
阅读 1247·2021-11-15 11:36
阅读 1846·2021-10-11 10:59
阅读 1457·2019-08-29 16:41
阅读 1733·2019-08-29 13:45
阅读 2129·2019-08-26 13:36