• 设置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相关代码到我们的版本,测试通过

  • 相关阅读:
    ReactNative学习-webView
    React Native学习-将 'screen', 'window' or a view生成图片
    React Native学习-measure测量view的宽高值
    React Native教程
    React Native学习-CameraRoll
    React Native学习-控制横竖屏第三方组件:react-native-orientation
    React Native学习-调取摄像头第三方组件:react-native-image-picker
    ReactNative学习-滑动查看图片第三方组件react-native-swiper
    MFC的简单加法器(二)
    MFC之目录结构及消息流转(一)
  • 原文地址:https://www.cnblogs.com/zhangyufei/p/7516294.html
Copyright © 2020-2023  润新知