原文地址: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机制,发送超时就先睡眠一下,过一段时间再尝试。这样对电池的使用会更加友好,对地铁信号的适应性也会增强。只是游戏需要制定一个硬性同步的点,到了这个点一定要将所有日志同步到服务器,不然就暂时禁止玩家操作,直到同步成功为止。这个点处理的好,体验会提升不少。
 
 

《一个 Go 程序系统线程暴涨的问题》结论的更多相关文章

  1. HandlerThread 创建一个异步的后台线程

    使用HandlerThread几大优点: 1.制作一个后台异步线程,需要的时候就可以丢一个任务给它,使用比较灵活; 2.Android系统提供的,使用简单方便,内部自己封装了Looper+Handle ...

  2. ExecutorService 建立一个多线程的线程池的步骤

    ExecutorService 建立一个多线程的线程池的步骤: 线程池的作用: 线程池功能是限制在系统中运行的线程数. 依据系统的环境情况,能够自己主动或手动设置线程数量.达到执行的最佳效果:少了浪费 ...

  3. 一个Windows下线程池的实现(C++)

    前言 本文配套代码:https://github.com/TTGuoying/ThreadPool 先看看几个概念: 线程:进程中负责执行的执行单元.一个进程中至少有一个线程. 多线程:一个进程中有多 ...

  4. delphi 线程教学第七节:在多个线程时空中,把各自的代码塞到一个指定的线程时空运行

    第七节:在多个线程时空中,把各自的代码塞到一个指定的线程时空运行     以 Ado 为例,常见的方法是拖一个 AdoConnection 在窗口上(或 DataModule 中), 再配合 AdoQ ...

  5. asp.net core C#设计一个实用的线程池

    菜菜呀,我最近研究技术呢,发现线上一个任务程序线程数有点多呀 CEO,CTO,CFO于一身的CXO x总,你学编程呢? 菜菜 作为公司总负责人,我以后还要管理技术部门呢,怎么能不会技术呢 CEO,CT ...

  6. iOS 10 的一个重要更新-线程竞态检测工具 Thread Sanitizer

    本文介绍了 Xcode 8 的新出的多线程调试工具 Thread Sanitizer,可以在 app 运行时发现线程竞态. 想想一下,你的 app 已经近乎大功告成:它经过精良的打磨,单元测试全覆盖. ...

  7. 一个I/O线程可以并发处理N个客户端连接和读写操作 I/O复用模型 基于Buf操作NIO可以读取任意位置的数据 Channel中读取数据到Buffer中或将数据 Buffer 中写入到 Channel 事件驱动消息通知观察者模式

    Tomcat那些事儿 https://mp.weixin.qq.com/s?__biz=MzI3MTEwODc5Ng==&mid=2650860016&idx=2&sn=549 ...

  8. (转)如何在Linux中统计一个进程的线程数

    如何在Linux中统计一个进程的线程数 原文:http://os.51cto.com/art/201509/491728.htm 我正在运行一个程序,它在运行时会派生出多个线程.我想知道程序在运行时会 ...

  9. linux网络编程-一个简单的线程池(41)

    有时我们会需要大量线程来处理一些相互独立的任务,为了避免频繁的申请释放线程所带来的开销,我们可以使用线程池 1.线程池拥有若干个线程,是线程的集合,线程池中的线程数目有严格的要求,用于执行大量的相对短 ...

随机推荐

  1. Java--静态区域块

    public class Demo3_2 { static int i=1; static //静态区域块 { //该静态区域块只被执行一次 System.out.println("a&qu ...

  2. 一个crackme的分析

    是看雪合集的一个,因为老师让我们多练习,所以我就找了个crackme来练习 http://images2015.cnblogs.com/blog/638600/201612/638600-201612 ...

  3. IO多路复用,实现多线程监听

    服务端 import socket sk1 = socket.socket() sk1.bind(('127.0.0.1',8001)) sk1.listen() sk2 = socket.socke ...

  4. 【FPGA】【代码】资源优化,结构优化

    资源优化 原始资源 定义时初始化和复位电路初始化都起作用,删除定义的初值后 将always块描述的组合逻辑变为时序逻辑后

  5. 如何用python搞定验证码中的噪点

    背景:朋友在为"关山口男子职业技术学校"写一款校园应用,于是找MoonXue写一个学生选课系统的登录接口.为了搞定这个接口,不得不先搞定这个系统的验证码. 验证码大概是这个样子 看 ...

  6. WPF 调用WinForm控件

    WPF可以使用WindowsFormsHost控件做为容器去显示WinForm控件,类似的用法网上到处都是,就是拖一个WindowsFormsHost控件winHost1到WPF页面上,让后设置win ...

  7. webpack初学

    写在前面的话 阅读本文之前,先看下面这个webpack的配置文件,如果每一项你都懂,那本文能带给你的收获也许就比较有限,你可以快速浏览或直接跳过:如果你和十天前的我一样,对很多选项存在着疑惑,那花一段 ...

  8. Java特性-HashMap

    想分享一个对HashMap的理解: 我们首先要知道一个HashMap对象的构成,一般的理解是:一个Map里面放了很多个键值对,合在一起就是一个键值对的数组: 大概这么理解没问题,可是有一点要说明一下, ...

  9. jQuery--事件总结

    标准的绑定: bind(type,[,data],fn)==>第一个参数是事件类型 第二个可选参数作为event.data 传递给事件对象的额外数据对象 第三个参数为用来绑定的处理函数 简写绑定 ...

  10. impress.js webslide 参数

    data-transition-duration="2000" 改变切换场景的速度,默认1000data-perspective="500" 改变透视的深度,默 ...