当前位置: 首页 > 科技观察

听说你做过建筑设计?来来来,我这里有一个系统设计...

时间:2023-03-15 00:43:01 科技观察

1.初步提示在上一篇《你以为架构师天天就画图写PPT吗,告诉你其他事儿多了去了~》中,我们已经给出了一套完整的数据一致性保障方案。我们从以下三个角度,给出如何实现的解决方案。并通过数据平台和电子商务系统进行实例分析。核心数据监控数据链路追踪自动化数据链路分析至此,我们的架构图大致如下:并且我们也详细讲解了该架构下如何基于MQ实现解耦。那么在本文中,我们将进一步讲解基于该架构的数据一致性。同样,我们以RabbitMQ的消息中间件为例。2.选择性订阅一些核心数据首先,基于MQ实现的一个细节点是,比如一个数据监控系统,他可能只是从MQ订阅一些数据来消费。这是什么意思?因为,比如实时计算平台会把自己计算出来的数据指标全部下发给MQ。但是,这些数据指标可能有几十个,甚至上百个。不可能所有的数据指标都是核心数据吧?基本上,根据我们以往的经验,系统核心数据指标对于这类数据大概只占10%左右。那么对于数据查询平台来说,他可能需要消费所有的数据指标,然后落地到自己的存储中。但是对于数据监控系统,他只需要过滤掉10%的核心数据指标,所以他需要的是选择性订阅数据。我们看看下图,马上就明白是什么意思了。3、RabbitMQ的queue和exchange的绑定不知道大家还记得基于RabbitMQ的多个系统订阅同一个数据的场景。我们使用的是每个系统使用自己的队列,但是都绑定了一个fanoutexchange,然后producer直接把数据投递到fanoutexchange。fanoutexchange会分发一份数据,绑定到自己所有的queue上,然后每个系统从自己的queue中获取同一份数据。再看看下面的图片。这里有一个关键代码如下:也就是把你创建的queue绑定到exchange上。这种绑定关系在RabbitMQ中有一个专业术语叫:绑定。4.直接交换实现消息路由。如果只用以前的fanoutexchange,是不可能实现不同系统按需订阅数据的。如果想让不同的系统按需订阅数据,就需要使用直接交换。直接交换允许您在传递消息时用路由键标记每条消息。同时,directexchange也允许绑定到自己的queue来指定一个bindingkey。这样directexchange会根据消息的routingkey将消息路由到同一个bindingkey对应的queue中,这样不同的系统就可以按需订阅数据了。说了这么多,是不是觉得有点晕,老规矩,来张图直观感受下是怎么回事:而一个队列可以使用多个绑定键,比如使用“k1”和“k2”,如果有的话两个绑定键,那么路由键为“k1”和“k2”的消息将被路由到该队列。同时,不同的队列也可以指定相同的rootingkey。这时候其实和fanoutexchange是一样的。一条消息会同时被路由到多个队列。5.按需订阅的代码实现首先,在生产者端,比如实时计算平台,他应该定义一个直接交换。如下代码所示,所有数据都传递到这个交易所。比如我们这里使用的交易所名称为“rt_data”,表示实时数据计算结果,类型为“direct”:channel.exchangeDeclare("rt_data","direct");而且,在传递消息的时候,需要给消息打上标签,即它的routingkey,指明消息是普通数据还是核心数据,这样才能实现路由,如下代码所示:一个参数是指定投递到哪个交易所,第二个参数为routingkey,其中“common_data”代表普通数据,“core_data”也可以代表核心数据,实时计算平台根据自己指定situation正常或核心数据。那么consumer在进行queue和exchange的绑定时需要指定bindingkey。代码如下:上面第一行是consumer,比如数据监控系统,也定义了directexchange。然后第二行是定义一个“rt_data_monitor”队列。第三行绑定queue和exchange,指定绑定key为“core_data”。如果是数据查询系统,既需要普通数据又需要核心数据,那么可以在bindingkey中指定多个值,用逗号分隔,如下:channel.queueBind("rt_data_query","rt_data","公共数据、核心数据");至此,大家就会明白如何给数据打上不同的标签(即routingkey),然后让不同的系统订阅自己需要的数据(即指定bindingkey)。该方法采用直接交换的方式,非常灵活。最后再看一下我之前画的图,大家可以再感受一下:6.更强大灵活的按需订阅RabbitMQ还支持更强大灵活的按需数据订阅,即使用topicexchange,这其实和Directexchange差不多,只是功能更强大。比如你定义了一个topicexchange,那么routingkey需要指定为以点分隔的多个单词,如下图:然后,当你设置bindingkey时,它支持通配符。*匹配一个词,#匹配0个或多个词,比如你的bindingkey可以这样设置:thisproduct.*.*会匹配“product.common.data”,也就是说,可能某个第一个系统是对商品数据指标感兴趣,不管是通用数据还是核心数据。那么到这里,大家应该就很容易理解了,通过RabbitMQ的直连和话题交换,我们可以轻松实现各种强大的数据点播订阅功能。通过这篇文章,我们将为大家详细讲解最近提到的数据一致性保证方案中的一些MQ中间件的实现细节。