zoukankan      html  css  js  c++  java
  • 架构师之路再刷一下思路记录-5

    消息总线架构

    什么时候使用MQ:跨进程通信传递消息;解耦;如果调用方实时依赖执行结果就不适用;加入MQ系统更复杂,传递路径更长,消息不丢不重难以同时保证

    数据驱动的任务依赖:cron人工排执行时间表:这个似不似有点傻;  用MQ,step1完了发个消息说完了,task2订阅收到step1完了就开始,以此类推;

    上游不关心执行结果:调用(发帖后调用其他相关业务),这个似乎也没有,现在不都MQ了吗,帖子发成功给MQ一个消息,下游订阅;

    上游关注执行结果,但执行时间很长:跨公网调用、离线处理,执行结果很长,可以用回调网关+MQ来解耦; 调用方直接跨公网调用微信接口,微信返回调用成功,此时并不代表返回成功,微信执行完成后,回调统一网关,网关将返回结果通知MQ,请求方收到结果通知

    =======================================================================================

    MQ实现延迟消息: 比如48小时后自动评价

    常见方案:启动一个cron定时任务,每小时跑一次,将完成时间超过48小时的订单取出,置为5星,并把评价状态置为已评价

    select oid from t_order where finish_time > 48hours and status=0;
    update t_order set stars=5 and status=1 where oid in[…];

    如果数据量大,需要分页查询分页更新,所以轮询效率低,已经执行过的还会再被扫,时效性不够好

    好的方案:

    环形队列,本质是个数组,环上每个slot是一个Set<Task>,同时启动一个timer每隔1s,在环形队列中移动一格,有一个Current Index指针来标志正在检测的slot

    Task结构中包含两个重要属性,cycle-num:当current index第几圈扫到这个slot时,执行任务;task-function:需要执行的任务指针

    假设环3600个slot,每秒扫描一个slot,需要3610秒后执行的延时消息到达后,发现当前index指向1,经过计算,应该存在11格子并且应该在一圈之后执行,每秒移动到一个新的slot,看set<task>中每个task的cycle-num是不是0,如果不是0,则经过减1,如果是0,则执行并删除该task

    此方案好处是无需轮询全部订单,效率高,一个订单任务只执行一次,时效性好

    =======================================================================================

    消息的必达:落地 + 消息超时、重传、确认

    发送方 -> MQ -> 接收方

    发送,MQ服务器落地消息,应答成功; MQ服务器发送消息给订阅端,订阅端回复服务器,服务器收到确认,将落地消息删除,完成一次可靠的投递

    =======================================================================================

    幂等

    对于服务端对客户端的确认丢失,导致客户端不断重发,避免服务端收到消息后重复落地,需要对每条消息生成全局唯一并且业务无关的inner-msg-id,由MQ生成并且业务无关,作为去重和幂等的依据

    客户端ack消费到服务端未成功,服务端多次推送消息给消费端,解决方法是业务消息体系中有一个Biz-id,作为去重和幂等依据,对同一个业务场景,全局唯一,由业务消息发送方生成,业务相关,对MQ透明,由业务消息消费方负责判重,保证幂等

  • 相关阅读:
    Java 中无参带返回值方法的使用
    Java 中无参无返回值方法的使用
    如何定义 Java 中的方法
    Java 中的二维数组
    使用 foreach 操作数组
    使用 Arrays 类操作 Java 中的数组
    如何使用 Java 中的数组
    Java 循环语句之多重循环
    UML常用图的几种关系的总结
    JAVA 对象引用,以及对象赋值
  • 原文地址:https://www.cnblogs.com/it-worker365/p/10032676.html
Copyright © 2011-2022 走看看