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

Java Go Node 哪种语言最适合做物联网平台开发

  •  
  •   unt · 2023-06-14 14:22:47 +08:00 · 6178 次点击
    这是一个创建于 528 天前的主题,其中的信息可能已经有所发展或是发生改变。
    设备量:10W 台同时在线,同时收发
    对接方式:mqtt,tcp ,websocket (设备种类较多,每种设备不同的对接协议)
    公司背景:中型企业,toB,本公司说了算,出现 bug 也没事
    68 条回复    2023-07-29 17:38:07 +08:00
    zbatman
        1
    zbatman  
       2023-06-14 14:32:02 +08:00   ❤️ 3
    有请 Rust 方辩手登场
    Presbyter
        2
    Presbyter  
       2023-06-14 14:45:20 +08:00
    曾经做过 lorawan, 我们使用的是 mqtt + go + nats 组建的核心网.
    当时选择使用 go 也是因为其网络能力强一些, 当然如果但是 rust 成熟些, 我们可能就选用 rust 了, 因为 leader 是 C 出身......
    yazinnnn
        3
    yazinnnn  
       2023-06-14 14:51:23 +08:00
    iot 用 java 需要大量 netty 的相关技能, 如果研发水平参差不齐的话, 建议用 go

    另外用 node 是图啥...
    Nazz
        4
    Nazz  
       2023-06-14 14:54:21 +08:00   ❤️ 2
    10W 在线量一个 go wbesocket server 实例就够了. 我们最近在跑百万连接压测: https://github.com/lesismal/go-websocket-benchmark
    hhjswf
        5
    hhjswf  
       2023-06-14 15:03:49 +08:00 via Android
    go
    coderxy
        6
    coderxy  
       2023-06-14 15:11:20 +08:00
    用 go 吧。 多协议兼容也很方便。 性能也没啥问题
    runningman
        7
    runningman  
       2023-06-14 15:19:44 +08:00
    go ,绝对是 go
    BBCCBB
        8
    BBCCBB  
       2023-06-14 15:22:12 +08:00   ❤️ 1
    toB 我建议你用 Java, Netty 有大量现成协议支持. mqtt 什么的也有现成方案.

    当然 10w 的量级,你说的这几个任何一个都可以完成..
    unt
        9
    unt  
    OP
       2023-06-14 15:53:17 +08:00
    关于量级:
    大项目会私有化部署,不会走我们的云平台。
    云平台上能做到 10W 的话我们项目也有几千万的体量的了,到时候领导就会重视起来,研发投入就不会再是个问题。
    unt
        10
    unt  
    OP
       2023-06-14 15:54:10 +08:00
    非常感谢各位的解答🙏
    INCerry
        11
    INCerry  
       2023-06-14 16:14:01 +08:00   ❤️ 3
    楼主限定了几种语言,我肯定用 C#,其实几十万同时在线这种需求对于现在有协程 /异步 IO 的开发语言压力都不大,工业物联网这个.NET 成熟和开源的项目蛮多了,基本支持各种协议和驱动,包括一些 PLC 、串口设备都支持。

    举个例子: https://github.com/iioter/iotgateway
    liqinliqin
        12
    liqinliqin  
       2023-06-14 16:23:20 +08:00   ❤️ 3
    我推荐 swoole
    xingjue
        13
    xingjue  
       2023-06-14 16:24:34 +08:00
    物联网绝对 go 必须 go
    smallmin97
        14
    smallmin97  
       2023-06-14 16:26:37 +08:00
    请问下 MQTT Broker 的选型是哪个?我司目前用的是 EMQX 开源版,同时在线数量是 3.5 w 。
    wangritian
        15
    wangritian  
       2023-06-14 16:30:22 +08:00
    必然用协程模型,开发最方便的就是 go 了
    wbuntu
        16
    wbuntu  
       2023-06-14 18:00:36 +08:00
    推荐用 go ,做过类似的物联网项目,服务端对接不同设备,解析二进制协议用 go 比较方便,客户端如果是带 OS 的,用 go 编译出多架构的程序也比较方便
    dudubaba
        17
    dudubaba  
       2023-06-14 18:06:34 +08:00
    都能实现那建议用自己熟练且相对热度不高的,既然有决定权不背锅,技术就掌握在自己手上。
    coder001
        18
    coder001  
       2023-06-14 18:25:49 +08:00   ❤️ 1
    看来用 dot net core 的只有我一个?
    coder001
        19
    coder001  
       2023-06-14 18:29:38 +08:00
    @INCerry #11 WOW ,看来我井还没有没落,没太仔细读回帖就先莽了
    建议不要太过于 “迷信”(🤔?) Task/async/await 的调度机制,到头来可能还不如自己撸线程来的快 :p
    xumiao
        20
    xumiao  
       2023-06-14 19:00:08 +08:00 via iPhone
    @smallmin97 请教一下,请问你们用的什么中间件存储数据呀🥹
    liantian
        21
    liantian  
       2023-06-14 19:04:57 +08:00 via iPhone
    用 ceo cio cto 最擅长的…
    moonheart
        22
    moonheart  
       2023-06-14 19:05:08 +08:00
    go 可以用 tinygo 这个嵌入式编译器 https://tinygo.org/
    zhuangzhuang1988
        23
    zhuangzhuang1988  
       2023-06-14 19:33:53 +08:00
    erlang/elixir ??
    mmdsun
        24
    mmdsun  
       2023-06-14 22:07:10 +08:00
    推荐个最近发现的物联网开源的项目。
    https://github.com/jetlinks/jetlinks-community

    支持统一物模型管理,多种设备,协议适配(TCP,MQTT,UDP,CoAP,HTTP),都很全。
    alsas
        25
    alsas  
       2023-06-14 22:08:16 +08:00
    go 需要超高的并发性能
    flyqie
        26
    flyqie  
       2023-06-14 22:08:42 +08:00
    @zhuangzhuang1988 #23

    总感觉现在只有游戏服务器用 erlang 了。。

    其他好像很少听到有用 erlang 的项目。
    westoy
        27
    westoy  
       2023-06-14 22:23:19 +08:00
    c10k 你上个 python 都没问题.........
    liuhan907
        28
    liuhan907  
       2023-06-14 22:41:05 +08:00   ❤️ 1
    @coder001
    除了纯 CPU 密集的东西---撇开 TPL 这套不谈---可能自己用线程会更好,其它的场景下还有默认调度器劣于手动线程的么?
    zjsxwc
        29
    zjsxwc  
       2023-06-14 23:39:15 +08:00 via Android
    纯 php 的 workerman 也可以,甚至提供了用于轻松实现分布式架构的框架 gatewayworker ,轻松通过加机器来处理大流量。
    tairan2006
        30
    tairan2006  
       2023-06-14 23:45:27 +08:00 via Android
    拿 go 写简单点
    AnroZ
        31
    AnroZ  
       2023-06-15 00:10:19 +08:00
    建议 Golang ,不考虑成本直接上 Rust 。
    someonedeng
        32
    someonedeng  
       2023-06-15 00:26:39 +08:00
    go

    开发简单,性能到位
    tomqin
        33
    tomqin  
       2023-06-15 00:28:31 +08:00 via Android
    K8s 原生,Go 写的物联网开发平台不考虑一下?
    https://github.com/Edgenesis/shifu
    lysS
        34
    lysS  
       2023-06-15 09:19:27 +08:00
    物联网都是有系统的吗?怎么动态语言都能用
    photon006
        35
    photon006  
       2023-06-15 09:26:37 +08:00
    @yazinnnn node 擅长的就是 IO 密集型任务。
    cnbattle
        36
    cnbattle  
       2023-06-15 09:44:13 +08:00
    同建议 go
    BigR
        37
    BigR  
       2023-06-15 10:02:37 +08:00   ❤️ 1
    物联网,建议上 Erlang 。实时性比较好。
    lujiaxing
        38
    lujiaxing  
       2023-06-15 10:05:05 +08:00   ❤️ 2
    没人提 C# 么... 做 IoT C# 简直不要更合适好吧...
    leeyuzhe
        39
    leeyuzhe  
       2023-06-15 10:07:42 +08:00
    mqtt 十万台毛毛雨了吧
    hhjswf
        40
    hhjswf  
       2023-06-15 10:35:27 +08:00
    @yazinnnn netty 框架封装了,做起来反而容易。go 啥都得自己亲力亲为。。
    ychost
        41
    ychost  
       2023-06-15 11:37:58 +08:00
    性能这些语言都不在话下,主要看哪个出问题了能修问题
    yazinnnn
        42
    yazinnnn  
       2023-06-15 11:39:55 +08:00
    @hhjswf 大多数 spring boy 写不了 netty
    coder001
        43
    coder001  
       2023-06-15 11:44:58 +08:00
    @liuhan907 #28

    吾辈在 TCP 异步 Socket 高并发的情况下滥用了异步回调处理收到的数据,响应时间拉长到无法接受,排查发现是调度延迟。
    后来在 SocketAsyncEventArgs 回调把要处理的东西封装成工作项,放进自己维护的线程,用线程安全队列排队处理,这才扛得起来。

    这算 CPU 密集吗🤔 (不过这倒是和主题的物联网沾上边了
    WispZhan
        44
    WispZhan  
       2023-06-15 12:50:25 +08:00 via Android
    中间件用 go ,平台化业务用 Java
    ssr 和 bff 用 node

    好全用上了🐶
    INCerry
        45
    INCerry  
       2023-06-15 13:29:04 +08:00
    @coder001

    > WOW ,看来我井还没有没落,没太仔细读回帖就先莽了 建议不要太过于 “迷信”(🤔?) Task/async/await 的调度机制,到头来可能还不如自己撸线程来的快 :p

    协程主要是为了 IO 密集场景,用异步代替阻塞,用更少的线程做更多的事,IO 密集场景收益肯定更大的。对于单个 task 有延迟的问题肯定是客观存在的,毕竟线程数量更少了 ,任务多了线程任务队列就堆积了,解决方案也可简单,适当提升线程池线程数量,避免线程池饥饿就可以了,很多项目都会设置 MinThread 。
    oldshensheep
        46
    oldshensheep  
       2023-06-15 13:30:38 +08:00
    用 Java 的 Vertx ,容易写好多,和 Go 和 JS 差不多,
    写 Vertx 就一种写 JS 的感觉,太舒服了。而且性能和 Netty 一样都是顶尖水平
    coder001
        47
    coder001  
       2023-06-15 15:04:58 +08:00 via Android
    @INCerry #45
    当然尝试设置最小线程数量,但收效甚微,而且 CPU 使用率显著上升
    lincanbin
        48
    lincanbin  
       2023-06-15 15:10:12 +08:00
    网络应用是 go 的主场。
    DOLLOR
        49
    DOLLOR  
       2023-06-15 15:16:31 +08:00
    微软刚出了个 DeviceScript ,TypeScript 的子集,专门用于物联网开发。
    INCerry
        50
    INCerry  
       2023-06-15 16:34:51 +08:00
    @coder001 我对于这块比较有经验,如果后面有遇到类似的问题,可以抓个 trace 和 dump ,一起分析下,总得来说那块应该不会有很大问题。
    liuhan907
        51
    liuhan907  
       2023-06-15 17:08:27 +08:00
    @coder001
    我比较好奇你的场景使用了多少连接数和 PPS ,还有吞吐量。或者说你对延迟的需求很高?
    Desdemor
        52
    Desdemor  
       2023-06-16 10:26:27 +08:00
    go 可以的,相对简单,并发用协程
    coder001
        53
    coder001  
       2023-06-16 11:29:13 +08:00
    @INCerry #50
    @liuhan907 #51
    先谢过两位

    目前用若干个绑定了队列的线程,每次有回调就挑队列长度最短的分配工作项,压测看起来数据没这么难看了
    压测用 5 万个 TCP 同时打进去,PPS 没测量,几乎所有 PDU 都小于 1400 ,姑且按 PDU 计算的话,极端状况下往返加起来可能会达到( x4 ) 20 万 PDU 每秒。
    协议超时时间是 30 秒,但超过 10 秒就会被称为数据不好看
    liuhan907
        54
    liuhan907  
       2023-06-16 15:18:40 +08:00
    @coder001
    怎么说呢,只有 5W 连接的情况下这个数据感觉有点奇怪。你的原始测试代码还有留存么?
    coder001
        55
    coder001  
       2023-06-16 15:21:53 +08:00
    @liuhan907
    目前性能数据已经可以接受,就不放出来丢人现眼了 _(:з)∠)_
    liuhan907
        56
    liuhan907  
       2023-06-16 15:53:22 +08:00
    @coder001
    我只是好奇为什么数据会这么差,因为和我之前压测的数据比差的不少。
    学习一下,以后避坑(
    coder001
        57
    coder001  
       2023-06-16 16:59:52 +08:00
    @liuhan907
    那就简单来说说 (^ o ^)ノ

    测试环境是 linux k8s 集群,所在节点 4 核 16G (后来加到了 8 核),非独占,还有一些其他东西跑,但不占太多 CPU

    最开始的版本是图省事,嫌复杂懒得用 SocketAsyncEventArgs ( SAE ),监听开单线程阻塞,接收就用 Socket.Select 方法批量轮询,把筛出来的 Socket 滥用 Task.Run 处理接收和协议解析,可以想象线程池会有多窘迫,再多的 MinThread 也处理不过来,只会徒增 CPU 使用率。

    单线程阻塞监听真是太天真了,大量 TCP 同时发起的时候根本 accept 不过来,后来改用 SAE 监听,一上来就安排 1024 个躺在端口前迎接,回调不直接处理,而是放进自己创建的工作线程排队创建应用层会话,加入会话管理器。这下几乎没有连不进去的了。

    后来多几次改进调优就变成完全 SAE 了,监听和接收还有发送全都走 SAE ,只是 SAE 的回调依旧信不过,不在这里做过多的处理,而是自己开线程排队,也能观测一下队列数量来评估性能。

    总算是稍微拯救了一下这难看的数据。

    要问为什么自己撸 Socket 而不用现成框架,我不想回忆被 SuperSocket 折磨的那些年 _(:з)∠)_
    辩解:协议单一,而且相对简单,可以自己来❌
    liuhan907
        58
    liuhan907  
       2023-06-16 17:18:27 +08:00   ❤️ 1
    @coder001
    搞明白了。Select 这个就不多说效率没眼看。至于 SAE 那个确实是专用 IO 线程更好。
    我建议你看一下 asp.net core 现在使用的那个抽象模式以及实现。我认为应该是目前比较好的答案了。
    主要代码在 aspnetcore 项目 src\Servers\Kestrel\Transport.Sockets\src 下面。
    BBCCBB
        59
    BBCCBB  
       2023-06-17 21:41:35 +08:00
    我看大家都在说并发用 go 的协程.. 其实 go 的协程在 socket 量级 10w 这种, 如果你每个 socket 都开 2 个 goroutine, 20w 个协程, go 的调度压力很大的, 这种情况下不太适合有栈协程, 所以你看 go 里也有许多框架封装后就是 netty 的线程模型的样子. 几个 goroutine 就能处理所有 socket 的 IO.

    每个 socket 开两个协程, 写写玩具, 量不大的应用可以, 量上去了就不是这样玩的了.


    还是选择自己擅长的. 稳就对了.
    coder001
        60
    coder001  
       2023-06-20 23:32:20 +08:00 via Android
    @liuhan907 #58
    源代码看起来有点枯燥,倒是发现原来 core 内置的 K 服务还能处理自定义 TCP 这就有意思了,正好有个新的小规模项目可以走这条路整整😋

    https://github.com/davidfowl/MultiProtocolAspNetCore/tree/master/KestrelTcpDemo
    liuhan907
        61
    liuhan907  
       2023-06-20 23:38:32 +08:00
    @coder001
    aspnetcore 的代码可真是不容易看懂,稍有些绕。这个自定义处理 Tcp 我还是在 SignalR 的源码里翻出来的 (
    不过后来我就直接用 ws 了
    coder001
        62
    coder001  
       2023-06-21 00:01:36 +08:00 via Android
    @liuhan907 能用 ws 是我的梦想,一直在做梦,苦于设备目前只支持 TCP 接入
    如果走 ws 就不需要专门开一种 TCP 服务端了,做好高可用使劲加 Web 服务器就成)
    coder001
        63
    coder001  
       2023-06-21 10:55:34 +08:00
    @liuhan907

    另外,我看 Kestrel 源代码时注意到监听是单线程异步,这可能会 accept 不过来,经验告诉我如果几万 TCP 同时打进去,能进去的可能会只有几千个

    https://github.com/dotnet/aspnetcore/blob/main/src/Servers/Kestrel/Transport.Sockets/src/SocketConnectionListener.cs#LL67C64-L67C64
    liuhan907
        64
    liuhan907  
       2023-06-22 01:50:01 +08:00
    @coder001
    以我对 IOCP 的认知,Windows 上应该不会发生这个问题。因为 Accept 慢主要是慢在创建 Socket 上,而 IOCP 创建是系统内核在处理这个问题,不会拖慢应用。
    至于 Linux 上,鉴于我对 epoll 的熟悉程度不如 IOCP ,所以我不是很确定。但是曾经读过 devblog 的文章,里面表示 Linux 上的实现是 epoll + 线程池,所以我觉得可能也没有你担心的问题,可能。
    coder001
        65
    coder001  
       2023-06-28 20:41:07 +08:00
    @liuhan907
    压测了一下 Kestrel 的 TCP 服务端,花了几秒钟来 accept 两万 TCP ,虽然有部分重连,但还是全都连上了

    看来以后可以用它,妈妈再也不用担心我维护不好 Socket 和 SAE 了,乐。
    BifroMQ
        66
    BifroMQ  
       2023-06-29 11:24:20 +08:00
    熟悉哪个选哪个。
    不用担心,99.99%情况下, 语言不会成为瓶颈;
    0.01%情况下业务增长到那个程度早重构了。
    liuhan907
        67
    liuhan907  
       2023-06-29 13:02:29 +08:00
    @coder001
    说不定你再改改配置和 GC 选项,连重连都没了(
    coder001
        68
    coder001  
       2023-07-29 17:38:07 +08:00 via Android
    @liuhan907 回来报喜
    正经项目换 kestrel 重构之后,目前压测连接承载能力摸到 3 万了,需要花一点时间来 accept ,问题不大~
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2781 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 13:03 · PVG 21:03 · LAX 05:03 · JFK 08:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.