/ gateway

gateway中keep-alive机制

前一个blog,我正纠结与对gateway项目的压测,要怎么执行。这里我仅仅提出一些,我关注的问题,希望后续的对http的进一步了解能够解答。

首先,从业务角度分析,性能瓶颈只能在backend,因为backend涉及到繁重的业务+redis、mysql等相关存储的访问。那么gateway在与backend交互时可以扮演什么样的角色(该扮演什么样的角色,我还没有想清楚)。gateway作为backend的统一client,可以控制:

  • maxconn(tcp conn最大连接数)
  • maxconnperhost(可以针对各host单独做限制)
  • tcp conn过期时间

keep-alive是针对单client多req这种情况下的性能优化,但这里涉及到取舍,conn数量越多该client性能越好,但注意server本身的资源是竞争的,不能无限制增加tcp conn,所以通常backend会维护一个pool,用来管理conn。而gateway和backend之间是lvs(负载均衡到backend集群的各个节点),所以gateway在forward的时候,我暂时将gateway视为req发起量不可预计的用户,不做控制,流量完全打到lvs上,依赖与lvs对于keep-alive的控制。当然net/http当前也是不支持这个控制的,在TODO中有描述。不过fasthttp中有实现数量和过期时间的控制。但暂时没有迁移到fasthttp的诉求,主要是对fasthttp的掌控力度,以及对它的稳定性暂时保持怀疑态度。

注意,上面划掉的部分有理解错误,修正一下,net/http可以通过设置Transport的MaxIdleConnsPerHost进行控制,限制和每个backend可以建立的conn上限。防止backend too many open files。当然backend也可以通过ulimit -u xxx提升性能。这也说明gateway在面对backend时,tcp conn的控制方法已经有明确方案。这里有掌声~~~

gateway的前面是lvs,lvs直接面对用户。这里要比与backend的交互设计麻烦些。这里的req量是真的不可预计,如果对于tcp conn的总数等做限制,长时间的高并发请求,会占满slot,导致后续的client请求都会阻塞在建立tcp连接的地方,这里就依赖于client的time out机制,如果client做的不好,肯定会影响用户体验。为了防止把tcp conn打满,需要对各gateway节点设置max tcp conn(防止资源过载)和过期时间(回收tcp conn,释放系统资源)。设置这两个参数的目的是不让gateway有可能进入到无法控制的状态。不做限制意味着监控困难,没有监控就不能在op层面做调节(例如增加机器)。所以上面两个参数发现有过载的可能性,就直接503回去,op那边监控后,增加机器即可。

看了下traefik的代码,在接收http req确实没有限制并发量,这可能导致traefik本身出现too many open files这种资源耗尽问题,但gateway前面会有lvs+nginx挡住用户端高并发访问,通过keep-alive conn与local network中的gateway沟通。所以只要gateway的benchmark合理,在prod环境合理扩展gateway服务应该没问题。

到底什么才算合理,查了下nginx的文档,可以通过max_conns(防止service overload)和queue(req达到max_conns时cache req)。通过benchmark测试gateway的上限。这样就算合理了。这么说gateway和backend之间也有nginx,gateway的限制需要根据lvs集群整体性能进行调节,但加上还是好的。

看nginx对于keep-alive的描述,net/http没有着急像fasthttp那样在接收请求时做限制,也可能是每个请求一个goroutine虽然比apache这种web server在分配资源时轻量级,但是仍旧是一种累积消耗资源的过程。与nginx这种目的就在于缓冲流量的组件不同。这里有可能也是traefik的一个设计缺陷?

max tcp conn和expired怎么计算,需要进行压力测试,得到一个gateway的数值(根据公司可以接受的硬件成本)。

nginx优化keep-alive模式

gateway中keep-alive机制
Share this