博客
关于我
一个简单基于LRU连接检测实现
阅读量:444 次
发布时间:2019-03-06

本文共 5280 字,大约阅读时间需要 17 分钟。

        在做网络应用的时候经常要处理不处于活动的连接,对于不活动的TCP连接可以通过设置KeepAlive来触发SocketError来处理掉.但有更多的时候是使用ping和pong来处理.对于ping,pong这种做法的发起者有两种情况,分别是由server或client发起.对于由服务器发起比较损耗资源毕竟每隔一段时间都要向整个连接列发送ping,当累计到定数量没得到pong回应用的时候杀死;而对于Client发起的话server只需要记录ping时间即可,隔一段时间没有得到ping的client杀死.但两种做法似乎都要对连接列表进行一次扫描,存在大量活动连接的时候这种做法似乎并不理想.

       其实可以通过一个LRU算法简单地把活动连接前置,那在处理的时候只需要关心不活动的连接即可以,LRU算法大概如下:

LRU(least recently used)。
假设 序列为 4 3 4 2 3 1 4 2
物理块有3个 则
首轮 4调入内存 4
次轮 3调入内存 3 4
之后 4调入内存 4 3
之后 2调入内存 2 4 3
之后 3调入内存 3 2 4
之后 1调入内存 1 3 2(因为最近最久未使用的是4,所以丢弃4)
之后 4调入内存 4 1 3(原理同上)
最后 2调入内存 2 4 1
可以通过一个简单的链接来完成上面功能,当某个项目接收到ping的时候,移到链表头即可以.在扫链表的时候只需要由尾部扫起,值到某个值不存在超时的时候就可以停止扫描.
 
通过LRU就能做到在活跃连接比较多的情况有比较好的处理效果,由于链表在找值的时候必须要扫一次,所以当连接更新在链表中寻找相应的值成本是不太划算的.可以通过制订一个双向引用的结构来解决寻找问题.
///         /// 连接描述接口        ///         public interface IConnecton        {            ///             /// 获取对应在LRU算法中的节点            ///             LinkedListNode
Node { get; set; } ///
/// 超时操作,当LRU算法检测到应该连接超时的时候会调用该方法 /// void TimeOut(); } ///
/// 节点信息 /// public class Node { ///
/// 最后活动时间 /// public int LastActiveTime; ///
/// 相关连接信息 /// public IConnecton Connection; ///
/// 检测是否过期 /// ///
///
///
public bool Detect(int cutime, int timeout) { return Math.Abs(cutime - LastActiveTime) > timeout; } }

制定一个应用接口和相应的节点类型.通过这个接口规范就可以方便定位到链表的节点上.

public void Update(IConnecton connection)        {            lock (this)            {                LinkedListNode
node = connection.Node; if (node != null) { node.Value.LastActiveTime = Environment.TickCount; mLinkedList.Remove(node); mLinkedList.AddFirst(node); } else { node = mLinkedList.AddFirst(new Node()); node.Value.LastActiveTime = Environment.TickCount; node.Value.Connection = connection; connection.Node = node; } } }

当一个项更新的时候就不再需要遍历链表查询,这样就能节省大量查询上的损耗.当然一个完整的LRU检测机制不是要一个timer来驱动,完全代码如下:

///     /// 基于LRU算法的连接检测    ///     public class LRUDetect : IDisposable    {        ///         /// 构建检测器        ///         /// 超时时间以毫秒为单位        public LRUDetect(int timeout)        {            mTimeout = timeout;            mTimer = new System.Threading.Timer(OnDetect, null, mTimeout, mTimeout);        }        private int mTimeout;        private System.Threading.Timer mTimer;        private LinkedList
mLinkedList = new LinkedList
(); ///
/// 更新连接 /// ///
连接信息 public void Update(IConnecton connection) { lock (this) { LinkedListNode
node = connection.Node; if (node != null) { node.Value.LastActiveTime = Environment.TickCount; mLinkedList.Remove(node); mLinkedList.AddFirst(node); } else { node = mLinkedList.AddFirst(new Node()); node.Value.LastActiveTime = Environment.TickCount; node.Value.Connection = connection; connection.Node = node; } } } ///
/// 删除连接 /// ///
连接信息 public void Delete(IConnecton connection) { lock (this) { LinkedListNode
node = connection.Node; if (node != null) { node.Value.Connection = null; mLinkedList.Remove(node); } } } private void OnDetect(object state) { lock (this) { int cutime = Environment.TickCount; LinkedListNode
last = mLinkedList.Last; while (last != null && last.Value.Detect(cutime, mTimeout)) { last.Value.Connection.TimeOut(); last.Value.Connection = null; mLinkedList.RemoveLast(); last = mLinkedList.Last; } } } ///
/// 连接描述接口 /// public interface IConnecton { ///
/// 获取对应在LRU算法中的节点 /// LinkedListNode
Node { get; set; } ///
/// 超时操作,当LRU算法检测到应该连接超时的时候会调用该方法 /// void TimeOut(); } ///
/// 节点信息 /// public class Node { ///
/// 最后活动时间 /// public int LastActiveTime; ///
/// 相关连接信息 /// public IConnecton Connection; ///
/// 检测是否过期 /// ///
///
///
public bool Detect(int cutime, int timeout) { return Math.Abs(cutime - LastActiveTime) > timeout; } } ///
/// 释放对象 /// public void Dispose() { if (mTimer != null) { mTimer.Dispose(); mLinkedList.Clear(); } } }

 

 

转载地址:http://setfz.baihongyu.com/

你可能感兴趣的文章
weblogic 服务器部署SSL证书
查看>>
Oracle Orion tool check io(ORACLE Orion 工具查看以及校验IO)
查看>>
oracle 11g not in 与not exists 那个高效?
查看>>
html5 Game开发系列文章之 零[开篇]
查看>>
ES6基础之——new Set
查看>>
玩玩小爬虫——试搭小架构
查看>>
Javascript之旅——第九站:吐槽function
查看>>
Sql Server之旅——第十站 看看DML操作对索引的影响
查看>>
双十一来了,别让你的mongodb宕机了
查看>>
深入探索Android热修复技术原理读书笔记 —— 热修复技术介绍
查看>>
解析js中( ( ) { } ( ) )的含义
查看>>
js设计模式总结5
查看>>
Python大神编程常用4大工具,你用过几个?
查看>>
一文带你了解图神经网络
查看>>
9个常用ES6特性归纳(一般用这些就够了)
查看>>
3D渲染集群,你了解多少?
查看>>
华为云FusionInsight湖仓一体解决方案的前世今生
查看>>
BootStrapTable 错误
查看>>
罗马数字
查看>>
IO多路复用小故事
查看>>