外贸商城网站 定制,泉州做网站优化价格,网站首页优化模板,wordpress伪春菜最近在新的平台上测试程序#xff0c;以前一些没有注意到的问题都成为了性能瓶颈#xff0c;通过设置一些TCP/IP选项能够解决一部分问题#xff0c;当然根本的解决方法是重构代码#xff0c;重新设计服务器框架。先列出几个TCP/IP选项#xff1a; 选项 man 7 socket: SO_R… 最近在新的平台上测试程序以前一些没有注意到的问题都成为了性能瓶颈通过设置一些TCP/IP选项能够解决一部分问题当然根本的解决方法是重构代码重新设计服务器框架。先列出几个TCP/IP选项 选项 man 7 socket: SO_REUSEADDR SO_RECVBUF/SO_SNDBUF SO_KEEPALIVE SO_LINGER man 7 tcp: TCP_CORK TCP_NODELAY TCP_DEFER_ACCEPT TCP_KEEPCNT/TCP_KEEPIDLE/TCP_KEEPINTVL SO_REUSEADDR man 命令的 领域 名称 说明 1 用户命令 可由任何人启动的。 2 系统调用 即由内核提供的函数。 3 例程 即库函数。 4 设备 即/dev目录下的特殊文件。 5 文件格式描述 例如/etc/passwd。 6 游戏 不用解释啦 7 杂项 例如宏命令包、惯例等。 8 系统管理员工具 只能由root启动。 9 其他Linux特定的 用来存放内核例行程序的文档。 SO_REUSEADDR选项: 在服务器程序中SO_REUSEADDR socket选项通常在调用bind()之前被设置。 SO_REUSEADDR可以用在以下四种情况下 (摘自《Unix网络编程》卷一即UNPv1) 1、当有一个有相同本地地址和端口的socket1处于TIME_WAIT状态时而你启动的程序的socket2要占用该地址和端口你的程序就要用到该选项。 2、SO_REUSEADDR允许同一port上启动同一服务器的多个实例(多个进程)。但每个实例绑定的IP地址是不能相同的。在有多块网卡或用IP Alias技术的机器可以测试这种情况。 3、SO_REUSEADDR允许单个进程绑定相同的端口到多个socket上但每个socket绑定的ip地址不同。这和2很相似区别请看UNPv1。 4、SO_REUSEADDR允许完全相同的地址和端口的重复绑定。但这只用于UDP的多播不用于TCP。 TCP_NODELAY/TCP_CHORK选项: TCP_NODELAY/TCP_CHORK TCP_NODELAY和TCP_CORK基本上控制了包的“Nagle化”Nagle化在这里的含义是采用Nagle算法把较小的包组装为更大的帧。TCP_NODELAY和TCP_CORK都禁掉了Nagle算法只不过他们的行为不同而已。 TCP_NODELAY 不使用Nagle算法不会将小包进行拼接成大包再进行发送直接将小包发送出去会使得小包时候用户体验非常好。 Nagle算法参见自己的博客:http://blog.163.com/xychenbaihuyeah/blog/static/132229655201231214038740/ 当在传送大量数据的时候为了提高TCP发送效率可以设置TCP_CORKCORK顾名思义就是塞子的意思它会尽量在每次发送最大的数据量。当设置了TCP_CORK后会有阻塞200ms当阻塞时间过后数据就会自动传送。 详细的资料可以查看参考文献5。 SO_LINGER选项: SO_LINGER linger顾名思义是延迟延缓的意思这里是延缓面向连接的socket的close操作。 默认close立即返回但是当发送缓冲区中还有一部分数据的时候系统将会尝试将数据发送给对端。SO_LINGER可以改变close的行为。 控制SO_LINGER通过下面一个结构 struct linger { int l_onoff; /*0off, nonzeroon*/ int l_linger; /*linger time, POSIX specifies units as seconds*/ }; 通过结构体中成员的不同赋值可以表现为下面几种情况 1. l_onoff设置为0选项被关闭。l_linger值被忽略就是上面的默认情形close立即返回。 2. l_onoff设置为非0l_linger被设置为0则close()不被阻塞立即执行丢弃socket发送缓冲区中的数据并向对端发送一个RST报文。 这种关闭方式称为“强制”或“失效”关闭。 3. l_onoff设置为非0l_linger被设置为非0则close()调用阻塞进程直到所剩数据发送完毕或超时。 这种关闭称为“优雅的”关闭。 注意 这个选项需要谨慎使用尤其是强制式关闭会丢失服务器发给客户端的最后一部分数据。UNP中: The TIME_WAIT state is our friend and is there to help us(i.e., to let the old duplicate segments expire in the network). TCP_DEFER_ACCEPT选项: TCP_DEFER_ACCEPT defer accept从字面上理解是推迟accept实际上是当接收到第一个数据之后才会创建连接三次握手完成连接还没有建立。 对于像HTTP等非交互式的服务器这个很有意义可以用来防御空连接攻击只是建立连接但是不发送任何数据。 使用方法如下 val 5; setsockopt(srv_socket-fd, SOL_TCP, TCP_DEFER_ACCEPT, val, sizeof(val)) ; 里面 val 的单位是秒注意如果打开这个功能kernel 在 val 秒之内还没有收到数据不会继续唤醒进程而是直接丢弃连接。如果服务器设置TCP_DEFER_ACCEPT选项后服务器受到一个CONNECT请求后三次握手之后新的socket状态依然为SYN_RECV而不是ESTABLISHED操作系统不会Accept。 由于设置TCP_DEFER_ACCEPT选项之后三次握手后状态没有达到ESTABLISHED而是SYN_RECV。这个时候如果客户端一直没有发送数据报文服务器将重传SYN/ACK报文重传次数受net.ipv4.tcp_synack_retries参数控制达到重传次数之后才会再次进行setsockopt中设置的超时值因此会出现SYN_RECV生存时间比设置值大一些的情况。 关于SYN_RECV状态可以查看参考文献7。 SO_KEEPALIVE选项: SO_KEEPALIVE/TCP_KEEPCNT/TCP_KEEPIDLE/TCP_KEEPINTVL 如果一方已经关闭或异常终止连接而另一方却不知道我们将这样的TCP连接称为半打开的。 TCP通过保活定时器(KeepAlive)来检测半打开连接。 在高并发的网络服务器中经常会出现漏掉socket的情况对应的结果有一种情况就是出现大量的CLOSE_WAIT状态的连接。这个时候可以通过设置KEEPALIVE选项来解决这个问题当然还有其他的方法可以解决这个问题详细的情况可以查看参考资料8。 使用方法如下 //Setting For KeepAlive int keepalive 1; setsockopt(incomingsock,SOL_SOCKET,SO_KEEPALIVE,(void*)(keepalive),(socklen_t)sizeof(keepalive)); int keepalive_time 30; setsockopt(incomingsock, IPPROTO_TCP, TCP_KEEPIDLE,(void*)(keepalive_time),(socklen_t)sizeof(keepalive_time)); int keepalive_intvl 3; setsockopt(incomingsock, IPPROTO_TCP, TCP_KEEPINTVL,(void*)(keepalive_intvl),(socklen_t)sizeof(keepalive_intvl)); int keepalive_probes 3; setsockopt(incomingsock, IPPROTO_TCP, TCP_KEEPCNT,(void*)(keepalive_probes),(socklen_t)sizeof(keepalive_probes)); 设置SO_KEEPALIVE选项来开启KEEPALIVE然后通过TCP_KEEPIDLE、TCP_KEEPINTVL和TCP_KEEPCNT设置keepalive的开始时间、间隔、次数等参数。 当然也可以通过设置/proc/sys/net/ipv4/tcp_keepalive_time、tcp_keepalive_intvl和tcp_keepalive_probes等内核参数来达到目的但是这样的话会影响所有的socket因此建议使用setsockopt设置