三次握手之全连接已满?

2018-08-12  本文已影响0人  维特无忧堡

前言

  最近看了一个公众号推送的文章,说是一个遇到的一个问题—client端连接服务器总是抛出异常,我很喜欢看这样实战分享的,因为还没正式工作,所以很少遇到这样的情况,解决这样的问题之后总能加上自己的理解。
  我把来源放在文章最末尾啦!

问题描述

  简单来讲就是client端向server端建立三次连接已经完成,但server的selector没有响应到这个连接(服务端采用的是selector轮询机制,疑惑的可以去了解一下nio)
  出问题的时间点会聚集在一起,也就是在某段时间内很频繁。

问题分析与解决

 在TCP三次握手中,服务端维护了两个队列——半连接队列&&全连接队列

 我们来回顾一下TCP三次握手的流程:

  1. 首先客户端发送syn包,发送完之后状态进入syn_send。

  2. 服务端接受到了syn包,然后发送syn+ack包,然后把这个连接信息放到半连接队列中。这时候服务端的状态变成syn_rcvd

syn floods 的攻击就是针对这个来的,每次都只发送syn包,让服务端的半连接队列溢出

  3.客户端接受到这个包之后给服务端发送ack包,然后自身的状态变成establishied;

  4. 服务端接受到ack包之后,如果全连接池没满的话,就从半连接池中取出数据,放入到全连接池,一个连接就这样完成了。

  这是理想情况;在第四步的时候,如果全连接池满了呢?这时候就要看
tcp_abort_on_overflow的指示了,如果是0就暂时不管这个包,丢弃,然后过一段时间给客户端发送syn+ack包,相当于重走第二步;如果是1,立刻就给客户端返回一个消息(reset包),让它别等了,连接作废,所以我认为第二种要好一点。

针对上面发生的问题,我们可以通过

我们可以使用cat /proc/sys/net/ipv4/tcp_abort_on_overflow查看值,好像默认是0,我在腾讯云上试的(这时候我就不得不吐槽一下阿里云了,有个bug,我明明已经学生认证了,买服务器的时候一直要调到学生认证,调到这个界面之后又显示让我不要重复认证,绝望....)

cat /proc/sys/net/ipv4/tcp_abort_on_overflow

image.png

那么如何调整全连接队列大小呢?在Socket中有个参数BackLog,默认是50,这是来控制队列大小的,我们可以这样进行设置

ServerSocket serversocket = new ServerSocket(10000, backlog);

那么怎么能观察到是否队列满了呢?

我们可以使用命令: ss -Int

image.png

Recv_Q表示当前队列中有多少,而Send—Q表示最大是多少,我这个好像是128哎

【参考地址】

 本文参考【阿里技术】,【Hollis】微信公众号搜索就行了
https://mp.weixin.qq.com/s/D1sB1WlI-gkN5orVWCvyWg

上一篇 下一篇

猜你喜欢

热点阅读