有没有大大搞过高性能的 udp 服务器的,遇到个问题,想请教下。 已经调了两天了,方法基本上都已经试过了。本人小弱鸡,谢谢啦~ - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
qk3z
V2EX    Java

有没有大大搞过高性能的 udp 服务器的,遇到个问题,想请教下。 已经调了两天了,方法基本上都已经试过了。本人小弱鸡,谢谢啦~

  •  
  •   qk3z Dec 13, 2017 5841 views
    This topic created in 3058 days ago, the information mentioned may be changed or developed.
    在不考虑丢包率的状态下,开一个端口服务器最高每秒收包 16w 左右。这个还能有什么方法再提升么?
    我开两个线程两个端口收包,就变成一个端口收 10 多万每秒,一个端口收 4、5 万每秒,感觉不对劲额,是不是有什么问题?先谢谢大家指点了。。。

    忘了说一点,一个数据包 1.3k 左右,大小固定死了。
    Supplement 1    Dec 14, 2017
    我看网卡上每秒是能接收到二三十万包的,但是 java 服务端这边开一个端口最多每秒就十六七万了..。
    把系统内核的 socket 缓存调大,能高个几万,但是和实际网卡接包数还是有差距。
    谢谢大家留言,我先放物理机上再测测,实在不行就放代码了...
    Supplement 2    Dec 14, 2017
    物理机上跑性能果然上升了一倍多,但是多端口多线程还是没什么提升。
    目前存在的问题就是网卡收包速还是略大于程序接收的包数,丢失的数据过多。
    程序就不贴了,就是简单的 udp socket 套接字接收数据,再一次谢谢各位大佬的意见。
    27 replies    2017-12-14 14:19:43 +08:00
    defunct9
        1
    defunct9  
       Dec 13, 2017 via iPhone   1
    开 ssh,我上去看看
    qk3z
        2
    qk3z  
    OP
       Dec 13, 2017
    @defunct9 #1 公司内网服务器...
    likuku
        3
    likuku  
       Dec 13, 2017   1
    网卡 /交换机转发率 /CPU 到顶了?
    defunct9
        4
    defunct9  
       Dec 13, 2017 via iPhone
    程序扔出来看看
    hugee
        5
    hugee  
       Dec 13, 2017   1
    要看具体程序
    changnet
        6
    changnet  
       Dec 13, 2017   1
    一般来说,内网服务器不太可能是因为网络问题,硬件也没变。基本上是你的程序写得有问题,比如你两个线程是不是存在竞争,或者你这个服务器是跑在虚拟机下的,就会这样。
    qk3z
        7
    qk3z  
    OP
       Dec 13, 2017
    @defunct9 #4
    @hugee #5 明天放代码给给位看看,谢谢指点


    @likuku #3 这个是虚拟机,CPU,网卡应该没到顶...
    @changnet #6 是在虚拟机下跑的,准备明天放到物理机上看看有没有提升。要不就是程序写得有问题...
    blahgeek
        8
    blahgeek  
       Dec 13, 2017   1
    之前在 Cloudflare 的 blog 里看到过,个人觉得写的很清晰

    https://blog.cloudflare.com/how-to-receive-a-million-packets/
    https://blog.cloudflare.com/kernel-bypass/
    blahgeek
        9
    blahgeek  
       Dec 13, 2017
    其中提到了你遇到的问题:

    The receiving performance is down compared to a single threaded program. That's caused by a lock contention on the UDP receive buffer side.
    ...
    Fortunately, there is a workaround recently added to Linux: the SO_REUSEPORT flag
    Michaelssss
        10
    a href="/member/Michaelssss" class="dark">Michaelssss  
       Dec 13, 2017   1
    我小小算了下。。。208MB/S,大概比千兆网络强
    changnet
        11
    changnet  
       Dec 13, 2017   1
    @qk3z 虚拟机开多线程、多进程都是会降性能的。双线程大概只有 1/2,三线程 1/3。这个你 google 一下就知道,无论是 virtualbox 还是 vm 都有这个问题。我之前测自己程序性能时也踩这个坑了。
    changnet
        12
    changnet  
       Dec 13, 2017
    @changnet
    @qk3z
    一激动,貌似搞错了。是给虚拟机加 cpu 核心数量性能才会降得这么厉害,就是设置虚拟的 cpu 数量。多线程貌似没这个问题,不过虚拟机是工作在单线程。多线程反而会降一些性能,但是不会降这么厉害。
    wsy2220
        13
    wsy2220  
       Dec 13, 2017   1
    测性能别用虚拟机
    tempdban
        14
    tempdban  
       Dec 14, 2017 via Android   1
    mtcp+dpdk
    Panic
        15
    Panic  
       Dec 14, 2017   1
    绑定进程到特定核试试,cpu 亲和性
    watzds
        16
    watzds  
       Dec 14, 2017 via Android   1
    @blahgeek 你说的是开一个端口,两个线程收,需要加锁。这种情况可以加 SO_REUSEPORT。
    楼主直接开了两个端口吧
    afeicool
        17
    afeicool  
       Dec 14, 2017   1
    好奇实际业务上下文:)
    realpg
        18
    realpg  
    PRO
       Dec 14, 2017   1
    一般普通服务器 udp 纯发包的服务器 万兆网卡只要程序写的不弱智 不任何优化 最次也能跑大约 2.2Gbps
    qk3z
        19
    qk3z  
    OP
       Dec 14, 2017
    @tempdban #14 使用 java 写的...
    @Michaelssss #10 万兆网卡...
    qk3z
        20
    qk3z  
    OP
       Dec 14, 2017
    @afeicool #17 C 那边给发数据包,java 这边接收并统计计算啥的,但是现在这边接收达不到性能要求。
    @realpg #18 是 Java 服务器么... 可能我程序也有问题吧 0.0
    nullen
        21
    nullen  
       Dec 14, 2017   1
    airqj
        22
    airqj  
       Dec 14, 2017   1
    先不要业务逻辑 收到包后就丢掉 看看最大能接收多少
    尽量减少内核态与用户态的数据拷贝
    realpg
        23
    realpg  
    PRO
       Dec 14, 2017 via Android
    @qk3z
    C 和 PYTHON 都能
    JAVA 没研究过
    写高性能服务器很少用
    catror
        24
    catror  
       Dec 14, 2017   1
    你这内核协议栈瓶颈都没达到,不需要上 DPDK 之类的技术。在物理机上测试时,可以考虑两个线程分辨绑定不同的核来测。性能上不去主要原因应该还是 CPU 或者锁竞争。
    defunct9
        25
    defunct9  
       Dec 14, 2017   1
    #include <unistd.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stdio.h>
    #include <stdbool.h>
    #include <arpa/inet.h>
    #include <pthread.h>

    void* do_work(void *arg)
    {
    int *port = (int *) arg;

    int listen_socket = socket(AF_INET, SOCK_STREAM, 0);
    int One= 1;
    setsockopt(listen_socket, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one));

    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(*port);

    int ret = bind(listen_socket, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
    listen(listen_socket, 5);

    struct sockaddr_in cli_addr;
    memset(&cli_addr, 0, sizeof(cli_addr));
    int addr_length = sizeof(cli_addr);

    do
    {
    int cli_sock = accept(listen_socket, (struct sockaddr *) &cli_addr, (socklen_t *) &addr_length);
    close(cli_sock);
    } while (true);

    close(listen_socket);

    return 0;
    }

    int main(int ac, const char *av[])
    {
    int port = atoi(av[1]);

    const int MAX_THREADS = 10;
    pthread_t tid[MAX_THREADS];
    for (int i = 0; i < MAX_THREADS; i++) {
    pthread_create(&tid[i], NULL, do_work, &port);
    }

    for (int i = 0; i < MAX_THREADS; i++) {
    pthread_join(tid[i], NULL);
    }
    return 0;
    }
    qk3z
        26
    qk3z  
    OP
       Dec 14, 2017
    @defunct9 #25 我知道 C 达到这个性能是可以的,但我这个需要用 java 搞定,还是谢谢大佬了。
    janxin
        27
    janxin  
       Dec 14, 2017   1
    先看问题在哪个层面再说吧,从现在的描述细节反正是可以排除硬件层面。
    那么优先考虑代码层面。因为没有就不好猜了。
    其次考虑系统优化层面。如果都调整过了,那回过头去看代码层面。或者写个能处理的 C 程序,证明是代码层面问题(如果时间够,没办法了
    About     Help     Advertise     Blog     API     FAQ     Solana     3247 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 69ms UTC 13:22 PVG 21:22 LAX 06:22 JFK 09:22
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86