栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【微服务-MQ消息推送】

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【微服务-MQ消息推送】

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录
  • 一、跨项目,跨服务之间的通信方式
      • 1.无论是跨项目通信,还是跨服务通信,cloud中通信方式基本就是两种:
      • 2.关于银行跨行转账:
      • 3.我们发邮件,发短信,发站内信时最好使用异步编程
      • 4.如何实现异步编程?
  • 二、消息队列MQ
    • 1.消息队列的四个使用场景
    • 三.课程上线消息推送
    • 四.单独搭建一个消息推送服务;
      • 第一步:依赖
      • 第二步:启动类
      • 第三步:bootstrap.yml
      • 第四步:在消息服务中,新建一个配置类声明交换机,队列,绑定关系
      • 第五步:在消息服务中新建一个dto类
      • 第六步:在消息服务中新建一个MsgController
      • 第七步:在消息服务中搭建一个hrm-msg-feign模块
      • 第八步:新建一个MsgProducerClentFallback类,实现。。。FallBack接口,泛型是
    • 五.其他服务调用消息服务:
    • 六.准备一个消费者模块,从MQ中拉取消息消费
      • 5.注意:
  • 总结


例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


一、跨项目,跨服务之间的通信方式 1.无论是跨项目通信,还是跨服务通信,cloud中通信方式基本就是两种:

1)不同项目中:A项目直接给B项目发送Http请求或RPC请求,同一个项目中,A服务直接给B服务发送Http请求或RPC请求;(OpenFeign,Ribbon就是使用这种方式)
以下图为例子:A项目发送Http请求或者RPC请求,直接访问项目B,这种直接访问的方式具有强一致性:就是说A服务必须要等到B服务返回结果才能继续往下执行;
所以这种就不太好;

2)项目A,项目B之间通过MQ进行通信,MQ是天然具有异步性的,A项目通过MQ发送消息给到B项目,B项目从MQ拉取项目然后进行消费;
这样的好处就是:A项目往MQ推送消息后就可以不用管了,就可以继续做其他事情;

总结:当跨项目进行通信时,我们建议使用MQ;当跨服务进行通信时,使用OpenFeign就可以了;

2.关于银行跨行转账:

比如工商银行与中国银行之间的跨行转账,这两家银行的系统绝对是两个不同的项目,所以它们一定是使用MQ进行通信的;
为什么它们不是用Http请求直接通信的?因为如果是使用Http请求,会存在强一致性问题,工商银行发起跨行转账后,必须等到中国银行返回了消息结果给工商银行,工商银行这边的跨行转账业务才算完成成功,但是中国银行肯定会优先完成自己的业务,所以这种情况,工商银行就会等很久,显然不合适;所以银行跨行转账才使用MQ操作;
但是使用MQ通信会存在消息排队的问题;所以当天跨行转账的人数很多时,跨行到账的时间可能会有较久的延迟;但是银行会保证24小时之内能到账,那银行到底是如何保证的?
银行会根据跨行转账的业务繁忙程度动态的增加消费者,平时业务不这么忙的时候,消费者就开少一点,一忙起来,消费者就躲开,增强处理请求的能力,所以它们能保证24小时内完成跨行转账;

3.我们发邮件,发短信,发站内信时最好使用异步编程

项目二中发邮件,发短信,发站内信存在一个问题,前端平台客户点击发送邮件后,如果不采用异步编程,假如后台发送邮件的逻辑处理变慢,那么就会导致前端的邮件发送界面一直转圈;体验很不好;
使用异步编程的好处是:用户点击发送邮件后,只要一点,就不用再等待后台返回结果给前端了;用户就可以继续再干其他的事,比如继续发送下一封邮件等;

4.如何实现异步编程?

1.使用MQ,MQ天然就是异步的。2.单独开一个线程,多线程当然是异步的。
其中使用多线程时,我们可以考虑线程池,比我们手动开启线程方便的多;

二、消息队列MQ 1.消息队列的四个使用场景

总体来说:只要项目中需要处理异步、消峰、解耦、通信的地方都可以使用消息队列:
1)不同项目或者服务之间发生通信时,可以使用MQ来传递消息;
场景:异步下单中,秒杀服务需要将下订单所需的数据作为消息内容传递给订单服务;页面静态化功能中,后端生成静态页面上传到OSS后,将地址作为消息推送到消息前端项目服务器部署的Java项目(消费者);
2)异步:生产者发送消息后,无需等待消费者处理完毕消息;
场景;微服务电商平台里面秒杀活动中,秒杀服务中通过分布式锁技术扣减库存,然后推送消息到订单服务;
3)消峰:消息队列可以配置最多允许多少个消息在队列中排队;
场景:规定同一时间内不能有太多请求(假设1000个)进入到消费者项目接口;假设此时瞬间来了1万个消息,其余9000个消息先进入死信队列,然后配合一个定时任务,每隔一段时间从死信队列里面拿出前面的N个消息补充到正常队列中;
4)解耦:应用程序之间进行通信是松耦合的,应用程序之间无需通过HTTP或者RPC请求进行调用;
场景:跨行转账、支付宝微信提现;

三.课程上线消息推送

1.架构设计

四.单独搭建一个消息推送服务; 第一步:依赖

第二步:启动类 第三步:bootstrap.yml 第四步:在消息服务中,新建一个配置类声明交换机,队列,绑定关系
@Configuration
public class MQ {
    //交换机
    private static final String EXCHANGE_HRM_MSG_TOPIC = "exchange_hrm_msg_topic";
    //短信队列
    private static final String QUEUE_HRM_MSG_SMS = "queue_hrm_msg_sms";
    //邮件队列
    private static final String QUEUE_HRM_MSG_EMAIL = "queue_hrm_msg_email";
    //站内信队列
    private static final String QUEUE_HRM_MSG_SYSTEM_MESSAGE = "queue_hrm_msg_system_message";

    @Bean
    public Exchange exchange(){
        return ExchangeBuilder.topicExchange(EXCHANGE_HRM_MSG_TOPIC)
                .durable(true)
                .build();
    }
    @Bean(QUEUE_HRM_MSG_SMS)
    public Queue queueSms(){
        return QueueBuilder.durable(QUEUE_HRM_MSG_SMS).build();
    }
    @Bean(QUEUE_HRM_MSG_EMAIL)
    public Queue queueEmail(){
        return QueueBuilder.durable(QUEUE_HRM_MSG_EMAIL).build();
    }
    @Bean(QUEUE_HRM_MSG_SYSTEM_MESSAGE)
    public Queue queueSystemMessage(){
        return QueueBuilder.durable(QUEUE_HRM_MSG_SYSTEM_MESSAGE).build();
    }
    @Bean
    public Binding bindingSms(Exchange exchange, @Qualifier(QUEUE_HRM_MSG_SMS)Queue queue){
        return BindingBuilder
                .bind(queue)
                .to(exchange)
                .with("sms.#")
                .noargs();
    }
    @Bean
    public Binding bindingEmail(Exchange exchange, @Qualifier(QUEUE_HRM_MSG_EMAIL)Queue queue){
        return BindingBuilder
                .bind(queue)
                .to(exchange)
                .with("email.#")
                .noargs();
    }
    @Bean
    public Binding bindingSystemMessage(Exchange exchange, @Qualifier(QUEUE_HRM_MSG_SYSTEM_MESSAGE)Queue queue){
        return BindingBuilder
                .bind(queue)
                .to(exchange)
                .with("system.message.#")
                .noargs();
    }
}
第五步:在消息服务中新建一个dto类

这个Msg类

第六步:在消息服务中新建一个MsgController

新建一个接口push,这个接口的作用是让消息服务能推送消息到MQ中;
其他服务在调用消息服务时push接口时,需要传递Msg对象过来;

把msg作为消息推送到mq中;

第七步:在消息服务中搭建一个hrm-msg-feign模块

其他服务要调用消息服务时,就可以调用hrm-msg-feign模块
注意:下图中的MsgProducerClientFallback后面有.class,截图只截少了一部分;
MsgController类上的@RequestMapping是@RequestMapping(“/msgProducer”),push接口的@RequestMapping是(“/push”);所以MsgProducerClent接口中,可以在@FeignClient注解中加path = “/msgProducer” ,也可以直接加在MsgProducerClent接口的push方法上面的@PostMapping中,就像上图这样;

第八步:新建一个MsgProducerClentFallback类,实现。。。FallBack接口,泛型是 五.其他服务调用消息服务:

其他服务要调用消息服务时,首先要创建一个Msg对象;
以发送短信为例:
msg要设置接收方的电话,还要设置routingkey,以便找到具体哪个路由;

六.准备一个消费者模块,从MQ中拉取消息消费

1.配置yaml
2.配置bootstrap.yaml
3.准备pom
①jackson-databind这个依赖是用来序列化Msg对象的;
②导入hrm-msg-common依赖,是因为消息传输对象Msg类是写在hrm-msg-common模块的;
③导入starter-amqp依赖是因为消费者要从MQ拉取消息,所以要starter-amqp依赖

4.消费者模块中新建一个监听类
消费者收到消息后的业务处理逻辑都写在监听类中

@RabbitListener注解表示这是一个RabbitMq的监听类,要在@RabbitListener里面指定当前类具体监听的哪一个队列,要指定队列名称;
形参里的Msg是消息推送服务往MQ推送的消息,推送的什么,Msg msg这里就填什么;后面两个参数Message message,Channel channel 不变;
然后通过message.getMessageProperties()可以获得mq的所有属性参数,然后.getDeliveryTag()就可以获得deiveryTag对象;注意multiple基本都会设置为false;

5.消息序列化
往MQ传输消息的时候,需要将消息序列化:
消息序列化的两种方式:JDK序列化和JSON序列化,我们采用JSON序列化的方式,因为它更优秀;
首先:
在调用消息服务的课程服务中,新建一个配置类,自定义一个RabbitTemplate的@Bean,用来覆盖掉starter-amqp依赖中自带的RabbitTemplate;代码写法如下:

其次:

5.注意:
总结

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1003885.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号