Skip to content

buexplain/netsvr

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

241 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

netsvr

简介

netsvr

netsvr主要负责:

  1. 承载客户端的websocket连接,并支持存储连接的:业务系统内唯一id、订阅的主题、连接登录后的session信息
  2. 承载业务进程的tcp连接
  3. 接收客户端连接发来的数据,并将数据转发给业务进程
  4. 接收业务进程发来的数据,并按数据中包含的cmd指令:或转发给客户端连接,或自己处理并返回给业务进程

netsvr具体能干嘛:

netsvr能起到桥梁作用,让你的业务进程和客户端之间进行通信,从而实现:

  • 你的业务进程:以单播、批量单播、组播、发布、批量发布、广播等形式,将数据主动下发给客户端连接
  • 你的客户端:订阅主题的数据、取消订阅主题、发送数据给服务端、接收服务端下发的数据

更多功能请阅读:业务进程与netsvr进程的交互协议

如何使用netsvr

具体的使用方式,请参考具体的sdk:

如果只做从服务端下发到客户端,客户端不通过websocket发送数据到服务端,则需要配置CallbackApi相关接口

下面是php语言的laravel框架下的websocket打开和关闭的回调接口示例:

<?php

namespace App\Http\Controllers;

use Exception;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Support\Facades\Log;
use NetsvrProtocol\ConnClose;
use NetsvrProtocol\ConnOpen;
use NetsvrProtocol\ConnOpenResp;
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;

/**
 * websocket打开和关闭的回调接口示例
 * 注册路由的时候一定要注册成post请求,并且加入到VerifyCsrfToken中间件的except属性中
 * composer require google/protobuf
 * composer require buexplain/netsvr-protocol-php
 */
class Controller extends BaseController
{
    use AuthorizesRequests, ValidatesRequests;

    /**
     * websocket连接打开的回调接口
     * @param Request $request
     * @return SymfonyResponse
     * @throws Exception
     */
    public function onopen(Request $request): SymfonyResponse
    {
        $protobuf = $request->getContent();
        $cp = new ConnOpen();
        $cp->mergeFromString($protobuf);
        Log::debug('onopen -->' . $cp->serializeToJsonString());
        $cpResp = new ConnOpenResp();
        $cpResp->setAllow(true);
        $cpResp->setData('欢迎登录,已为您订阅法律相关栏目: ' . $cp->serializeToJsonString());
        $cpResp->setNewSession(json_encode([
            'id' => 1,
            'nickname' => '法外狂徒',
        ]));
        $cpResp->setNewCustomerId("1");
        $cpResp->setNewTopics([
            '法治在线栏目',
            '法考专题栏目'
        ]);
        return response($cpResp->serializeToString(), 200, [
            'Content-Type' => 'application/x-protobuf',
        ]);
    }

    /**
     * websocket连接关闭的回调接口
     * @param Request $request
     * @return SymfonyResponse
     * @throws Exception
     */
    public function onclose(Request $request): SymfonyResponse
    {
        $protobuf = $request->getContent();
        $cc = new ConnClose();
        $cc->mergeFromString($protobuf);
        Log::debug('onclose -->' . $cc->serializeToJsonString());
        return response('', 204);
    }
}

本项目代码结构介绍

  • netsvr.go 是netsvr程序的启动入口。
  • business.go 是为了测试netsvr程序的业务进程启动入口。
  • stress.go 是为了压测netsvr程序的压测进程启动入口,它可以大规模的向网关发起websocket连接。
  • build.sh 是编译脚本,把项目clone下来后,直接跑它(依赖go环境),会自动编译出Windows、Linux、Mac三端的netsvr程序、业务进程程序、压测进程程序。

启动顺序是:netsvr --> 业务进程 --> 压测进程

注意:生产环境只需要netsvr程序

压测数据

场景:

  • 40个群,每个群2500连接,目标连接数是100000
  • 每个连接都是登录状态,绑定:1个userId、2KiB的session
  • 每个群每秒发送3条100B(纯文本内容、不含协议/元数据)的群消息

以上场景要求对应stress.toml中的配置如下:

# 群聊,登录、订阅、发消息
[GroupChat]
Enable = true
# 模拟登录后存储的session长度
SessionLen = 2048
# 群数量
GroupNum = 10
# 发送的消息大小
MessageLen = 100
# 每秒发消息条数
SendSpeed = 3
# 每个群的人数
Step = [
    { ConnNum = 2500, ConnectNum = 100, Suspend = 1 },
]

机器配置:

配置项 规格值
实例类型 腾讯云CVM服务器:X86计算、标准型 SA9
规格代码 SA9.LARGE8
vCPU 4 核
内存 8 GiB
处理器主频/睿频 - / 3.4 GHz
处理器型号 AMD EPYC Turin-D (-/3.4GHz)
内网带宽 2 Gbps
内网每秒包转发数量 30 万 PPS

部署情况: 1台部署netsvr程序,2台机器部署business程序,4台机器部署stress程序

程序运行后,实际压测结果如下:

实际连接数 99999
绑定userId数 99998
群数 40
netsvr程序接收消息并发数平均值(1分钟) 120 msg/s
netsvr程序下发消息并发数平均值(1分钟) 299115 msg/s

系统监控信息 (top):

  • 系统概况
指标 数值
时间 15:07:37
运行时间 up 5:11
用户数 0 user
负载平均值 (1分钟) 5.92
负载平均值 (5分钟) 5.16
负载平均值 (15分钟) 4.22
  • 任务统计
总计 运行中 睡眠 停止 僵尸进程
1 1 0 0 0
  • CPU 使用率
用户态(us) 系统态(sy) 优化(ni) 空闲(id) 等待(wa) 硬件中断(hi) 软件中断(si) 窃取(st)
22.8% 33.5% 0.0% 6.1% 0.0% 0.0% 37.6% 0.0%
  • 内存使用 (MiB)
类型 总计 空闲 已用 缓冲/缓存 可用
内存 7555.2 4938.8 2199.7 708.9 5355.5
Swap 0.0 0.0 0.0 - -
  • netsvr程序进程详情
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
12793 root 20 0 6566132 1.3g 5816 R 332.2 17.2 313:15.07 netsvr-linux-am
  • 关键指标分析

  • CPU 负载极高:

    • 1分钟负载高达 5.92
    • 关键问题: %Cpu(s)si (软中断) 高达 37.6%sy (内核态) 高达 33.5%
    • 这意味着 CPU 大量时间花在处理网络包中断和内核处理上,而非实际的用户程序计算 (us 仅为 22.8%)。
    • 这非常符合网络密集型应用的特征。
  • 进程占用:

    • netsvr-linux-am 进程占用了 332.2% 的 CPU(约占用 3-4 个核心)。
    • 状态为 R (Running),表明该进程正在全速运行。
  • 内存状态:

    • 内存使用正常,主要进程占用 1.3GB (17.2%),剩余可用内存充足 (5.3GB)。

About

基于websocket的网关层,支持php、golang快速开发websocket业务。

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors