首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  程序员

C/S 模型程序,遇到瓶颈,大佬们快来帮忙

  •  
  •   bbxiong · 62 天前 · 1354 次点击
    这是一个创建于 62 天前的主题,其中的信息可能已经有所发展或是发生改变。

    简单介绍: Server(控制端) Client(客户端)

    Server 主要功能 通过 ListView 显示 Client 发来的状态消息 给 Client 发送命令执行相应代码

    client 主要功能 每秒发送当前状态信息(文本数据)到 Server 接收 Server 发来的命令进行执行

    规模: Client 规模最大能到 500 左右

    目前的网络模型 Server 使用 UDP server 接收来自 client 的消息 Server 使用 UDP 发送命令给 Client

    Client 使用 UDP server 接收来自 Server 的命令 Client 使用 UDP 发送状态信息给 Server

    Server 和 Client 都使用 lua socket 模块

    问题如下: 当 Client 规模太大的时候 Server 接收消息出现排队情况如何处理或者避免? Server 每秒处理显示 10 条来自 Client 的状态消息,Client 的消息会有重复,准备加个过滤,Server 只处理显示每个 Client 的最新个消息,但是这样当每秒钟消息大于 10 条,也还是会出现拥堵问题.

    请大佬们帮忙指出问题所在

    19 回复  |  直到 2019-06-21 19:31:07 +08:00
        1
    bbxiong   62 天前
    100 Client 每秒 1 个消息 就是每秒 100 个消息,Server 每 100 毫秒更新显示一次 ListView 里的数据,1 秒只能更新显示 10 条数据,这么多 Client 同时发状态信息 Server 如何全都完整的展示出来呢.
        2
    KylinJiang   62 天前
    信息量与处理速度是简单的数学公式恒定的,水池 10m2,每秒放水 10m2,进水 100m2。
    要么扩大水池:
    列表扩大
    列表分页
    要么减少入水量:
    消息分优先级,高级在前,屏蔽低级
    消息去重
    消息聚合(多个 client 显示相同消息的话,将消息聚合为一个组)
        3
    liuzhiyong   62 天前 via Android
    lua 我不太懂哈,你说的“每秒钟消息大于 10 条,也还是会出现拥堵问题”:这个程序性能太低了,可以考虑换个技术实现(据说 go 很擅长这个,可以试一下)。
        4
    hackfly   62 天前
    Server(控制端) 加一个队列,每次接收到消息,push 到队列,每次只取出 10 条处理
        6
    runtu2019   62 天前
    做成异步的吧,反正能双向通信,接收到 C 端的消息缓存到 Redis 后,直接返回 OK 接收成功,
    后续单独做个服务处理 Redis 里缓存信息,Redis 也能去重,写个多线程,也能很快处理完缓存队列,
    S 端处理完成了再把指令发给 C 端
        7
    index90   62 天前
    你是把接收信息和更新 ListView 做成同步的吧?
        8
    FelixLiu   62 天前
    开始吐槽:
    1.为啥用 udp,发送命令这种东西,你丢了就没了,为啥不用 tcp,黑人问号???
    2.client 发送速度太快,server 处理太慢,你是不是要自己实现一个 block ?当服务器命令缓冲区满了,server 自动发个消息过去,让 client 发送线程 block。
    3.如果你一定要用 udp,那你自己要弄个缓冲区,要不然 recv 间隔之间的包可能被丢失。。。。
    4.tcp 啊,tcp,应用层处理啊,处理啊
        9
    bbxiong   62 天前
    @liuzhiyong 感谢回复,用 lua 就是为了简单自己用起来比较顺手,换别的学习成本有点高
        10
    bbxiong   62 天前
    @hackfly 感谢回复,我现在就是这样处理的 Server(控制端)收到数据不是直接处理,而是压到 列队里,ui 用定时器 100 毫秒一次从 列队里取用来展示在 ListView 里 ,取一个删一个
        11
    bbxiong   62 天前
    @runtu2019 感谢回复,我现在 Server(控制端)收到数据不是直接处理,而是压到 列队里,ui 用定时器 100 毫秒一次从 列队里取用来展示在 ListView 里 ,取一个删一个,Redis 不熟悉,数据很简单应该不需要这么复杂的东西
        12
    bbxiong   61 天前
    @index90 感谢回复,接收信息是 Server UDP 线程,接收到以后放到列队里,UI 定时器 每 100 毫秒取一个更新到 ListView 上,取出的同时删掉,也就是 pop()
        13
    bbxiong   61 天前
    @FelixLiu 感谢回复,
    1.用 udp 就是考虑本身业务很简单,Server 通过 ListView 展示 Client 来的状态消息,偶尔的发送个控制命令给 Client.
    2.是的,client 每秒 1 个,server 没秒只能处理 10 个,准备吧 client 改成每 10 秒发一个消息
    3.数据丢失不怕,不是重要的东西,Server 简单展示 Client 的状态
    4.改成 TCP 一样存在 client 发送快 ,Server 处理慢导致信息拥挤的问题.
        14
    wuzhizhan   61 天前 via iPhone
    @bbxiong 是否 server 可以分布式,计算出结果 redis 存放,再一个模块读 redis 进行展示
        15
    hackfly   61 天前
    udp iocp 试过吗?
        16
    JerryV2   61 天前
    问题出在服务端处理接收到的消息速度,考虑能否优化消息处理速度,或者通过多线程,提高消息处理能力
    另外客户端发送消息频率的问题你也提到了,必要的发送频率是多少?既然存在重复消息,在发送端是否可以把重复消息屏蔽掉?比如记录上一条消息内容,如果内容重复且服务端已处理则丢弃
        17
    bbxiong   61 天前
    @hackfly 没用过 iocp 只是展示个数据,感觉不需要这么高级的东西
        18
    bbxiong   61 天前
    @JerryV2 处理速度不慢的,只是说 ui 没 100 秒获取数据更新 ListView 如果快了,窗口会卡,造成操作有延迟
        19
    bbxiong   61 天前
    刚才加了个打印,Server 处理显示单条信息的耗时是 0.004 - 0.007 秒
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2506 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 22ms · UTC 14:10 · PVG 22:10 · LAX 07:10 · JFK 10:10
    ♥ Do have faith in what you're doing.