RocketMQ(二)

一、案例介绍

1.业务分析

模拟电商网站购物场景中的【下单】和【支付】业务

1)下单

1. 用户请求订单系统下单
2. 订单系统通过RPC调用订单服务下单(确认订单用RPC完成)
3. 订单服务调用优惠券服务,扣减优惠券
4. 订单服务调用调用库存服务,校验并扣减库存
5. 订单服务调用用户服务,扣减用户余额
6. 订单服务完成确认订单

2)支付

1. 用户请求支付系统
2. 支付系统调用第三方支付平台API进行发起支付流程
3. 用户通过第三方支付平台支付成功后,第三方支付平台回调通知支付系统
4. 支付系统调用订单服务修改订单状态
5. 支付系统调用积分服务添加积分
6. 支付系统调用日志服务记录日志

2.问题分析

1)问题1

用户提交订单后,扣减库存成功、扣减优惠券成功、使用余额成功,但是在确认订单操作失败,需要对库存、库存、余额进行回退。

如何保证数据的完整性?使用MQ保证在下单失败后系统数据的完整性

2)问题2

用户通过第三方支付平台(支付宝、微信)支付成功后,第三方支付平台要通过回调API异步通知商家支付系统用户支付结果,支付系统根据支付结果修改订单状态、记录支付日志和给用户增加积分。

商家支付系统如何保证在收到第三方支付平台的异步通知时,如何快速给第三方支付凭条做出回应?通过MQ进行数据分发,提高系统处理性能

二、技术分析

1.技术选型

SpringBoot、Dubbo、Zookeeper、RocketMQ、Mysql

2. SpringBoot整合RocketMQ

下载rocketmq-spring项目

将rocketmq-spring安装到本地仓库

mvn install -Dmaven.skip.test=true

1)消息生产者

1] 添加依赖

<!-- springboot-rocketmq-producer/pom.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.itheima.shop</groupId>
    <artifactId>springboot-rocketmq-producer</artifactId>
    <version>1.0-SNAPSHOT</version>


    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
    </parent>

    <properties>
        <rocketmq-spring-boot-starter-version>2.0.3</rocketmq-spring-boot-starter-version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.apache.rocketmq</groupId>
            <artifactId>rocketmq-spring-boot-starter</artifactId>
            <version>${rocketmq-spring-boot-starter-version}</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.6</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>

</project>

2] 配置文件

# springboot-rocketmq-producer/src/main/resources/application.properties

# nameserver
rocketmq.name-server=192.168.25.135:9876;192.168.25.138:9876
# 发送者组名
rocketmq.producer.group=my-group

3] 启动类

//  springboot-rocketmq-producer/src/main/java/com/itheima/shop/springboot/rocketmq/ProducerApplication.java
package com.itheima.shop.springboot.rocketmq;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ProducerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ProducerApplication.class,args);
    }

}

4] 测试类

//    springboot-rocketmq-producer/src/test/java/com/itheima/shop/test/ProducerTest.java
package com.itheima.shop.test;

import com.itheima.shop.springboot.rocketmq.ProducerApplication;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {ProducerApplication.class})
@Slf4j
public class ProducerTest {

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Test
    public void testSendMessage(){
        rocketMQTemplate.convertAndSend("springboot-rocketmq","Hello Springboot Rockekmq");
        log.info("消息发送成功");
    }
}

2)消息消费者

1] 添加依赖

<!-- springboot-rocketmq-consumer/pom.xml  和生产者差不多相同 -->
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.itheima.shop</groupId>
    <artifactId>springboot-rocketmq-consumer</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
    </parent>

    <properties>
        <rocketmq-spring-boot-starter-version>2.0.3</rocketmq-spring-boot-starter-version>
    </properties>

    <dependencies>

        <!-- 添加web起步依赖,保证消费者不会去停止,持续监听mq的消息 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.rocketmq</groupId>
            <artifactId>rocketmq-spring-boot-starter</artifactId>
            <version>${rocketmq-spring-boot-starter-version}</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.6</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>


    </dependencies>
    
</project>

2] 配置文件

#同生产者
# nameserver
rocketmq.name-server=192.168.25.135:9876;192.168.25.138:9876
# 消费者组名
rocketmq.consumer.group=my-group

3] 启动类

//     springboot-rocketmq-consumer/src/main/java/com/itheima/shop/springboot/rocketmq/ConsumerApplication.java
package com.itheima.shop.springboot.rocketmq;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@Slf4j
@SpringBootApplication
public class ConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class,args);
        log.info("消费者启动成功");
    }

}

4] 消息监听器

// springboot-rocketmq-consumer/src/main/java/com/itheima/shop/springboot/rocketmq/listener/Consumer.java
package com.itheima.shop.springboot.rocketmq.listener;

import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Component;

@RocketMQMessageListener(topic = "springboot-rocketmq",consumerGroup = "${rocketmq.consumer.group}")
//@RocketMQMessageListener(topic = "springboot-mq",consumerGroup = "springboot-mq-consumer-1")//consumerGroup 可以写死
@Component//注册到spring容器中
public class Consumer implements RocketMQListener<String>{

    @Override
    public void onMessage(String s) {
        System.out.println("接收到消息"+s);
    }
}

topic中的第一个参数对应到这儿中找

consumerGroup到这儿中去找 

3.SpringBoot整合Dubbo

下载dubbo-spring-boot-starter依赖包

将dubbo-spring-boot-starter安装到本地仓库

mvn install -Dmaven.skip.test=true

1)搭建Zookeeper集群

1] 准备工作

① 安装JDK

② 将Zookeeper上传到服务器

③ 解压Zookeeper,并创建data目录,将conf下的zoo_sample.cfg文件改名为zoo.cfg

④ 建立/user/local/zookeeper-cluster,将解压后的Zookeeper复制到以下三个目录

/usr/local/zookeeper-cluster/zookeeper-1
/usr/local/zookeeper-cluster/zookeeper-2
/usr/local/zookeeper-cluster/zookeeper-3

⑤ 配置每一个 Zookeeper 的 dataDir(zoo.cfg) clientPort 分别为 2181 2182 2183

   修改/usr/local/zookeeper-cluster/zookeeper-1/conf/zoo.cfg

clientPort=2181
dataDir=/usr/local/zookeeper-cluster/zookeeper-1/data

​    修改/usr/local/zookeeper-cluster/zookeeper-2/conf/zoo.cfg

clientPort=2182
dataDir=/usr/local/zookeeper-cluster/zookeeper-2/data

​    修改/usr/local/zookeeper-cluster/zookeeper-3/conf/zoo.cfg

clientPort=2183
dataDir=/usr/local/zookeeper-cluster/zookeeper-3/data

2] 配置集群

1. 在每个 zookeeper 的 data 目录下创建一个 myid 文件,内容分别是 1、2、3 。这个文件就是记录每个服务器的 ID

2. 在每一个 zookeeper 的 zoo.cfg 配置客户端访问端口(clientPort)和集群服务器 IP 列表。

集群服务器 IP 列表如下

server.1=192.168.25.140:2881:3881
server.2=192.168.25.140:2882:3882
server.3=192.168.25.140:2883:3883

解释:server.服务器 ID=服务器 IP 地址:服务器之间通信端口:服务器之间投票选举端口

3] 启动集群

启动集群就是分别启动每个实例。

2)RPC服务接口

<!--    springboot-dubbo-interface/pom.xml  -->
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.itheima.shop</groupId>
    <artifactId>springboot-dubbo-interface</artifactId>
    <version>1.0-SNAPSHOT</version>

    
</project>
//  springboot-dubbo-interface/src/main/java/com/itheima/shop/service/IUseService.java
package com.itheima.shop.service;

public interface IUseService {
    public String sayHello(String name);
}

3)服务提供者

1] 添加依赖

<!--    springboot-dubbo-provider/pom.xml   -->
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.itheima.shop</groupId>
    <artifactId>springboot-dubbo-provider</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
    </parent>


    <dependencies>

        <!--dubbo-->
        <dependency>
            <groupId>com.alibaba.spring.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>2.0.0</version>
        </dependency>
        <!--spring-boot-stater-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <exclusio
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值