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

物联网设备 TCP 代理转发系统求助

  •  
  •   unscientific404 · 2023-07-11 16:59:19 +08:00 · 2526 次点击
    这是一个创建于 499 天前的主题,其中的信息可能已经有所发展或是发生改变。

    各位大佬好,求助一个问题:

    我司有一套基于 TCP 协议开发的物联网系统,正常情况设备是和我们机房的后端服务器建立长连接,但是我们有很多属地化平台(后端服务部署在客户机房),这样就需要对设备修改远端服务 IP 。

    同时由于配置的是定向物联网卡,IP 白名单经常搞错导致设备无法联网,因此领导希望开发一个TCP 代理中转系统,所有的设备都接入该服务,再由该服务解析报文里的设备号,决定转发到那个平台(上行和下行数据都需要对应转发)。

    想请教大家有合适的开源方案吗,或者类似的检索关键词,不想重复造轮子(技术栈是 JAVA )谢谢^_^。


    当前情况:

    设备 1 <-> 主平台

    设备 2 <--> 主平台

    设备 3 <--> 主平台

    设备 4 <--> 属地化平台 A

    设备 5 <--> 属地化平台 B

    期望的效果:

    设备 1 <--> TCP 代理 <--> 主平台

    设备 2 <--> TCP 代理 <--> 主平台

    设备 3 <--> TCP 代理 <--> 主平台

    设备 4 <--> TCP 代理 <--> 属地化平台 A

    设备 5 <--> TCP 代理 <--> 属地化平台 B

    第 1 条附言  ·  2023-07-11 17:53:52 +08:00
    大佬们,我们设备用的的协议是行业标准协议,无法更改。还需要兼容市场上存量设备。所以没办法从设备端想办法解决
    43 条回复    2023-07-17 15:18:11 +08:00
    anonymous002
        1
    anonymous002  
       2023-07-11 17:01:05 +08:00
    你这不就类似于反向代理么,可以看看反向代理 frp 之类的源码,很简单
    hankai17
        2
    hankai17  
       2023-07-11 17:07:12 +08:00
    nginx 的 stream 模块?
    Dogtler
        3
    Dogtler  
       2023-07-11 17:12:35 +08:00
    op 这种方案确实可以具备,操作好了基本上能为公司省下很多资金。
    但是有个问题就是,如果是国外的属地化服务后端,高峰时间段下的 tcp 物联网涉及到大量数据上报数据包 会不会造成丢失丢包情况呢?
    FreeWong
        4
    FreeWong  
       2023-07-11 17:12:36 +08:00
    反向代理无法识别自定义协议中的设备号等内容,无法根据设备号重定向 我的经验是得自己开发
    wizzer
        5
    wizzer  
       2023-07-11 17:14:09 +08:00
    MQTT
    FreeWong
        6
    FreeWong  
       2023-07-11 17:14:15 +08:00
    另外移动有非定向卡,可以向任意 IP 地址通讯,这里就没有白名单的问题了,当然如果你们的通讯模块只能使用电信的那就没有办法
    xuxuxu123
        7
    xuxuxu123  
       2023-07-11 17:20:16 +08:00
    把问题进行拆分:
    1 、设备因运营商白名单问题经常导致无法联网
    2 、动态修改设备上报服务端 IP

    第一个问题,行业内有不错的解决方案,并且可以解决同一个运营商白名单数量有限但是客户的服务器超额导致白名单不够的情况
    第二个问题,设备生成方案商 sdk 提供功能,设备上报信息之后获取最新的 ip 即可

    第一个方案不能说太多,毕竟同行业
    Georgedoe
        8
    Georgedoe  
       2023-07-11 17:24:00 +08:00
    ekuiper
    lasuar
        9
    lasuar  
       2023-07-11 17:24:16 +08:00
    要解析报文中的设备号,自己开发一个 TCP 服务不就行了,选一个 java 的 tcp 框架来写就行。
    cpstar
        10
    cpstar  
       2023-07-11 17:26:31 +08:00
    看起来就是要保证服务器端稳定而已,那就搞一个前端代理屏蔽主平台、属地平台 A/B 的变化,nginx-upstream 就解决了。

    如果解析报文设备号,可以配合 nginx 的 lua 脚本,但是不如简单一点,三个平台三个端口号,在设备上配置好访问哪个端口。
    unscientific404
        11
    unscientific404  
    OP
       2023-07-11 17:27:57 +08:00
    @xuxuxu123 谢谢大佬指点。设备的协议是交通部部标协议,是通用协议,需要兼容存量设备,所以无法自定义。另外定向物联网卡的问题这个必须得走,因为我就是运营商的人...
    yazinnnn
        12
    yazinnnn  
       2023-07-11 17:32:27 +08:00
    设备是你们开发的么?
    unscientific404
        13
    unscientific404  
    OP
       2023-07-11 17:35:07 +08:00
    @hankai17 我去了解一下,它可以通过嵌入脚本解析报文获取到设备号,再查询转发地址做转发吗
    unscientific404
        14
    unscientific404  
    OP
       2023-07-11 17:35:38 +08:00
    @Dogtler 我们这个服务只会在国内部署
    unscientific404
        15
    unscientific404  
    OP
       2023-07-11 17:36:39 +08:00
    @FreeWong 我们用的也是移动的物联网卡,不过是定向的必须走 IP 白名单
    xuxuxu123
        16
    xuxuxu123  
       2023-07-11 17:37:13 +08:00
    @unscientific404
    那么这样的话,其实就是一个反向代理的功能,只不过,这个代理程序需要自己手敲硬编码去查库;
    编码难度不大,只是需要考虑高并发、带宽以及网络 IO
    unscientific404
        17
    unscientific404  
    OP
       2023-07-11 17:38:06 +08:00
    @Georgedoe 我研究一下
    unscientific404
        18
    unscientific404  
    OP
       2023-07-11 17:38:53 +08:00
    @yazinnnn 设备是行业标准设备,协议是定死的,不能动
    u20237
        19
    u20237  
       2023-07-11 17:40:11 +08:00
    use udp.
    unscientific404
        20
    unscientific404  
    OP
       2023-07-11 17:44:24 +08:00
    @cpstar 属地化平台很多,未来还会增加。而且设备是市场上的存量标准设备,不能配置
    Erroad
        21
    Erroad  
       2023-07-11 17:58:23 +08:00
    @unscientific404 #13 拆包了,到七层了,用 java 或者 golang 写个转发程序吧
    hankai17
        22
    hankai17  
       2023-07-11 18:01:55 +08:00
    @unscientific404 可以 直接上 openresty
    bugmakerxs
        23
    bugmakerxs  
       2023-07-11 18:03:50 +08:00
    7 层代理应该没有类似的。自己用 nio 整一个吧
    wangzy
        24
    wangzy  
       2023-07-11 18:04:32 +08:00
    搞个 emq cloud 或者企业版,里面含部标协议转换( cloud 最低版本得跟对方说开通 jt808 ),后端订阅 jt808 topic 直接获取解析后的 json ,然后根据设备号转发到其他 topic ,各地机房订阅自己 topic 就可以了。

    emq 这个 jt808 的协议插件我应该是第一个客户,那时候数据都不对,现在用了 2 年多了
    liqinliqin
        25
    liqinliqin  
       2023-07-11 18:20:18 +08:00 via iPhone
    swoole 十分钟完成
    u20237
        26
    u20237  
       2023-07-11 18:25:54 +08:00
    最好大部分协议都支持
    opengps
        27
    opengps  
       2023-07-11 18:29:08 +08:00
    似乎真的需要你介入开发一层,毕竟很多协议都是自定义的,行业里很多这种模式的
    opengps
        28
    opengps  
       2023-07-11 18:29:53 +08:00
    一般来说,推荐用增加一个独立消息队列单独转发位置数据即可
    chinawrj
        29
    chinawrj  
       2023-07-11 18:46:15 +08:00
    iptables 搞个 DNAT 转发就行了啊
    yplam
        30
    yplam  
       2023-07-11 18:48:44 +08:00 via Android
    可以考虑 设备<-->代理 agent<-->代理 server<-->平台 的方式,设备与平台的代码不变,agent 与 server 自己写,可以先按 tcp connection io copy 的方式实现,后面根据运行情况优化
    mineralsalt
        31
    mineralsalt  
       2023-07-11 18:51:01 +08:00
    根本不需要自己搞一套 TCP 系统, 用 docker 一键安装一个开源的 EMQX, 好用的不得了, 各种客户端的 SDK 都有, 单机百万级连接, 支持 MQTT, WebSocket 等等各种协议, 比你们自己琢磨出来的玩意性能不知道好多少
    humbass
        33
    humbass  
       2023-07-11 22:17:06 +08:00 via Android
    思路有问题,正经的做法是:终端先查询服务器地址,然后再进行连接!
    Bijiabo
        34
    Bijiabo  
       2023-07-11 22:40:56 +08:00
    比较好奇对于存量设备的兼容方式是什么,是按照当前情况继续将数据上传到属地华平台,还是会考虑将存量设备 OTA 变更为新的代理实现方案?

    如果只是存量设备保持不变,只考虑新设备入网的时候接入对应的服务,也许可以考虑从配置 TCP 服务变更为配置 MQTT 服务,或者其他方案。物联网的不少业务场景中 TCP 不一定是合适的选择嘛
    cnbatch
        35
    cnbatch  
       2023-07-11 23:06:17 +08:00
    既然你就是运营商员工,那么其实最佳做法是出一套方案,把“IP 白名单搞错”这件事解决掉,因为这是根源所在。比如自动化管理 IP 白名单之类的。

    说真的,按照你们领导的想法,做好了中转系统也许暂时躲避问题,但要是这种做法被客户无意中发现,不就等于收获新的吐槽,比如“运营商搞骚操作,原本直连的卡硬是被他们用中转服务器接管了”,甚至投诉:“你们拦截我们的数据再转发给我们,是不是改了内容?”

    尤其是客户设备出故障的时候,要是你们真的搞了中转系统并且被客户发现,客户们还真有可能会认为是你们修改了数据导致设备损坏。
    Shiweizhi
        36
    Shiweizhi  
       2023-07-11 23:54:13 +08:00
    试试 Node-RED
    gemini
        37
    gemini  
       2023-07-12 01:54:26 +08:00   ❤️ 1
    这种定制类的场景应该没有开源的吧。
    按照楼主描述应该是使用了行业标准协议,没有使用设备厂商 SDK 之类的。

    画重点,需要自行开发一个中转模块(假设叫 RelayServer ),解决数据上行和下行的路由问题。

    需要维护:
    上行路由表:[设备号, 后端服务器信息] (这个是要提前配置好)
    下行路由表:[设备号, 设备连接 Socket] (程序中自行维护)

    1 )上行:
    RelayServer 收到上行数据包,按照协议解析(或部分解析)得到设备号,查询上行路由表得到要转发的后端服务器信息 BackendServerInfo ,转发上行数据。

    检查该设备号是否存在于 [下行路由表] ,若不存在则添加下行路由信息(也就是后面回去的路)

    2 )下行:
    RelayServer 收到上行数据包,根据设备号找到对应 Socket ,转发下行数据。

    ---
    以上为单进程模式大概思路,设备或数据量不是非常大的情况应该能撑得住。
    RelayServer 替换原有服务器,并把原有服务器后移。

    另外,负载较高的是还有可能 RelayServer 会有多台,情况会更复杂一些,可以再多交流。
    tomqin
        38
    tomqin  
       2023-07-12 01:59:24 +08:00 via Android
    开源的 K8s 原生物联网框架 Shifu 试一下?
    https://github.com/Edgenesis/shifu
    可以用 TCPdeviceShifu 实现你要的功能,YAML 直接部署
    教程
    https://github.com/Edgenesis/shifu/tree/main/examples%2FtcpDeviceShifu
    bronco
        39
    bronco  
       2023-07-12 07:42:01 +08:00
    水一个,阿里云的 NLB 就是干这个的,直接用~
    unscientific404
        40
    unscientific404  
    OP
       2023-07-12 08:53:37 +08:00   ❤️ 1
    @Bijiabo 协议是国家颁布的标准协议,走的 TCP ,这个没办法更改。相当于协议不是我们制定的,设备也不是我们生产的。
    wangzy
        41
    wangzy  
       2023-07-12 09:12:20 +08:00
    @unscientific404 jt/t808 吧,java 的有很多实现的
    liu1297528606
        42
    liu1297528606  
       2023-07-12 16:54:18 +08:00 via Android
    感觉直接用 cloudfare 之类的走域名就可以,多设置几个 a 记录,在 cloudfare 配 Ip 映射
    unscientific404
        43
    unscientific404  
    OP
       2023-07-17 15:18:11 +08:00
    @gemini 是的,就是你这个思路
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3055 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 13:51 · PVG 21:51 · LAX 05:51 · JFK 08:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.