数据库修仙金丹篇十三——缩短tcp超时时间的方法

本文介绍了几种缩短TCP超时时间的方法,包括使用TCP_USER_TIMEOUT选项、SIOCOUTQ查询、调整tcp_retries2参数及应用层keepalive机制。这些方法有助于在网络异常时减少等待时间。

缩短tcp超时时间的方法

在tcp链路中,当网络异常时,缩短tcp超时时间一般有如下方法:

  • TCP_USER_TIMEOUT(需要内核2.6.37及其以上版本)
  • SIOCOUTQ
  • tcp_retries2
  • 应用层keepalive

TCP_USER_TIMEOUT

需要内核2.6.37及其以上版本才支持该选项。

TCP_USER_TIMEOUT选项是TCP层的socket选项,选项接受unsigned int类型的值。值为数据包被发送后未接收到ACK确认的最大时长,以毫秒为单位,例如设置为10000时,代表如果发送出去的数据包在十秒内未收到ACK确认,则下一次调用send或者recv,则函数会返回-1,errno设置为ETIMEOUT,代表connection timeout。

unsigned int timeout = 10000;
if (-1 == setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &timeout, sizeof(timeout))) {
    fprintf(stderror, "set TCP_USER_TIMEOUT option error: %s", strerror(errno));
}

SIOCOUTQ

linux提供了ioctl(fd, SIOCOUTQ, &count)方法来查询一个tcp socket的write buffer是否清空。发送方一般可以用这个方法来判断对端是否收到报文。当底层网卡将缓冲区的数据全部发送成功时,获取的count=0.

#include <sys/ioctl.h>
 
#include <linux/sockios.h>
 
int value;
 
ioctl(client_fd,SIOCOUTQ,&value);

tcp_retries2

在丢弃激活(已建立通讯状况)的TCP连接之前﹐需要进行多少次重试。默认值为15,根据RTO的值来决定,相当于13-30分钟(RFC1122规定,必须大于100秒).(这个值根据目前的网络设置,可以适当地改小,我的网络内修改为了5)

int name[] = {CTL_NET, NET_IPV4, NET_IPV4_TCP_RETRIES2};
long value = 0;
size_t size = sizeof(value);
if(!sysctl(name, sizeof(name)/sizeof(name[0]), &value, &size, NULL, 0) {
  value // It contains current value from /proc/sys/net/ipv4/tcp_retries2
}
value = ... // Change value if it needed
if(!sysctl(name, sizeof(name)/sizeof(name[0]), NULL, NULL, &value, size) {
  // Value in /proc/sys/net/ipv4/tcp_retries2 changed successfully
}

tcp_retries2指定的是tcp重传的次数,其超时时间与RTO的计算有关。RTO最小值默认为200ms,最大为120s,在tcp的重传过程中,以200ms为基础,每次重传超时时间翻倍,但最大只能为120s。

在linux中tcp_retries2默认为15,因而其超时时间为:(2^9 -1)*0.2 + (16 - 9) * 120s = 924.6s.

需要特别留意的是tcp_retries2针对的是系统上的所有链路。

应用层keepalive

可以在应用层实现keepalive机制,通过主动发送keepalive报文和设置超时时间来检测链路是否异常。

需修改应用层代码,设计实现keepalive。

reference

  1. https://stackoverflow.com/questions/5907527/application-control-of-tcp-retransmission-on-linux/5907951#5907951
  2. https://blog.youkuaiyun.com/thwack/article/details/79960935
  3. https://developer.aliyun.com/article/840000
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我在数据库世界里修仙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值