![MongoDB进阶与实战:微服务整合、性能优化、架构管理](https://wfqqreader-1252317822.image.myqcloud.com/cover/697/38209697/b_38209697.jpg)
3.6 小技巧——使用固定集合实现FIFO队列
在股票实时系统中,大家往往最关心股票价格的变动。而应用系统中也需要根据这些实时的变化数据来分析当前的行情。
倘若将股票的价格变化看作是一个事件,而股票交易所则是价格变动事件的“发布者”,股票APP、应用系统则是事件的“消费者”。这样,我们就可以将股票价格的发布、通知抽象为一种数据的消费行为,此时往往需要一个消息队列来实现该需求。
在本章的内容中,我们已经领略过固定集合(capped collection)的一些特性。而基于前面的介绍,我们知道这种类型的集合拥有固定的大小,同时满足高性能FIFO读写能力。因此,可以利用固定集合来实现股票系统中的消息队列。
首先,需要在数据库中声明固定集合,通size来指定该消息队列的容量,代码如下:
![](https://epubservercos.yuewen.com/6F449D/20118171608699906/epubprivate/OEBPS/Images/40827_67_1.jpg?sign=1739035591-SB86n5tJ0w8fSRvqYkat5H9uef0A88vD-0-d3971c83a3d6bff2026a9c734d39c1f8)
这样,我们就拥有了stock_queue消息队列,其可以容纳10MB的数据。每一条消息的格式可以定义为如下形示。
![](https://epubservercos.yuewen.com/6F449D/20118171608699906/epubprivate/OEBPS/Images/40827_67_2.jpg?sign=1739035591-DTq7fTtNduxBXMjvwrdciXVmqZYsw4lr-0-4d64ba64aa51cceaa932af966ebc3661)
● timestamp指股票动态消息的产生时间。
● stock指股票的名称。
● price指股票的价格,是一个Double类型的字段。
其中,为了能支持按时间条件进行快速的检索,比如查询某个时间点之后的数据,可以为timestamp添加索引,代码如下:
![](https://epubservercos.yuewen.com/6F449D/20118171608699906/epubprivate/OEBPS/Images/40827_68_1.jpg?sign=1739035591-PuEr2WaFZAdxoaCUhRMGd72qZPewZJ4y-0-3ad1ad486dd4a7efb1296745ae44c91a)
1.发布股票动态
为了模拟股票的实时变动,我们实现如下函数:
![](https://epubservercos.yuewen.com/6F449D/20118171608699906/epubprivate/OEBPS/Images/40827_68_2.jpg?sign=1739035591-EmUYCtU4dzLB1SpESsMk4L9i7S9s6Oyb-0-001bedc0429b84669d7f339098a3057e)
执行pushEvent函数,此时客户端会每隔1秒向stock_queue中写入一条股票信息,结果如下:
![](https://epubservercos.yuewen.com/6F449D/20118171608699906/epubprivate/OEBPS/Images/40827_68_3.jpg?sign=1739035591-o4B0XG2A3HcD9lJiBHgSPAuh4qcqmSpy-0-12c8034fb0c17455189dd6e7c8968289)
2.监听股票动态
对于股票动态的消费方来说,更关心的是最新数据,同时还应该保持持续进行“拉取”,以便知晓实时发生的变化。根据这样的逻辑,可以实现一个listen函数,代码如下:
![](https://epubservercos.yuewen.com/6F449D/20118171608699906/epubprivate/OEBPS/Images/40827_69_1.jpg?sign=1739035591-N7j6Jw3Rf4PG5Yfkm6kp3p6u6htNkQB4-0-fcb54e6eeddf48ed201fcd7c839441f4)
上述代码中,find操作的查询条件被指定为仅查询比当前时间更新的数据,而由于采用了读取游标的方式,因此游标在获取不到数据时并不会被关闭,这种行为非常类似于Linux中的tail-f命令。
接下来,在一个循环中会定时检查是否有新的数据产生,一旦发现新的数据(cursor.hasNext()=true),则直接将数据打印到控制台。
执行这个监听函数,就可以看到实时发布的股票信息,代码如下:
![](https://epubservercos.yuewen.com/6F449D/20118171608699906/epubprivate/OEBPS/Images/40827_69_2.jpg?sign=1739035591-13rdemgvJEb39L77TNMBhv31V3gg2s0X-0-8616c5a09304a745a9b856a328860ac4)
![](https://epubservercos.yuewen.com/6F449D/20118171608699906/epubprivate/OEBPS/Images/40827_70_1.jpg?sign=1739035591-wO6oGWpEt4rwQ1PVUlQvlv2R8y6N3Ffh-0-b8a8de7199714fa0f38a5661068e1697)