zoukankan      html  css  js  c++  java
  • 设置TCP_USER_TIMEOUT参数来判断tcp连接是否断开

    1. bug描述

    前段时间遇到这样的一个问题,openstack一个控制节点宕机后,在宕机后一段时间内创建的虚拟机,一直卡在创建中的状态。有的甚至要等到16分钟之后虚拟机才会切换到下一个状态,创建成功。

    2. 问题分析

    1. 看现象,像是调度器没有接收到这个创建请求,直到16分钟后,api服务重新发送这个请求,才开始进行处理。
    2. 但是我们配置的各种参数,rpc的超时设置,都没有到16分钟这么久,按理说,应该控制器1宕机后几秒钟,api就应该发现,他连接到的消息队列服务死掉了,应该尝试重新发送。
    3. 仔细观察控制器1宕机后,控制器2上的tcp连接情况,发现控制器2上还是有很多连接到控制器1消息队列服务的连接,并且有未发送的数据包。

    3. 结论

    1. 将控制器01的网络中断之后,控制器02上大部分连接到控制器01 rabbitmq的长连接,都会因为10秒(5+1*5) 01内没有keepalive 响应而断开连接

      我们的tcp keepalive设置:
      net.ipv4.tcp_keepalive_intvl=1
      net.ipv4.tcp_keepalive_time=5
      net.ipv4.tcp_keepalive_probes=5
      net.ipv4.tcp_retries2=15
      
    2. 但是如果在这10秒内,控制器使用长连接往01发消息,那被使用的长连接,就不会触发keepalive的断开,而是会因为发送不成功,不断尝试重新发送,直到连续net.ipv4.tcp_retries2次发送失败后,才放弃发送。

    3. tcp_retries2的值默认是15,15次retry发送大约需要15分钟(取决于当时的网络rto).因为连接数很多,所以几乎一定会出现10秒内有消息发送的情况。

    4. openstack oslo_messaging 2.5.0-1会在消息发送失败后重连,但是在消息发送的这个动作,它没有超时放弃的逻辑。

    4. 解决

    1. 由于我们的平台对外隔离,仅仅提供再同一个二层网络内通信,所以在我们的场景下,可以将net.ipv4.tcp_retries2调小,oracle在类似的场景中,建议的值是3。

    2. 将这个值调到3之后,进行测试,发现虚拟机卡在创建中的时间大幅度缩小了,但是仍以分钟计,达不到我们的要求

    3. 在stackoverflow上发现了这样一个问题:keepalive-does-not-work。这个问题里面提到了TCP_USER_TIME_OUT参数,这个参数是tcp链接的参数,用来在3-2中描述的情况下,让tcp不用等到15次重试完成,就断开链接的超时时间,在linux kernel 2.6.37后提供支持。

    4. 在openstack 中搜索TCP_USER_TIME_OUT,发现在这个patch中:patch,openstack添加了对这个参数的支持。

    5. backport相关代码到我们的版本,测试通过

  • 相关阅读:
    【转】苹果App Store审核指南中文翻译(更新)
    ios中的coredata的使用
    iOS开发——网络编程OC篇&Socket编程
    [深入浅出Cocoa]iOS网络编程之Socket
    RESTful架构详解
    IOS开发 REST请求 ASIHTTPRequest用法
    iOS 8 AutoLayout与Size Class自悟
    nodejs入门demo
    微信公众号查询账户余额等
    微信公众号token验证失败的一些总结
  • 原文地址:https://www.cnblogs.com/zhangyufei/p/7516294.html
Copyright © 2011-2022 走看看