关于服务器的连接超时如何管理?

72 views
Skip to first unread message

lizp.net

unread,
Sep 12, 2010, 2:14:08 AM9/12/10
to dev4server
场景:
使用tcp,服务端需要对连接的活动状态进行管理,如果一个tcp连接规定时间内没有数据活动就要将其关闭。
想到的解决办法是:建立一个列表,保存所有活动连接,一个线程定时检测这个列表中的连接状态,如果超时关闭它,并从列表中删除。而如果这个连接正常关闭的话,也需要从这个列表中删除。
问题:性能太低。对列表的操作需要加锁,当连接到来,加锁插入列表,连接关闭,加锁从列表中删除。检测如果超时也需要加锁从列表中删除。目前系统的响应要求达到毫秒级,而且是大量的短连接,三次加锁操作感觉性能太低了,请问有什么更好的解决办法?
 
2010-09-12

kejun

unread,
Sep 12, 2010, 12:12:16 PM9/12/10
to dev4s...@googlegroups.com
对于短连接一般都是echo型的server.发送完数据后即可关闭连接,当然对server端的开销是非常大的。
如果是长连接,业内通常做法是client-server端采用心跳keep-alive的方式进行。如果心跳在指定之际内未到达,可以使用定时器机制,则可以关闭连接,释放句柄。

--
高性能服务器研发与运营
http://groups.google.com/group/dev4server

nn hust

unread,
Sep 12, 2010, 12:49:31 PM9/12/10
to dev4s...@googlegroups.com
KEEP_ALIVE


--
高性能服务器研发与运营
http://groups.google.com/group/dev4server

Shuo Chen

unread,
Sep 12, 2010, 8:20:16 PM9/12/10
to 高性能服务器研发与运营邮件列表
问题:

1. 运行在什么硬件,什么操作系统?
2. 一般有多少 TCP 并发连接?
3. TCP 连接建立与销毁的频率是多少?长连接还是短连接?
4. TCP 连接超时关闭的比例是多少?
5. 多久算超时?几秒还是几分钟?

以上几点决定了"加锁"会不会导致性能瓶颈。
另外你说"性能太低"是测出来的还是纯粹感觉出来的?

On Sep 12, 2:14 pm, "lizp.net" <lizp....@gmail.com> wrote:
> 场景:
> 使用tcp,服务端需要对连接的活动状态进行管理,如果一个tcp连接规定时间内没有数据活动就要将其关闭。
> 想到的解决办法是:建立一个列表,保存所有活动连接,一个线程定时检测这个列表中的连接状态,如果超时关闭它,并从列表中删除。而如果这个连接正常关闭的话,也 需要从这个列表中删除。
> 问题:性能太低。对列表的操作需要加锁,当连接到来,加锁插入列表,连接关闭,加锁从列表中删除。检测如果超时也需要加锁从列表中删除。目前系统的响应要求达到 毫秒级,而且是大量的短连接,三次加锁操作感觉性能太低了,请问有什么更好的解决办法?
>
> 2010-09-12
>

> lizp.net

lizp.net

unread,
Sep 12, 2010, 8:36:19 PM9/12/10
to dev4server
非常感谢您的问题。
1. 运行在什么硬件,什么操作系统?
linux操作系统
2. 一般有多少 TCP 并发连接?
上万个
3. TCP 连接建立与销毁的频率是多少?长连接还是短连接?
短连接,频率是毫秒级
4. TCP 连接超时关闭的比例是多少?
不多,但是怕恶意连接上来
5. 多久算超时?几秒还是几分钟?
最多3秒吧。
 
实在不好意思,还没有测试,是感觉出来的,还请兄台释疑。。
 
 
2010-09-13


发件人: Shuo Chen
发送时间: 2010-09-13  08:20:30
收件人: 高性能服务器研发与运营邮件列表
抄送:
主题: Re: 关于服务器的连接超时如何管理?
-- 
高性能服务器研发与运营
14.gif

Shuo Chen

unread,
Sep 12, 2010, 8:48:04 PM9/12/10
to 高性能服务器研发与运营邮件列表
你用什么 IO 模型来处理上万个 TCP 连接?是 reactor 还是 proactor?
程序的线程模型是什么样的?一共有几个线程?机器有几个核?
有几个 IO 线程?TCP 连接会分到几个线程上还是由一个线程处理?
是在 IO 线程处理逻辑还是分配到线程池?
连接会被跨线程使用吗?

如果合适,可以考虑每个 IO 线程管理自己的 TCP 连接超时,这样没有全局的连接表,每个线程一个连接表,别的线程看不到,超时的 timer
也在 IO 线程触发,这样也就不用加锁。

On Sep 13, 8:36 am, "lizp.net" <lizp....@gmail.com> wrote:
> 非常感谢您的问题。
> 1. 运行在什么硬件,什么操作系统?
> linux操作系统
> 2. 一般有多少 TCP 并发连接?
> 上万个
> 3. TCP 连接建立与销毁的频率是多少?长连接还是短连接?
> 短连接,频率是毫秒级
> 4. TCP 连接超时关闭的比例是多少?
> 不多,但是怕恶意连接上来
> 5. 多久算超时?几秒还是几分钟?
> 最多3秒吧。
>

> 实在不好意思,还没有测试,是感觉出来的,还请兄台释疑。。
>
> 2010-09-13
>
> lizp.net


>
> 发件人: Shuo Chen
> 发送时间: 2010-09-13 08:20:30
> 收件人: 高性能服务器研发与运营邮件列表
> 抄送:
> 主题: Re: 关于服务器的连接超时如何管理?
>
> 问题:
> 1. 运行在什么硬件,什么操作系统?
> 2. 一般有多少 TCP 并发连接?
> 3. TCP 连接建立与销毁的频率是多少?长连接还是短连接?
> 4. TCP 连接超时关闭的比例是多少?
> 5. 多久算超时?几秒还是几分钟?
> 以上几点决定了"加锁"会不会导致性能瓶颈。
> 另外你说"性能太低"是测出来的还是纯粹感觉出来的?
> On Sep 12, 2:14 pm, "lizp.net" <lizp....@gmail.com> wrote:> 场景:
> > 使用tcp,服务端需要对连接的活动状态进行管理,如果一个tcp连接规定时间内没有数据活动就要将其关闭。
> > 想到的解决办法是:建立一个列表,保存所有活动连接,一个线程定时检测这个列表中的连接状态,如果超时关闭它,并从列表中删除。而如果这个连接正常关闭的话,也 需要从这个列表中删除。
> > 问题:性能太低。对列表的操作需要加锁,当连接到来,加锁插入列表,连接关闭,加锁从列表中删除。检测如果超时也需要加锁从列表中删除。目前系统的响应要求达到 毫秒级,而且是大量的短连接,三次加锁操作感觉性能太低了,请问有什么更好的解决办法?
>
> > 2010-09-12
>
> > lizp.net
>
> --
> 高性能服务器研发与运营
> http://groups.google.com/group/dev4server
>

> 14.gif
> 2KViewDownload

lizp.net

unread,
Sep 12, 2010, 9:05:55 PM9/12/10
to dev4server
我是用的是epoll,是把所有连接放到一个线程池管理的,所以不是每个线程一个连接的。
 
 
2010-09-13


发件人: Shuo Chen
发送时间: 2010-09-13  08:48:16
-- 
高性能服务器研发与运营

qiaojie

unread,
Sep 12, 2010, 11:37:08 PM9/12/10
to dev4s...@googlegroups.com
看你的描述连接之间应该是没有相关性的,这样的话可以开个线程池,每个线程分管一些连接,每个线程里面顺序处理,这样就不需要加锁了。

 
--
高性能服务器研发与运营
http://groups.google.com/group/dev4server

yachan...@gmail.com

unread,
Sep 16, 2010, 9:11:55 PM9/16/10
to 高性能服务器研发与运营邮件列表
你担心连接被占用完吗, 比较合理的作法是不用单独的线程去关闭连接.

每次新请求到达时,肯定要分配一个连接的,如果连接已用完,就把根据LRU算法,把最早的空闲连接关闭,这样,不用加锁,也可以保持加接不会被闲置用户
占用完.

On 9月13日, 上午11时37分, qiaojie <qiao...@gmail.com> wrote:
> 看你的描述连接之间应该是没有相关性的,这样的话可以开个线程池,每个线程分管一些连接,每个线程里面顺序处理,这样就不需要加锁了。
>

> 2010/9/12 lizp.net <lizp....@gmail.com>
>
>
>
> > 场景:
> > 使用tcp,服务端需要对连接的活动状态进行管理,如果一个tcp连接规定时间内没有数据活动就要将其关闭。
>
> > 想到的解决办法是:建立一个列表,保存所有活动连接,一个线程定时检测这个列表中的连接状态,如果超时关闭它,并从列表中删除。而如果这个连接正常关闭的话,也-需要从这个列表中删除。
>
> > 问题:性能太低。对列表的操作需要加锁,当连接到来,加锁插入列表,连接关闭,加锁从列表中删除。检测如果超时也需要加锁从列表中删除。目前系统的响应要求达到-毫秒级,而且是大量的短连接,三次加锁操作感觉性能太低了,请问有什么更好的解决办法?
>
> > 2010-09-12
> > ------------------------------
> > lizp.net
>
> > --
> > 高性能服务器研发与运营
> >http://groups.google.com/group/dev4server- 隐藏被引用文字 -
>
> - 显示引用的文字 -

Jiang Zhiqiang

unread,
Sep 20, 2010, 2:20:57 AM9/20/10
to dev4s...@googlegroups.com
是否可以换个角度思考
1、由client负责计时,超时后发消息告知server,server收到后断开连接
2、为了避免非正规client,即不发送超时消息,server启用一个较长(比如5分钟)的定时器来检查超时,断开连接


--
高性能服务器研发与运营
 http://groups.google.com/group/dev4server



--



Email(MSN):zhiq...@gmail.com


nn hust

unread,
Sep 21, 2010, 12:58:31 AM9/21/10
to dev4s...@googlegroups.com
keep_alive能解决么?

--
高性能服务器研发与运营
http://groups.google.com/group/dev4server

wu thomas

unread,
Sep 21, 2010, 1:38:24 AM9/21/10
to dev4s...@googlegroups.com
采用EPOLL或完成端口,对SOCKET句柄设定超时事件即可。

2010/9/21 nn hust <nzje...@gmail.com>
--
高性能服务器研发与运营
http://groups.google.com/group/dev4server

韩潇

unread,
Sep 21, 2010, 2:31:17 AM9/21/10
to dev4s...@googlegroups.com
应该是压力问题,一下子那么多连接,就是会有问题吧,试试sleep一下呢

--
高性能服务器研发与运营
http://groups.google.com/group/dev4server

lizp.net

unread,
Sep 21, 2010, 2:43:45 AM9/21/10
to dev4server
请问“对SOCKET句柄设定超时事件即可”这句话,怎么理解呢?怎么实现呢?
 
 
2010-09-21


发件人: wu thomas
发送时间: 2010-09-21  13:38:38
收件人: dev4server
抄送:
主题: Re: 关于服务器的连接超时如何管理?
--
高性能服务器研发与运营
http://groups.google.com/group/dev4server

wu thomas

unread,
Sep 21, 2010, 2:45:44 AM9/21/10
to dev4s...@googlegroups.com
事件有3种,1、read事件 2、write事件 3、超时事件

--
高性能服务器研发与运营
http://groups.google.com/group/dev4server

lizp.net

unread,
Sep 21, 2010, 2:58:10 AM9/21/10
to dev4server
恩,非常感谢,您的意思是超时事件,epoll也可以实现?请问怎么实现呢?
 
 
2010-09-21


发件人: wu thomas
发送时间: 2010-09-21  14:45:57
收件人: dev4server
抄送:
主题: Re: Re: 关于服务器的连接超时如何管理?
--
高性能服务器研发与运营
http://groups.google.com/group/dev4server

阿杜

unread,
Sep 21, 2010, 3:38:55 AM9/21/10
to dev4s...@googlegroups.com
句柄超时对于恶意连几乎是没用的,心跳包是王道。
知易行难

phoenix yang

unread,
Sep 25, 2010, 5:05:56 AM9/25/10
to dev4s...@googlegroups.com
这用个心跳就OK了啊。在你的程序里做一个链表保存SOCKET;状态,启动一个线程不停的循环检查,到时间没发包,就CLOSE.

--
高性能服务器研发与运营
http://groups.google.com/group/dev4server

lizp.net

unread,
Sep 25, 2010, 9:01:59 PM9/25/10
to dev4server
这个办法是常用办法,但效率不高。
 
 
2010-09-26


发件人: phoenix yang
发送时间: 2010-09-25  17:06:11
收件人: dev4server
抄送:
主题: Re: Re: Re: 关于服务器的连接超时如何管理?
--
高性能服务器研发与运营
http://groups.google.com/group/dev4server

Zark Yoc

unread,
Sep 26, 2010, 3:34:30 AM9/26/10
to dev4s...@googlegroups.com

"恩,非常感谢,您的意思是超时事件,epoll也可以实现?请问怎么实现呢?"


哥哥,我只想告诉你,epoll是epoll,所谓的心跳是心跳。两者不同概念。
谢谢!!!

Zark Yoc


胡人

unread,
Sep 30, 2010, 12:39:49 PM9/30/10
to dev4s...@googlegroups.com
建议直接io线程(组)加个timer,内部处理下超时问题。
如果按照正常逻辑一直有数据交互,其实也不用专门的心跳,因为任何一个来自client的收包操作都可视为一个有效的心跳,只要记录下最后的时间,和当前的时间比较下就知道多少时间没有活动,根据设置即可决定是否可关闭这个连接。如果正常逻辑下客户端可长时间保持连接但无逻辑数据交互则需要设计一个合适的心跳消息。
 

shiwei xu

unread,
Oct 2, 2010, 11:04:16 AM10/2/10
to dev4s...@googlegroups.com
Test

> --
> 高性能服务器研发与运营
> http://groups.google.com/group/dev4server

Eric.Wang

unread,
Nov 28, 2010, 1:18:16 PM11/28/10
to 高性能服务器研发与运营邮件列表

假设每秒连接/断开的次数不超过1w次,则:
accept之后,把socket以time为key放到一个最小堆里面去,以socket为key放到map里面去。socket断开的时候,从
map找到对应的time然后从最小堆里面删掉。
定时检查只要检查最小堆即可。
如果需要多线程,则使用spin lock,因为map和最小堆的运算都很快,每秒1w次以下是基本上不会锁碰撞的。
Reply all
Reply to author
Forward
0 new messages