zoukankan      html  css  js  c++  java
  • TCP_DEFER_ACCEPT的坑

    我实现了一个server,支持HTTP协议和内部私有协议,为了简化部署,我设计成一个端口同时兼容两种协议的客户端。根据连接后到达的消息头自动识别客户端协议。这种事情的传统做法是,accept后加入epoll,当fd第一次可读时,读出一些并解析,判断协议类型。

    创建相应的上下文对象,开始服务。这样就引入了中间状态,为了省事,我用了TCP_DEFER_ACCEPT来简化这个过程。

    TCP_DEFER_ACCEPT,是Linux下的socket支持一个tcp选项,man这么说的:

    TCP_DEFER_ACCEPT

        Allows a listener to be awakened only when data arrives on the socket. Takes an integer value (seconds), this can bound the maximum number of
      attempts TCP will make to complete the connection. This option should not be used in code intended to be portable.

    这样,当accept后,马上就读出并解析协议头,然后再把fd设置为非阻塞的,创建上下文对象,代码简化了不少。

    但是今天用大量短连接压测时,发现连接数过了几千后,程序急剧变慢,最后干脆停止响应了。gdb上去看发现居然阻塞在recv的地方,加时间日志发现,recv居然有不少耗时数百毫秒,而如果先设置成非阻塞的,读取时就会大量返回EAGAIN错误。看来行为和文档并不一样。

    最后,我把代码改为在epoll通知可读时再读取并解析,故障消失。

    后记:

    早上在微博上顺手搜了一下,发现也有人已经掉过坑,但是我用google搜索时就没看到这个信息,看来对于新技术应该多做一些调研和试验才能放心用。

    http://weibo.com/1457629002/AymKa8FeS?type=comment#_rnd1416450208506

    相关修改

    http://lists.openwall.net/netdev/2009/10/19/72

  • 相关阅读:
    链家大数据多维分析引擎实践
    html 读取变量
    django 分配字典给前台模板
    django将数组传递给前台模板
    fetachone和fetchall
    django捕获url中的值
    django 控制页面跳转
    MySQL的前缀索引及Oracle的类似实现
    django url捕获
    django 页面调用方法
  • 原文地址:https://www.cnblogs.com/chen3feng/p/4109257.html
Copyright © 2011-2022 走看看