RabbitMQ 高可用集群搭建及电商平台使用经验总结

RabbitMQ 高可用集群搭建及电商平台使用经验总结,第1张

RabbitMQ高可用集群搭建及电商平台使用经验总结
  • 以面向EDA(事件驱动架构)的方式设计你的信息。

  • AMQP路由密钥的设计

    兔MQ聚类的建立

    镜像队列策略设置

    两个不错的RabbitMQ插件大型应用插件(分片、重定义)

    队列镜像无法手动同步

    每个集群配置同步模式(RabbitMQexport\import)

    客户端连接方式(尽量使用AMQP组动态链接)

    RabbitMQ生产线二次产品化封装(消息补偿、已发送消息持久化、异常处理、页面监控、消除重复消息)

    1。用一种面向EDA(事件驱动架构)的方式设计你的消息 一般情况下,你使用消息中间件的时候,你是在没有设计的情况下使用的,你没有把应用架构和系统架构的界限搞清楚。消息中间件只是一个纯技术工具。你介绍的时候是从应用架构的角度介绍的。这是架构的视角,也是架构的上帝视角,这样你就不会到最后发现越来越多的困惑,也不会结合软件模式、方法论和最佳实践来全面提升系统的架构能力。

    EDA(EventDrivenArchitecture)是一种用于SOA或微服务的架构模式。它的优点有几个,灵活性是高度可伸缩的。

    (请参考我的SOA架构文章:SOA架构设计经验分享——架构、责任、数据一致性)

    既然您想要EDA,那么您应该计划在您当前系统的边界内有多少业务实体。这些实体是围绕领域模型派生的。所以不要在这里定义一些你认为主观的事件。这些事件应该根据业务实体中的对象来设计。商业实体至少有一个唯一的身份。例如,订单和商品都围绕着这些实体。订单可能有几种常见的状态,如创建、支付、交付和取消。商品可能有价格、关键属性修改等等。这些实体的抽象和细化取决于您当前的业务。

    (此内容请参考“领域驱动设计”和“探索CQRS和事件源”)

    这些是相对理论的指导思想。有了这些,你就可以登陆你的Rabbitmq,这样你就不会流浪了。例如,您的消息的名称不会看起来没有结构和层次,deliveryMssage。相反,它应该有一个类似于秩序的结构。delivery.ondeliveryeven(订单。送货。交付完成事件)。

    当你的层次结构不满足业务需求时,可能需要进一步明确事件的范围,order.VIPorder.delivery.ondeliveryeven(order.VIPorder.delivery.delivery完成事件)。

    上图是一个事件驱动的基本场景,它最显著的特点是这些。首先,它是异步的,可以大大提高系统的抗高峰能力。然后就是脱钩。不用说,设计模式的观察者模式没有人知道它的好处。可扩展性,可以按需扩展。比如rabbitmq的节点就可以轻松加入。最后,一致性解决了分布式系统的CAP定理问题。

    2.AMQProutingkey的设计

    AMQP协议规定了路由密钥的设计和交互。为了实现订阅和发布功能,我们需要某种方式来订阅我们感兴趣的事件。因此,在AMQP的绑定中,可以根据路由关键字进行模式匹配。所以这里可以把amqproutingkey和domain事件结合起来,发送的事件相当于amqp中的路由键,可以完美结合。

    你的事件肯定是随着业务的发展而不断增加的,而这个事件集在一开始是无法明确定义的,所以这里有一点需要注意:绑定的时候千万不要把具体的路由键写死。比如订单。送货。ondeliveryeven,这是订单交付。绑定时,routingkey被写成“order。送货。ondeliveryeven”。以后订单事件一扩大,就很麻烦了。订阅了不相关的事件,无法细化或者无法获取事件,因为routingkey已经更改。所以绑定的时候要记住具体的点绑定,也就是带字符串的模式匹配绑定,比如*.delivery.*,*。ondeliveryeven”。以后越来越多的routingkey和event不会影响你的绑定。你只需要根据你的关注程度绑定不同级别的事件。

    在上图中,orderBinding被绑定到order事件,该事件订阅顶级事件,这意味着将来可以订阅任何类型的订单。比如order.normalorder.delivery.ondeliveryevent也可以订阅。而viporderBinding订阅viporder事件,如果发送了order.normalorder.delivery.ondeliveryevent,则与其无关。

    3.RabbitMQcluster搭建

    了解了应用程序架构,我们开始构建RabbitMQ集群。AMQP产品Rabbitmq是用erlang开发的,所以让我们简单介绍一下erlang。

    我第一次正式接触erlang是从rabbitmq开始的。一开始,我也没觉得有什么特别。后来我才知道,越理解越发现自己喜欢上了这门语言。我喜欢它,因为它是一种自然的分布式语言。这句话似乎很常见,但是当您理解erlang.cookie机制时,您就会明白了。我顿悟了。为什么erlang要用于rabbitmq,但是它真的很适合信息交换等软件。Erlang是爱立信专门为开发高性能信息交换机而开发的。仔细想想就会发现,那些软件对性能和稳定性的要求都是极高的。RabbitMQ发现和互联节点真的很方便,集成在erlang的虚拟机中,容错性很高。反正我很喜欢。

    另一个值得骄傲的是RabbitMQ属于伟大的pivotal公司。你应该知道pivotal公司是做什么的。如果你不清楚,建议你马上谷歌一下。

    一开始我并没有太在意他们的版权。后来对pivotalCompany的印象越来越深,突然看到RabbitMQ也是他们家的,信心倍增。这就是影响力和口碑。看看其他公司的spring,springboot,springcloud。我钦佩他们。(RabbtiMQ官网:http://www.rabbitmq.com/)

    3.1.安装erlang&RabbitMQ

    要安装RabbitMQ,首先需要安装和配置它的主机环境erlang。去erlang官网下载erlangotp_src源码包,然后在本地安装源码。(二郎官网:http://www.erlang.org/)

    由于我已经下载了otp_src源码包,所以我使用的是otp_src_19.1版本。下载后解压,然后进入目录执行。/configure-prefix=/usr/Erlang/检查环境并选择安装路径。如果你提示“没有找到curses库函数”错误,那是因为curses库丢失了。安装后配置。

    如果没有错误,安装成功。您还需要配置环境变量:

    导出路径=$PATH:/usr/erlang/bin

    来源/etc/配置文件

    此时,使用erl命令检查erlang是否可以正常工作。

    接下来安装RabbitMQ,去官网下载运行包。

    还要配置环境变量,以便系统可以找到您的命令。然后运行rabbitmq实例。

    这里有一点需要注意。请记住在127.0.0.1中配置主机并添加该机器的名称。Erlang进程需要主机来连接,所以它会检查您的主机配置。还需要设置防火墙,要开放三个端口。5672用于管理接口,25672是集群之间使用的端口,4369由erlangprocessepmd用于节点连接。

    我配置了两个节点,192.168.0.105和192.168.0.107,现在都准备好了。我们添加原账号进入rabbitmq管理界面。

    3.2.配置RabbitMQcluster

    首先确保你所有的rabbitmq节点都是可访问的,打开rabbitmq_management插件,这样当一个节点挂起时,你就可以切换到其他管理界面查看情况或者进行管理。

    打开管理界面插件:

    rabbitmq插件启用rabbitmq_management

    添加账号:

    rabbitmqctladd_useradminadmin

    添加权限标签

    rabbitmqctlset_user_tagsadmin管理员

    确保两个节点都能正常工作。让我们将这两个节点连接起来,形成一个高可用的集群,这样我们的交换和队列就可以在这两个节点之间复制,形成一个高可用的队列。

    Cd到你的主目录,我在root下,里面有一个隐藏的erlang.cookie文件,就是我前面介绍erlang的时候提到的。这个文件是erlang用来发现和互连的基础。我们需要做的很简单,将两个节点中的erlang.cookie设置为相同。这是erlang的约定,同样的cookiehashkey,他认为是合法正确的连接。

    。默认情况下,erlang.cookie是只读的。您需要修改写权限,然后复制并粘贴cookie字符串。

    chmodu+w.erlang.cookie

    配置后,配置主机文件。erlang将使用hosts文件中的配置来发现节点。

    vim/etc/hosts

    192.168.0.107兔子问_节点2

    确保所有节点上的配置相同。要验证您的配置是否正确,您只需要在您的机器上pingrabbitmq_node1,看看您是否配置了请求的ip。根据DNS的请求原则,主机是最高优先级的。除非浏览器有缓存,否则直接使用ping不会有问题。

    选择一个节点停靠点并连接到另一个节点。

    rabbitmqctlstop_app

    rabbitMQCTLjoin_clusterrabbit@rabbitMQ_node2

    用rabbitmq_node2对节点rabbit@rabbitmq_node1进行聚类...

    rabbitmqctlstart_app

    节点已成功连接。

    默认情况下,节点占用的内存占总内存的40%。可以根据自己的使用情况仔细研究一下rabbitmq的配置项。为了提高性能,我们不需要两个节点都是磁盘节点,所以我们需要以RAM模式启动一个节点。

    rabbitmqctl更改_群集_节点_类型ram

    将rabbitmq_node1更改为存储器节点模式。

    4.Mirrorqueuepolicy设置

    节点准备好了。接下来,我们需要设置交换和队列的高可用性策略,这样才能真正实现高可用性。现在物理机或者虚拟机节点高可用,但是里面的对象需要我们配置策略。

    RabbitMQ支持好的策略模式,需要管理员 *** 作。

    首先我们需要创建一个属于自己业务范围的vhost,标记一个逻辑独立空的房间。虚拟机中的所有帐户、策略和队列都是强制的。我创建了一个普通的虚拟主机。

    开始添加警察。

    最重要一个应用于,它可以作用于交换或队列,当然也可以包含两者。有很多选择,最常用的是HAmode和MessageTTL(消息的过期时间)。这些策略根据几个方面进行分组,包括与高可用性、联合、队列和交换相关的方面。可以根据业务场景进行调整。

    我们定义匹配模式。秩序。以便我们可以避免镜像所有exchange和队列。

    我们已经创建了一个新的ex.order.topicexchange,exchange_queue_ha策略已经应用到它的特性中。(同样的策略不能叠加。)其他交易所没有应用这种策略,因为我们的模式限制名称只能匹配.order。

    创建一个qu.order.crm队列,注意在其节点属性中有一个“synchronizedmirrors:rabbitMQ_node2”镜像副本。exchange_queue_ha策略也应用于功能中。此时,队列实际上存在于两个节点中。虽然我们创建它时它在rabbit@rabbitmq_node1中,但是它将被复制到集群中的其他节点。在创建HAmode时,可以提供HAparams参数来限制复制节点的数量,这通常用于提高性能和HA之间的平衡。

    5.两个不错的RabbitMQplugin大型应用插件(Sharding、Rederation)

    rabbitmq里有两个插件——插件,可以试着研究一下。插件列表.

    rabbitMQ-插件列表
    已配置:E=显式启用;e=隐式启用
    |状态:*=运行于rabbitMQ_node1
    |/
    [E*]amqp_client3.6.5
    []cowlib1.0.3
    [E*]mochiweb2.13.1
    []rabbitMQ_amqp1_03.6.5
    []rabbitMQ_auth_backendrabbitMQ_sharding0.1.0
    []rabbitMQ_slope3.6.5
    []rabbitMQ_slope_management3.6.5
    []rabbitMQ_stomp3.6.5
    []rabbitMQ_tracing3.6.5
    []rabbitMQ_trust_store3.6.5
    [e*]rabbitMQ_web

    rabbitmq_sharding,rabbitmq_federation,rabbitmq_sharding的版本有点低。github地址:https://github.com/rabbitmq/rabbitmq-sharding.

    重新定义可用于跨集群或节点同步消息。http://www.rabbitmq.com/federated-exchanges.html

    这是在不同域之间传输消息的一个很好的解决方案。跨机房或网络区域订阅别人的rabbitmq消息总是不稳定。你可以用这种方式传递信息。

    6.Queue镜像失败手动同步

    有时,队列镜像可能会由于各种原因而失败。这时候可以手动同步,而不是像其他分布式系统一样重启节点或者重建数据。

    这样更方便。有时候总有一些小问题需要你手动处理。

    7.各集群配置同步方式(RabbitMQexport\import)

    各种环境下集群配置的同步也是日常运维问题。好在RabbitMQ也提供了相关工具。

    8.客户端连接方式(尽量采用AMQP组来动态链接)

    由于RabbitMQ是amqp协议的实现,我们应该尽量使用AMQP协议进行远程连接

    varamqpList=newList<amqptcpbendpoint>;
    {
    newamqptcpdendpoint(newUri("amqp://192.168.0.105:5672")),
    newamqptcpdendpoint(newUri("amqp://192.168.0.107:5672"))
    };

    其实集群的vip方案也是需要综合考虑的。如果是统一地址,会面临三个问题,DNS,负载均衡,VIP。这三点可能会导致集群连接失败。现在越来越多的方案倾向于在客户端加载和故障转移,这样做有很多好处,消除了中间节点带来的故障概率。这三点加在一起,可用性指数肯定比直接客户端连接低很多。

    我们遇到的大部分问题都是VIP问题。这种系统的VIP不同于数据库。数据库的主\从大部分都是切换前手动检查,主从数据库不会随便自动切换。但是大部分非数据库VIP都是由Keepalived自动检测和切换的,这就带来了一些列问题,包括连接重试和心跳保持。这只是VIP的一个错误。还有负载均衡带来的问题,DNS出错的可能性也很大。所以我倾向于用客户端来做这个。

    有几个要点。第一个是应该带来消息的持久状态,第二个是ContentType。这个属性非常实用,方便您查看邮件正文。

    如果未设置,默认值为null。

    第三个是AutomaticRecoveryEnabled,它自动重试连接,这是致命且重要的。当上面的VIP被切换的时候,这个可以救你一命。第四个是TopologyRecoveryEnabled,恢复交换、队列和绑定。网络断开后,一旦连接恢复,这些设置将被恢复,以确保它们是最新的设置。

    9.RabbitMQ产线二次产品化封装(消息补偿、发送消息持久化、异常处理、监控页面、重复消息剔除)

    无论rabbitmq有多强大,多高可用,都要记得做好备份计划。

    之前我写过一篇文章,WebAPi的可视化输出模式(RabbitMQ,与消息补偿有关)——一个所有WebAPi似乎都缺少的功能。

    也就是说新闻的持久性和补偿性。

    一旦我们坚持我们发送和接收的信息,我们可以做得更多。新闻是可以补偿的,不用担心例外。但是,在发送消息时,必须注意,首先在业务逻辑中处理持久性消息。为了应对特殊活动的监控,可以开发某个业务来监控接收和处理的消息数量,然后自动进行补偿。

    在制定补偿计划时,有一个相当宽容的逻辑。当你对某条信息进行补偿时,你会发送更多的信息,你收到的信息肯定会比你发送的少。所以当你数数的时候,记得要数清楚。

    欢迎分享,转载请注明来源:内存溢出

    原文地址: http://outofmemory.cn/zz/778230.html

    (0)
    打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
    上一篇 2022-05-03
    下一篇 2022-05-03

    发表评论

    登录后才能评论

    评论列表(0条)

    保存