黑马微服务项目-黑马商城学习打卡第6天

基础MQ

课程背景
同步调用优势:时效性强,等待结果后返回
同步调用问题:拓展性差、性能下降、级联失败问题
异步调用
异步调用优势
异步调用的问题:

  • 不能立即得到调用结果,时效性差
  • 不能确定下游业务执行是否成功
  • 业务安全依赖于Broker的可靠性
  • 架构复杂,后期维护和调试麻烦
    技术选型
    RabbitMQ基本介绍
    RabbitMQ的安装参考黑马在线文档
    消息发送的注意事项:
    1.交换机智能路由消息,无法存储消息
    2.交换机只会路由消息给与其绑定的队列,因此队列必需与交换机绑定

shujugeli

数据隔离具体操作步骤见黑马在线文档

1.Java客户端-SpringAmqp

开发业务功能时候不会直接在控制台收发消息,RabbitMQ官方提供的Java客户端编码相对复杂,一般生产环境下我们更多会结合Spring来使用。而Spring的官方刚好基于RabbitMQ提供了这样一套消息收发的模板工具:SpringAMQP。并且还基于SpringBoot对其实现了自动装配,使用起来非常方便。
SpringAMQP提供了三个功能:

  • 自动声明队列、交换机及其绑定关系
  • 基于注解的监听器模式,异步接收消息
  • 封装了RabbitTemplate工具,用于发送消息

SpringAmqp简单收发消息过程:
AMQP

1.1WorkQueues - 任务模型

任务模型:简单来说就是让多个消费者绑定到一个队列,共同消费队列中的消息
背景:当消息处理比较耗时的时候,可能生产消息的速度会远远大于消息的消费速度。长此以往,消息就会堆积越来越多,无法及时处理。多个消费者共同处理消息处理,消息处理的速度就能大大提高了。但消费者处理消息的速度也不同,故均分也不合理。可以通过prefetch来设置让其处理完当前的消息才能取下一条。
work
prefetch在消费者的配置文件中添加配置:

spring:
  rabbitmq:
    listener:
      simple:
        prefetch: 1 # 每次只能获取一条消息,处理完成才能获取下一个消息

1.2交换机

交换机模型
Exchange(交换机)只负责转发消息,不具备存储消息的能力
交换机类型:

  • Fanout:广播,将消息交给所有绑定到交换机的队列。我们最早在控制台使用的正是Fanout交换机
  • Direct:订阅,基于RoutingKey(路由key)发送给订阅了消息的队列
  • Topic:通配符订阅,与Direct类似,只不过RoutingKey可以使用通配符
  • Headers:头匹配,基于MQ的消息头匹配,用的较少。
    jiaohuanji

交换机

Fanout交换机
fanout
Direct交换机
direct

描述下Direct交换机与Fanout交换机的差异?

  • Fanout交换机将消息路由给每一个与之绑定的队列
  • Direct交换机根据RoutingKey判断路由给哪个队列
  • 如果多个队列具有相同的RoutingKey,则与Fanout功能类似

Topic交换机
Topic类型的Exchange与Direct相比,都是可以根据RoutingKey把消息路由到不同的队列。只不过Topic类型Exchange可以让队列在绑定BindingKey 的时候使用通配符

通配符验证:

  • #:匹配一个或多个词
  • *:匹配不多不少恰好1个词
    举例:
  • item.#:能够匹配item.spu.insert 或者 item.spu
  • item.*:只能匹配item.spu

描述下Direct交换机与Topic交换机的差异?

  • Topic交换机接收的消息RoutingKey必须是多个单词,以 . 分割
  • Topic交换机与队列绑定时的bindingKey可以指定通配符
  • #:代表0个或多个词
  • *:代表1个词

声明队列和交换机
基于RabbitMQ控制台来创建队列、交换机。但是在实际开发时,队列和交换机是程序员定义的,将来项目上线,又要交给运维去创建。那么程序员就需要把程序中运行的所有队列和交换机都写下来,交给运维。在这个过程中是很容易出现错误的。推荐的做法是由程序启动时检查队列和交换机是否存在,如果不存在自动创建。
声明
基于Bean声明队列和交换机
示例
基于注解声明队列和交换机
注解

消息转换器:
消息转换器
推荐
业务改造:
业务改造

  1. 添加amqp依赖
  2. 配置文件配置MQ地址
  3. 配置消息转换器,生产者消费者都使用故配置在hm-common模块,此时配置没有生效,其他微服务不包包名不一样不会扫描该配置类,因此采用Springboot自动装配原理在“wp-hmall\hm-common\src\main\resources\META-INF\spring.factories”添加config,让Springboot能够扫描到。
  4. 在trade-service服务中定义一个消息监听类(文档定义的交换机名称为pay.topic)
  5. 改pay-service服务下的com.hmall.pay.service.impl.PayOrderServiceImpl类中的tryPayOrderByBalance方法(此时文档使用的交换机名称为pay.direct,和第4步不一致,以视频为主,定义为pay.direct)

注意在common模块配置消息转换器之后其他模块报错:由于所有的服务都依赖于common,当MqConfig自动配置到Spring时,除去trade和pay服务,其他服务也会自动注入MqConfig中的消息转换器Bean,但其他服务并没有引入amqp的依赖,自然注入失败报错。两种解决方法都行,一种是common里面引amqp的依赖,另一种就是ConditionalOnClass(在MqConfig配置类上添加@ConditionalOnClass(RabbitTemplate.class))

拓展作业第一题,将MQ配置抽取到Nacos中管理,微服务中直接使用共享配置,此时需要给pay-service也添加bootstrap.yaml文件,不要忘了添加相关的两个依赖

        <!--统一配置管理-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <!--读取bootstrap文件-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>

拓展作业第二题:改造下单功能,将基于OpenFeign的清理购物车同步调用,改为基于RabbitMQ的异步通知

  1. cart服务添加amqp依赖,并在bootstrap.yaml文件文件添加mq配置
  2. 在cart-service服务中定义一个消息监听类
package com.hmall.cart.listener;

import com.hmall.cart.service.ICartService;
import com.hmall.common.utils.UserContext;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import org.springframework.amqp.core.Message;
import java.util.Collection;


@Component
@Slf4j
@RequiredArgsConstructor
public class PaySuccessListener {
    private final ICartService cartService;
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = "cart.clear.queue", durable = "true"),
            exchange = @Exchange(name = "trade.topic"),
            key = "order.create"
    ))
    public void listenPaySuccess(Collection<Long> itemIds, Message message){
        Long userId = message.getMessageProperties().getHeader("userId");
        log.info("监听到清空购物车的用户id:{},商品id:{}", userId,itemIds);
        UserContext.setUser(userId);
        cartService.removeByItemIds(itemIds);
    }
}


  1. 改trade-service服务下的trade-service\src\main\java\com\hmall\trade\service\impl\OrderServiceImpl.java类中的createOrder方法的第3步cartClient.deleteCartItemByIds清理购物车商品,不需要cartClient,只需要向队列发送消息。
rrabbitTemplate.convertAndSend("trade.topic", "order.create", itemIds, new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                Long userId = UserContext.getUser();
                log.info("清理购物车商品消息发送成功,用户id,{}", userId);
                message.getMessageProperties().setHeader("userId",userId);
                return message;
            }
        });

重启服务cartservice报错:报错报错1上述报错可以看到错误处在cartservice,才发现是之前注入cartservice时候private final ICartService cartService少了final

步骤2和3的代码我是参考评论里的大佬,评论里还有另一种写法放在这里:
消费者生产者

### 回答1: 2019年黑马项目-畅购商城springcloud微服务实战是一门以实战为主的课程,旨在通过项目实践的方式,帮助学员深入理解和掌握SpringCloud微服务架构以及相关技术的应用。 课程的主要内容包括搭建基础的微服务架构、使用SpringCloud构建服务注册与发现、实现服务间的负载均衡、实现分布式配置中心、服务间的调用与容错处理、使用网关统一接入服务等。通过这些实战练习,学员不仅能够熟悉SpringCloud架构与组件,还能够了解微服务架构下的常见问题与解决方案。 畅购商城项目是一个典型的电商应用,通过实现该项目,学员可以接触到真实的业务场景与需求,并能够将所学知识应用到实际项目中。课程中通过模块化的方式逐步完善商城的功能,包括用户注册登录、商品浏览、购物车管理、订单生成与支付等。通过这些实践,学员除了掌握SpringCloud微服务的开发技术,还能够了解和掌握电商项目的开发流程和注意事项。 该课程的目标是让学员通过实战项目,全面了解和掌握SpringCloud微服务架构的设计与开发,在此基础上能够独立完成具有较高要求的微服务项目。通过参与实战项目的过程,学员还能够提升团队协作能力、解决问题的能力以及项目管理能力。 通过这门课程的学习,学员将会对SpringCloud微服务架构有更深入的理解,并能够将这些知识应用到实际项目中,提高自己在微服务开发领域的竞争力。 ### 回答2: 2019年黑马项目-畅购商城springcloud微服务实战是一个基于springcloud微服务架构的商城项目。该项目的目标是通过运用微服务的理念和技术,构建一个高可用、可扩展的商城系统。 在该项目中,使用了springcloud的多个组件,如Eureka注册中心、Feign负载均衡、Ribbon客户端负载均衡、Hystrix服务降级和容错、Zuul网关等。这些组件共同协作,实现了系统的弹性伸缩和高可用性。 畅购商城的功能包括商品展示、购物车、订单管理、支付、用户管理等。通过将这些功能拆分成独立的微服务,使得系统更加灵活和可维护。同时,使用分布式事务和消息队列来保障数据的一致性和可靠性。 在项目的开发过程中,采用了敏捷开发的方法,以迭代的方式进行开发和测试。通过使用Jenkins进行持续集成和部署,保证了代码的质量和系统的稳定性。 在项目的实战过程中,面临了许多挑战和困难,如微服务之间的通信、服务的负载均衡、服务的容错等。但通过团队的共同努力和不断的学习,最终成功地完成了该项目的开发和部署。 在该项目的实施过程中,不仅学到了springcloud微服务架构的相关知识和技术,还体会到了团队合作和解决问题的能力。该项目的成功实施,不仅为公司带来了商业价值,也提升了团队的技术水平和项目管理能力。 ### 回答3: 2019年黑马项目-畅购商城springcloud微服务实战是一个以Spring Cloud为基础的微服务项目微服务架构是一种将应用拆分成多个小型服务的架构模式,这些服务可以独立开发、部署、扩展和管理。 畅购商城项目使用了Spring Cloud的一系列子项目,如Eureka、Ribbon、Feign、Hystrix、Zuul等,来实现各个微服务之间的通信、负载均衡、服务降级与熔断等功能。 在项目中,我们会通过Eureka来实现服务的注册与发现,每个微服务都会向Eureka注册自己的地址,其他微服务可以通过Eureka来发现并调用这些服务。而Ribbon则负责实现客户端的负载均衡,可以轮询、随机、加权等方式分发请求。 Feign是一种声明式的HTTP客户端,它简化了服务间的调用方式。我们只需编写接口,并通过注解来描述需要调用的服务和方法,Feign会自动实现远程调用。 Hystrix是一个容错机制的实现,可以通过断路器来实现服务的降级与熔断,当某个服务出现故障或超时时,Hystrix会快速响应并返回一个可控制的结果,从而保证系统的稳定性。 另外,Zuul作为微服务网关,可以实现请求的统一入口和路由转发,提高系统的安全性和性能。 通过这些Spring Cloud的组件,畅购商城项目可以实现高可用、容错、自动扩展等优质的微服务架构。 总之,2019年黑马项目-畅购商城springcloud微服务实战是一个基于Spring Cloud的微服务项目,通过使用Spring Cloud的各个子项目,可以实现微服务之间的通信、负载均衡、服务降级与熔断等功能,为项目的开发、部署和管理提供了便利。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值