golang 实现蓝牙体征监测设备数据上报及存储的频率控制

发布时间: 2022-08-23 15:46:10 作者: 大象笔记

需求背景

蓝牙体征检测设备的初始上报频率非常高,单台每秒 370 个数据包。 需要通过通过服务器向蓝牙网关下发禁止波形数据的指令,禁用掉无用数据的上报。

有两个禁用策略:

显然第二种方式更合理,而且在有多台设备接入的情况下,也方便批量下发(根据 mac 地址)。

但是,这里就出现了一个频率控制问题,就是从下发指令,到禁止成功,是有一个时间间隔的。这个时间间隔内,要规避重复下发指令。

同时,还有另外一个需求,就是对写入数据进行控制,设备方的体温上报频率过高,增加了存储成本,所以同样需要限制。

找到一个 golang 的官方库,可以方便的实现这个频率控制功能:

go get golang.org/x/time/rate

配合 Golang Gin 实现接口限速,可以参考这里

类似场景:IP 限速

https://medium.com/@pliutau/rate-limiting-http-requests-in-go-based-on-ip-address-4e66d1bea4cf

原理就是:

使用 rate 库,每个 ip 对应一个 limiter。对应的这里使用 mac 地址作为 key。

内存控制

如果不断的加 IP,如何控制总内存。

限制 IP 总量,当超过时,清掉长期不用的。虽然目前的应用场景,设备总量可控,而且不太可能超过 1000。

但,这个很容易变成一个漏洞。如果黑客模拟发包,导致 key 总量不可控,内存爆炸。。。是否可以像 nginx 一样,限制内存使用上限。

限速一秒一次

除了直接指定每秒产生的 Token 个数外,还可以用 Every 方法来指定向 Token 桶中放置 Token 的间隔,例如:

limit := rate.Every(1 * time.Second);
limiter := rate.NewLimiter(limit, 1);

https://www.cyhone.com/articles/usage-of-golang-rate/

如何测试

加锁是否会影响性能

频繁 RWMutex Lock 是否影响性能。

不必担心。RWMutex 是读写锁,同时,Lock 是加写锁,RLock 是加读锁,性能更加有保证了。

互斥锁 (sync.Mutex) 和读写锁 (sync.RWMutex)

https://geektutu.com/post/hpg-mutex.html

TODO

我是一名山东烟台的开发者,联系作者