请教下这种情况下有必要上消息队列吗

2020-12-18 12:12:55 +08:00
 zypy333

公司现在做物联网智能楼宇,起步不久,现在的架构是一个项目负责采集设备信息,放到 redis 里,另外一个项目负责从 redis 里读取采集到信息,抽到自己的 mysql 数据库并持久化展示,采集跟抽取都是用定时任务来完成,像能耗系统,温湿度,一些系统频率不高好像没啥问题,但是防盗报警,消防报警这种,如果用 quartz,如果想保证实时性必须把定时任务设置的很频繁才行,会不会对系统压力比较大,查网上资料说消息队列的好处是异步削峰解耦,好像在此场景下都不是强需求

4291 次点击
所在节点    Java
20 条回复
ElmerZhang
2020-12-18 12:18:59 +08:00
想一下如果你的任务如果套在一个死循环里一直执行的话会有多大压力,频繁执行的压力最大也就到那程度了。
根据楼主的描述,取消息的应该只有一端并且是单线程执行的,不会有太大压力。
redis 唯一的问题是消息可靠性,极端情况下有丢消息的可能。
zypy333
2020-12-18 12:29:32 +08:00
@ElmerZhang 主要怕 quartz 挂,我个人觉得这么频繁写在死循环更好,至于丢消息,如果都死循环了是不是就不用担心这件事了
anonydmer
2020-12-18 12:37:34 +08:00
假定采集的定时任务的时间间隔是 M,抽取的是 N,M+N 的时延能满足防盗消防之类的需求?
hantsy
2020-12-18 12:38:31 +08:00
现在只是异步的场景,不在同一个 Domain 的(可能还在同一个程序,为了以后扩展考虑,比如 MS 演进,各 Domain 之间业务尽量不使用太多直接的关联),需要数据同步的情况,全部是用 Message Broker,当然 Spring 首选 RabbitMQ 。
opengps
2020-12-18 12:38:44 +08:00
消息队列的解耦目的更重要,楼主现在的系统压力有多大?小项目建议直接抗,因为你向来可能要扩展的东西还有很多。
探索性业务,一开始不适合被大包袱前进,不适合直接套用各种规范的分布式,甚至 redis 也不应该想你现在说的用法,
条件允许你可以考虑下直接入库,redis 只存需要频繁读写的最新数据
keepeye
2020-12-18 12:44:20 +08:00
为什么要用定时任务呢 redis 有 blpop
haosamax
2020-12-18 12:51:26 +08:00
之前用 schedule 做的也是一个负责采集数据到 redis,一个负责消费
MoHen9
2020-12-18 12:54:32 +08:00
可以先上 Redis 的发布订阅嘛,后面数据量大了,改成 kafka 或者 rabbitmq 也可以,代码风格也一样,改起来很容易。Redis 每秒处理几千条数据没问题的,每条数据最好小一些,当然跟 kafka 或 rabbitmq 还是没得比。
zypy333
2020-12-18 13:15:30 +08:00
@anonydmer 公司好像没人操心延迟....我们是先行开发,设备还没怎么对接呢

@hantsy 抱歉都看不懂你说的 domain 和 MS 演进是什么

@opengps 小项目,但是公司愿景很大,一口气上了二十几个模块,什么消防温湿度考勤停车场广播一卡通,很多都只是 demo,我称之为面向 ppt 编程,至于为啥分两个项目,是因为沿用以前二开的一个.net 项目,现在报警表里还有奇怪的字段压根没用到

@keepeye 考虑过这个方案,项目负责人说目前没有必要,我自己写写试试
xx6412223
2020-12-18 13:42:19 +08:00
quartz 挂是啥意思?你想说的是数据太多,一次 job 的时间会超过 Interval ?
solaya
2020-12-18 13:44:56 +08:00
上 MQ
Weixiao0725
2020-12-18 14:11:00 +08:00
对于报警场景,我觉得你需要的是消息队列的 pub-sub 特性吧
onion83
2020-12-18 14:15:12 +08:00
建议不要自己造轮子,使用成熟的 MQTT 协议和专门的 MQ 队列,阿里云、腾讯云等都有成熟的一整套从接入到分析方案,而且费用很便宜。
BeFun
2020-12-18 14:53:46 +08:00
只要不是实时性非常高的的,我建议用队列,解耦对以后拆分项目,服务降级很友好,我们项目现在就在拆分阶段,改动量小,线上项目影响小
laminux29
2020-12-18 15:00:43 +08:00
物联网业务,要确保的是各种智能设备的稳定性、低负载与低功耗。

从这个角度来说,智能设备与服务器的数据交互模式应该是,服务端把新增或修改的配置信息发给智能设备,智能设备根据配置信息里的数据采集规则,主动向服务端推送。这样做的好处是:

(1).如果智能设备负载过高,它可以通过降低数据推送频率来保持稳定。不然如果是服务端主动采集的话,智能设备可能会因本来就负载过高,还得响应来自服务端的请求,很容易挂掉。另外,如果智能设备功耗过高,或剩余电量不足,它也可以自行调节数据推送的频率,来达到降低功耗,或增加续航时间的目的。

(2).由于智能设备,把数据推往服务器的时间,通常设定为整点时间,比如 14 点 10 分 00 秒,那么服务端在处理接收数据的负载问题上,很容易出现差异很大的峰值现象。也就是说,对于服务端来说,要不在某一刻会同时接收到几乎大部分设备的推送数据,要不在某一时刻干脆就彻底闲着,因为没啥设备推送数据。比如:14 点 10 分 00 秒,1000 台智能设备同时推送数据,导致服务器负载 95%;然后 14 点 10 分 0 秒 - 14 点 19 分 59 秒,整台服务器负载却只有 1%;到了 14 点 20 分 0 秒,智能设备又同时推送,服务器负载飙升。

这问题的本质,同于春运,解决方法只有 2 种:

如果需要保证数据质量,就只能提供消化峰值的足够算力。这需要砸钱配置尽可能多、尽可能强的服务器或服务器集群;

要不,就降低数据推送频率,以及错峰推送,来降低项目预算。错峰推送的意思是,比如:

14 点 10 分 00 秒,ID 为 1-10 的 10 台设备进行数据推送。

5 秒后,

14 点 10 分 05 秒,ID 为 11-20 的 10 台设备进行数据推送。

5 秒后,

.....
zarte
2020-12-18 15:02:04 +08:00
无脑推荐 redis 改 kafka
hyqCrystal
2020-12-18 16:16:05 +08:00
我觉得还是推荐上队列 队列解耦太重要了 且不说定时带来的性能问题,延迟与数据不准确这块就很恼火
mengbai
2020-12-18 16:31:29 +08:00
我们是走 mqtt 协议,设备主动推送数据,服务端接收解析数据入库
teddy2725
2020-12-18 16:36:53 +08:00
redis 也可以 pub sub,也有 stream,重构下就可以了
zypy333
2020-12-18 17:28:12 +08:00
@xx6412223 是担心任务不能成功执行,以前定时任务都没这么高频用过,负载延迟都不清楚
@onion83 我也觉得人家的很好,但是公司好像是想拿自己开发的系统申请专利,未来有机会提一

感谢其他大佬们的建议,不一一回复了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/736716

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX