• 网络通讯合并数据发送的重要性和实现原理


    在网络通讯中会经常面对一种情况就是信息广播转发,比较常见就是QQ群聊天。群里的人只要发一条信息就会广播到群里的其他人,不过这种转发量是非常的少一般情况下直接把通过对应用户的socket.send方法发送出去即可。但有些情况并不允可你这样,为什么呢?因为在某些场景下这些信息的转发量和密集度是非常之高,数量可以达到每少10w,20w,50w,100w或更多,也许你的服务器性能好每秒10w的IO不算什么问题,那面对一100W或更多的消息转发呢?有人会可能会问那来这么多的转发量,其实一个同场500的用户,每个用户平均每秒有两次行为改变,那就足以产生50W的转发量了。

        从上面的图可以看到用户之间的交互都会压在服务器上,其信息交互是每秒都会产生这样的量,以上图紧紧是6个,如果是500或1000个呢?那是一个怎样的情况。所以从IO的吞吐数量想把这些信息吃了是件不可能的事情。

        针对上面的情况我们需要做的就是控制IO,有朋友可能会问题怎么控制,难不成不Send?其实做控制很简单,其实只需用固定的资源去做某些事情就行,当工作的损耗超出的额定资源的情况就让他等一下。

        通过线程队列就可以控制IO处理的数量,当队列不存在堆压一般有以下情况:1的线程有足够的资源完成这些事情,2你需要转发的消息不多对队列构不成压力。其实这些情况都不需要进行合并,因为处理不存IO压力。

    当队列存在压力的时说线程没足够的资源来处理大量IO,这时候我们就需要做些额外的工作发送数据合并,减低IO压力。

        把当前队列的所有数据拿出来进行一个合并处理,然后再发送。整个过程都是内存操作其性能远高于网络IO处理,如果这个过程的实现比IO还损耗资源,那就认真的检查一下实现方法,这是不应该的。

        以上这种方式实现的延时是非常乐观的,同时它能根据当前资源的使用情况来决定是否进行合并数据操作。当你服务器资源满足,但延时上有点高那就可以通过多队列来处理,把压力分担到其他线程上以达到一个短的延时处理。

        在实际应用测试中由于网络带宽受限,所以只测试了500物体同场景测试,每个物体每秒产生两次变化,实际广播信息在50W每秒,发送IO大概1.5w每秒。core e4300的cpu占用大概在25% 左右,内存使用60mb,带宽80Mbps.,延时大概是60ms左右.

    以下是转发信息结构:

    class Po : IMessage
    {
        public int ID;
        public short X;
        public short Y;
        public short Type;
        public void Load(BufferReader reader)
        {
            ID = reader.ReadInt32();
            X = reader.ReadInt16();
            Y = reader.ReadInt16();
            Type = reader.ReadInt16();
        }
        public void Save(BufferWriter writer)
        {
            writer.Write(ID);
            writer.Write(X);
            writer.Write(Y);
            writer.Write(Type);
        }
    }
  • 相关阅读:
    android 源码
    android 保护
    电池信息 显示
    RGB、HSB、HSL 互相转换算法
    网页美工
    css 设计标准
    js 封闭 小结
    格式转换工具
    网页设计规范
    瀑布流分析
  • 原文地址:https://www.cnblogs.com/daichangya/p/12959043.html
Copyright © 2020-2023  润新知