zoukankan      html  css  js  c++  java
  • 《一个 Go 程序系统线程暴涨的问题》结论

    原文地址:https://zhuanlan.zhihu.com/p/22474724

    作者的结论没写好,我来说两句。。

    结论:
    Docker swarm自己有个函数,叫setTcpUserTimeout,这个函数调用了conn.File()方法,将tcp的fd变成了blocking,而且没有关闭对应的fd。相当于每次设定tcpUserTimeout参数,再去read一下fd,都会产生一个新的线程。因为老的线程在读fd,而fd被设置成blocking了,于是golang的运行时只好再开一个新的。
    解决方法:
    不要用swarm的这个方法,或者提交到上游让swarm fixed掉,或者自己调用SetsockoptInt……
     
    好奇八卦了一下TCP_USER_TIMEOUT是什么:根据RFC 5482,这个选项是用来跟对端沟通TCP超时时间的。顺带看了一下,有关TCP超时的RFC还包括:[RFC0793]  [RFC1122]。之前,TCP有类似的超时选项TCP Keepalive。但是,TCP Keepalive是一个不建议打开的选项。因为委员会觉得这样会浪费带宽,引起不必要的网络中断。说白了,TCP是一组计时器组成的状态机,设计者是希望中间的电路中断、重新路由之类的变动,不会影响到两端的TCP状态。
     
    在游戏开发这块,一般都会做心跳机制。目的是为了让服务器的资源尽早释放,以支撑更多玩家。TCP Keepalive和上述的TCP_USER_TIMEOUT,勉强能完成任务。但是,不是所有平台都支持keepalive,所以只好放在应用层来做。目前用的心跳包是30秒一个的。太频繁的心跳,只会浪费流量,没有意义。同时,不断发送小数据包,会让手机的芯片持续处于高功率状态,游戏变得更加耗电。如果游戏本身能允许一定时间内的不一致,网络部分就能够更加灵活了。
     
    比如有玩家在地铁里进行游戏,列车行驶在站与站之间的时候,网络信号是非常弱的。如果能够将协议都变成异步的,游戏不需要等待上一条协议结果,就能继续进行。那么就可以定时上传操作日志,甚至可以模仿安卓的doze机制,发送超时就先睡眠一下,过一段时间再尝试。这样对电池的使用会更加友好,对地铁信号的适应性也会增强。只是游戏需要制定一个硬性同步的点,到了这个点一定要将所有日志同步到服务器,不然就暂时禁止玩家操作,直到同步成功为止。这个点处理的好,体验会提升不少。
     
     
  • 相关阅读:
    2月16号
    2月15号
    dubbo与springmvc的简单使用
    dubbo与zookeeper学习中的问题
    linux下jdk与tomcat的安装与配置
    mysql存储引擎
    mysql存储过程
    mysql子查询与连接查询
    mysql简单增删改查(CRUD)
    SpringMvc执行流程
  • 原文地址:https://www.cnblogs.com/Lifehacker/p/tcp_user_timeout.html
Copyright © 2011-2022 走看看