简单说一下背景:
我的项目是一个 IoT 数据收集平台,对接了非常多不同类型、不同厂家的设备,每种设备之间的通信方式(如 http/tcp/udp/mqtt 等)、协议编解码方式各不相同;
目前的状况是,IoT 数据收集平台(主程序)独立运行;每个类型的设备,都创建一个 springboot 服务(协议服务),实现不同的通信和编解码,协议服务通过 RocketMQ 发送消息,主程序消费消息,实现数据收集;
这样如果单个协议服务死了,也不会影响其他协议服务和主程序,优点是实现简单(当初就是为了快速搭建起来而这样做),缺点就是服务过多(目前协议服务已经有接近 60 个)、难以管理、对服务器资源占用也大;
看了一些开源的 IoT 平台,完善度比较高的:如 Jetlinks ,源码晦涩难懂,放弃了;
所以我想能不能用插件化实现:如使用 pf4j ,写一个简单的插件,里面写好一些编解码的操作,打包成 Jar 包后,对接进主程序,复用主程序的通信模块和数据上报模块。插件部署了就采集、卸载了就停止;
问: 我的这个想法可不可行? 技术上实现难度高不高? 如可行,有没一些开源的项目可供学习参考?
1
weenhall5 3 天前
osgi
|
2
2han9wen71an 3 天前
osgi
|
3
lolita89201 3 天前
楼上说的 osgi 没用过。 但是 java 做插件化非常容易, 定义好统一的接口, 不同的模块都编译成 jar , 然后动态加载 jar 的 class , 用反射的方式去执行接口函数就好了。
|
4
matcloud 3 天前
Java SPI 了解下,以前给我们平台用这个技术实现过插件系统。
|
5
byteLoading 3 天前 2
通过 SPI 机制可以实现,原生支持,阿里的很多开源组件也都用到了,dubbo 、canal 之类的
https://cn.dubbo.apache.org/zh-cn/docsv2.7/dev/source/dubbo-spi/ https://juejin.cn/post/7054435670244196359 |
6
onikage 3 天前
osgi 感觉不如直接上 java-agnet 简单粗暴。
|
7
sagaxu 3 天前
osgi 就是为这个而生的
|
8
fj19 3 天前
"目前协议服务已经有接近 60 个"....,哪有那么多协议,说的是报文格式?建议了解一下物模型
|
9
huzekang 3 天前
可以了解下 SOFABoot
|
10
4ra1n 3 天前
我手撸过一个:
1. 定义一套接口 2. 核心模块根据这个接口做一些事,调用具体的方法 3. 核心模块启动前使用 URLClassLoader 加载插件目录的 jar 文件 4. 插件目录的 jar 插件需要有第一步这个接口的实现 注意插件 jar 不能自己写一模一样的接口,因为是 ClassLoader 的问题,不认为是同一个类 |
11
Verizon 3 天前
没明白 一个协议服务+不同的编解码器不就行了 如果协议之间有冲突再另外分配端口
|
12
LanLiang 3 天前
在 java 里面调用 javascript 或者 groovy 来做动态解析传感器数据.
|
13
LanLiang 3 天前
协议服务的话就看 SPI 机制
|
14
siweipancc 3 天前 via iPhone
你没研究过日志框架吗……
或者 Hibernate |
15
Cbdy 2 天前
没必要,直接嵌入 JS 代码就可以了
|
16
int0x03 2 天前
如果问题的核心在如何管理和维护这么多服务.
简单一点, 就使用 docker 桌面, dashboard 上面可以停止或启动某个搜集服务. 复杂一点, 就自己搭建一个 kubernetes 集群. 上面提到的 Java 提供的 SPI 本身的设计并不直接支持动态加载和卸载服务提供者,因为它的实现基于静态的 META-INF/services 配置文件和 ServiceLoader 类的设计,这些都在应用程序启动时被加载,并且在运行时不提供动态更新的机制。需要借助于 OSGI 或者自定义类加载器. 然而现实当中看到过很多没处理好加载/卸载的例子, 导致内存泄漏. |
17
Sum0l 2 天前
kubernetes 门槛还是有一点的,一套简化的 devOps 弄下来,挺费事,也只能减轻一部分维护负担。
楼主的主要问题是微服务太多,难以管理、资源浪费,那么解决方向就是减少微服务数量。 协议 agent 服务+主程序解耦,agent 可以考虑抽象分类,一类协议集合在一个 agent 中,agent 使用 SPI 实现热插拔(类加载而已,很普遍),然后用 Spring Cloud 等做下 LB ,监控告警也方便做。 |
18
hangszhang 2 天前
groovy
|
19
hdfg159 2 天前 via iPhone
直接上传 动态执行 groovy 脚本就行了
|
20
night98 2 天前
建议根据通讯方式拆分成 5-6 个协议服务,然后在协议服务内部根据你的经验设计一整套的上下线及接口服务,这样后续的数据收集接入,只需要在相同协议类型的 springboot 项目下,按照 java 接口去实现一下数据的转换逻辑即可。你还可以在设计的整套方案里面加上一些监控之类的,再进一步的话就是统计啊一些什么之类的。你说的插件化没必要搞的那么麻烦,后续部署什么的也很麻烦,其实重点就是风险隔离和数据隔离,你既可以按照现有的部署模式(一个设备类型一个服务),也可以设计成代码都放一起,但是部署的时候根据参数动态的去启用禁用某些模块,也可以做成我刚开始说的那种,以几个大的项目为主,在里面包含小的模块,然后实现动态开关的方式。
|
21
GayGayUp OP @night98 将相同协议类型当成一个服务也考虑过,最大的问题是没办法区分上报内容来源于什么设备;
例如有两款设备都是 tcp 协议,上报内容分别为:FF0001 、FF0002 (0001 和 0002 为设备号),所以作为开发者,仅仅知道设备号,无法区分属于什么设备; |
23
GayGayUp OP 不一个一个 @了,我这里统一回复感谢回复的各位,我研究研究各位大神的方案
|