• # RocketMQ 实战:模拟电商网站场景综合案例(二)


    RocketMQ 实战:模拟电商网站场景综合案例(二)

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

    一、SpringBoot 整合 Dubbo :dubbo 概述

    1、dubbo 概述

    Dubbo :是阿里巴巴公司开源的一款高性能、轻量级的 Java RPC 框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。

    2、下载 SpringBoot 集成 Dubbo 的依赖包:dubbo-spring-boot-starter

    https://github.com/alibaba/dubbo-spring-boot-starter

    rocketmq-spring-rocketmq-spring-all-2.0.3.zip

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

    
    mvn install -Dmaven.skip.test=true 
    
    

    4、Dubbo 使用流程图

    在这里插入图片描述


    二、SpringBoot 整合 Dubbo :zookeeper 集群搭建

    1、zookeeper 集群搭建:准备工作

    1.1 安装 JDK
    
    sudo apt install jdk-8
    
    
    1.2 将 Zookeeper 上传到服务器上 /usr/local/zookeeper/
    # 建议下载 zookeeper-3.5 以上完全版本
    
    /usr/local/zookeeper/zookeeper-3.4.6.tar.gz 
    
    /usr/local/zookeeper/apache-zookeeper-3.5.6-bin.tar.gz
    
    
    1.3 解压 Zookeeper,并创建 data 目录,将 conf 下的 zoo_sample.cfg 文件改名为 zoo.cfg
    
    # 切换目录:
    cd /usr/local/zookeeper/
    
    # 解压:
    sudo tar -zvxf zookeeper-3.4.6.tar.gz
    
    # 创建 data 目录:
    mkdir ./zookeeper-3.4.6/data/
    
    # 将 conf 下的 zoo_sample.cfg 文件改名为 zoo.cfg
    mv ./zookeeper-3.4.6/conf/zoo_sample.cfg ./zookeeper-3.4.6/conf/zoo.cfg 
    
    
    1.4 建立 /usr/local/zookeeper-cluster 文件夹,将解压后的 Zookeeper 复制到三个目录。
    
    # 切换目录:
    cd /usr/local/zookeeper/
    
    # 创建 zookeeper-cluster 目录:
    mkdir /usr/local/zookeeper/zookeeper-cluster/
    
    
    # 将解压后的 Zookeeper 复制到三个目录
    cp -rf /usr/local/zookeeper/zookeeper-3.4.6  /usr/local/zookeeper/zookeeper-cluster/zookeeper-1
    cp -rf /usr/local/zookeeper/zookeeper-3.4.6  /usr/local/zookeeper/zookeeper-cluster/zookeeper-2
    cp -rf /usr/local/zookeeper/zookeeper-3.4.6  /usr/local/zookeeper/zookeeper-cluster/zookeeper-3
    
    
    1.5 配置一个 zookeeper 的 dataDir ( zoo.cfg ) , clientPort 分别为:2181, 2182, 2183
    
    # 修改  /usr/local/zookeeper/zookeeper-cluster/zookeeper-1/conf/zoo.cfg 
    cd /usr/local/zookeeper/zookeeper-cluster/
    sudo vim ./zookeeper-1/conf/zoo.cfg 
    
    clientPort=2181
    dataDir=/usr/local/zookeeper/zookeeper-cluster/zookeeper-1/data
    
    
    # 修改  /usr/local/zookeeper/zookeeper-cluster/zookeeper-2/conf/zoo.cfg 
    cd /usr/local/zookeeper/zookeeper-cluster/
    sudo vim ./zookeeper-2/conf/zoo.cfg 
    
    clientPort=2182
    dataDir=/usr/local/zookeeper/zookeeper-cluster/zookeeper-2/data
    
    # 修改  /usr/local/zookeeper/zookeeper-cluster/zookeeper-3/conf/zoo.cfg 
    cd /usr/local/zookeeper/zookeeper-cluster/
    sudo vim ./zookeeper-3/conf/zoo.cfg 
    
    clientPort=2183
    dataDir=/usr/local/zookeeper/zookeeper-cluster/zookeeper-3/data
    
    

    2、zookeeper 集群搭建:配置集群

    2.1 在每一个 zookeeper 的 data 目录下创建一个 myid 文件,内容分别为 1、2、3。这个文件就是记录每个服务器的 ID。
    
    # 切换目录:
    cd /usr/local/zookeeper/zookeeper-cluster/
    
    # 创建并编辑 myid 文件:
    sudo vim ./zookeeper-1/data/myid 
    1
    
    # 创建并编辑 myid 文件:
    sudo vim ./zookeeper-2/data/myid 
    2
    
    # 创建并编辑 myid 文件:
    sudo vim ./zookeeper-3/data/myid 
    3
    
    
    2.2 在每一个 zookeeper 的 zoo.cfg 配置客户端访问端口(clientPort)和集群服务器 IP 列表。
    
    # 切换目录:
    cd /usr/local/zookeeper/zookeeper-cluster/
    
    #  编辑 zoo.cfg 文件:
    sudo vim ./zookeeper-1/conf/zoo.cfg 
    
    # 配置样例:server.服务器 ID = 服务器 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
    
    # 或者:(填写你自己虚拟机的IP地址)
    server.1=172.18.30.110:2881:3881
    server.2=172.18.30.110:2882:3882
    server.3=172.18.30.110:2883:3883
    
    
    #  编辑 zoo.cfg 文件:
    sudo vim ./zookeeper-2/conf/zoo.cfg 
    
    # 配置样例:server.服务器 ID = 服务器 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
    
    # 或者:(填写你自己虚拟机的IP地址)
    server.1=172.18.30.110:2881:3881
    server.2=172.18.30.110:2882:3882
    server.3=172.18.30.110:2883:3883
    
    
    #  编辑 zoo.cfg 文件:
    sudo vim ./zookeeper-3/conf/zoo.cfg 
    
    # 配置样例:server.服务器 ID = 服务器 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
    
    # 或者:(填写你自己虚拟机的IP地址)
    server.1=172.18.30.110:2881:3881
    server.2=172.18.30.110:2882:3882
    server.3=172.18.30.110:2883:3883
    
    

    3、zookeeper 集群搭建:启动集群

    
    # 切换目录:
    cd /usr/local/zookeeper/zookeeper-cluster/
    
    # 启动 zookeeper 
    ./zookeeper-1/bin/zkServer.sh start 
    
    # 启动 zookeeper 
    ./zookeeper-2/bin/zkServer.sh start 
    
    # 启动 zookeeper 
    ./zookeeper-3/bin/zkServer.sh start 
    
    # 查看 zookeeper 启动状态
    ./zookeeper-1/bin/zkServer.sh status 
    
    # 查看 zookeeper 启动状态
    ./zookeeper-2/bin/zkServer.sh status 
    
    # 查看 zookeeper 启动状态
    ./zookeeper-3/bin/zkServer.sh status 
    
    

    三、SpringBoot 整合 Dubbo :dubbo 服务接口开发

    1、打开 idea 创建 springboot-dubbo-interface 项目,并在项目 pom.xml 中添加 依赖。

    
    	--> idea --> File 
    	--> New --> Project 
    	--> Maven 
    		Project SDK: ( 1.8(java version "1.8.0_131" ) 
    	--> Next 
    	--> Groupld : ( djh.it )
    		Artifactld : ( springboot-dubbo-interface )
    		Version : 1.0-SNAPSHOT
    	--> Name: ( springboot-dubbo-interface )
    		Location: ( ...\springboot-dubbo-interface\ )	
    	--> Finish
    
    

    2、在 springboot-dubbo-interface 项目中,创建 接口类 IUseService.java

    
    /**
     *   springboot-dubbo-interface\src\main\java\djh\it\shop\service\IUseService.java
     *
     *   2024-6-4 创建 接口类 IUseService.java
     */
    
    package djh.it.shop.service;
    
    public interface IUseService {
    
        public String sayHello(String name);
    }
    
    
    

    3、把 springboot-dubbo-interface 项目 install 安装一下,让它生成 引用 .jar 包。

    
    右键 springboot-dubbo-interface 项目 ---》Run Maven ---》clean Install 
    ---》target 目录会生成 springboot-dubbo-interface-1.0-SNAPSHOT.jar
    
    或者:
    idea 右边 Maven ---》springboot-dubbo-interface 项目 ---》lifecycle ---》install 
    ---》target 目录会生成 springboot-dubbo-interface-1.0-SNAPSHOT.jar
    
    

    4、打开 idea 创建 springboot-dubbo-provider 项目,并在项目 pom.xml 中添加 接口工程 依赖。

    
    	--> idea --> File 
    	--> New --> Project 
    	--> Maven 
    		Project SDK: ( 1.8(java version "1.8.0_131" ) 
    	--> Next 
    	--> Groupld : ( djh.it )
    		Artifactld : ( springboot-dubbo-provider )
    		Version : 1.0-SNAPSHOT
    	--> Name: ( springboot-dubbo-provider )
    		Location: ( ...\springboot-dubbo-provider\ )	
    	--> Finish
    
    
    
    <?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>djh.it</groupId>
        <artifactId>springboot-dubbo-provider</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <dependencies>
            <dependency>
                <groupId>djh.it</groupId>
                <artifactId>springboot-dubbo-interface</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
        </dependencies>
    
    </project>
    <!-- D:\Java\java-test\idea\springboot-dubbo-provider\pom.xml -->
    
    

    5、打开 idea 创建 springboot-dubbo-consumer 项目,并在项目 pom.xml 中添加 接口工程 依赖。

    
    	--> idea --> File 
    	--> New --> Project 
    	--> Maven 
    		Project SDK: ( 1.8(java version "1.8.0_131" ) 
    	--> Next 
    	--> Groupld : ( djh.it )
    		Artifactld : ( springboot-dubbo-consumer )
    		Version : 1.0-SNAPSHOT
    	--> Name: ( springboot-dubbo-consumer )
    		Location: ( ...\springboot-dubbo-consumer\ )	
    	--> Finish
    
    
    
    <?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>djh.it</groupId>
        <artifactId>springboot-dubbo-consumer</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <dependencies>
            <dependency>
                <groupId>djh.it</groupId>
                <artifactId>springboot-dubbo-interface</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
        </dependencies>
    
    </project>
    <!-- D:\Java\java-test\idea\springboot-dubbo-consumer\pom.xml -->
    
    

    四、SpringBoot 整合 Dubbo :dubbo 服务提供方

    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>djh.it</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>
            <dependency>
                <groupId>djh.it</groupId>
                <artifactId>springboot-dubbo-interface</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
            <!--  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>
                <exclusions>
                    <exclusion>
                        <artifactId>log4j-to-slf4j</artifactId>
                        <groupId>org.apache.logging.log4j</groupId>
                    </exclusion>
                </exclusions>
            </dependency>
            <!--  zookeeper -->
            <dependency>
                <groupId>org.apache.zookeeper</groupId>
                <artifactId>zookeeper</artifactId>
                <version>3.4.10</version>
                <!--  依赖排除,避免多个日志冲突 -->
                <exclusions>
                    <exclusion>
                        <groupId>org.slf4j</groupId>
                        <artifactId>slf4j-log4j12</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>log4j</groupId>
                        <artifactId>log4j</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <!--  zkclieng -->
            <dependency>
                <groupId>com.101tec</groupId>
                <artifactId>zkclient</artifactId>
                <version>0.9</version>
                <exclusions>
                    <exclusion>
                        <artifactId>slf4j-log4j12</artifactId>
                        <groupId>org.slf4j</groupId>
                    </exclusion>
                </exclusions>
            </dependency>
        </dependencies>
    </project>
    <!-- D:\Java\java-test\idea\springboot-dubbo-provider\pom.xml -->
    
    

    2、在 springboot-dubbo-provider 项目中,创建 配置文件 application.properties

    
    ##  D:\Java\java-test\idea\springboot-dubbo-provider\src\main\resources\application.properties
    
    spring.application.name=dubbo-demo-provider
    spring.dubbo.application.id=dubbo-demo-provider
    spring.dubbo.application.name=dubbo-demo-provider
    # spring.dubbo.registry.address=zookeeper://192.168.25.140:2181;zookeeper://192.168.25.140:2182;zookeeper://192.168.25.140:2183
    spring.dubbo.registry.address=zookeeper://172.18.30.110:2181;zookeeper://172.18.30.110:2182;zookeeper://172.18.30.110:2183
    
    spring.dubbo.server=true
    spring.dubbo.protocol.name=dubbo
    spring.dubbo.protocol.port=20880
    
    
    

    3、在 springboot-dubbo-provider 项目中,创建 启动类 ProviderApplication.java

    
    /**
     *   springboot-dubbo-provider\src\main\java\djh\it\shop\springboot\dubbo\ProviderApplication.java
     *
     *   2024-6-4 创建 启动类 ProviderApplication.java
     */
    
    package djh.it.shop.springboot.dubbo;
    
    import com.alibaba.dubbo.spring.boot.annotation.EnableDubboConfiguration;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    @EnableDubboConfiguration
    public class ProviderApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ProviderApplication.class, args);
        }
    }
    
    
    

    4、在 springboot-dubbo-provider 项目中,创建 接口服务实现类 UserServiceImpl.java 。

    
    /**
     *   springboot-dubbo-provider\src\main\java\djh\it\shop\springboot\dubbo\service\impl\UserServiceImpl.java
     *
     *   2024-6-4 创建 接口服务实现类 UserServiceImpl.java
     */
    
    package djh.it.shop.springboot.dubbo.service.impl;
    
    import com.alibaba.dubbo.config.annotation.Service;
    import djh.it.shop.service.IUseService;
    import org.springframework.stereotype.Component;
    
    @Component
    @Service(interfaceClass = IUseService.class)
    public class UserServiceImpl implements IUseService {
        @Override
        public String sayHello(String name) {
            return "hello: " + name;
        }
    }
    
    

    五、SpringBoot 整合 Dubbo :dubbo-admin 管理平台搭建

    1、下载并上传 tomcat 到服务器上。

    
    # 切换目录
    cd /usr/local/zookeeper/ 
    
    # 上传 tomcat : apache-tomcat-7.0.52.tar.gz 
    
    

    2、解压 tomcat

    
    # 切换目录
    cd /usr/local/zookeeper/ 
    
    # 解压 tomcat 
    tar -zvxf apache-tomcat-7.0.52.tar.gz
    
    

    3、下载并上传 dubbo.war 到服务器上。

    
    # 切换目录
    cd /usr/local/zookeeper/apache-tomcat-7.0.52/webapps/
    
    # 上传 dubbo.war : dubbo-admin.war
    
    

    4、启动 tomcat

    
    # 切换目录
    cd /usr/local/zookeeper/apache-tomcat-7.0.52/bin/
    
    # 启动 tomcat 
    ./startup.sh 
    
    # 查看启动日志 
    tail -f ../logs/catalina.log 
    
    

    5、访问 dubbo 控制台。默认用户名、密码:root

    浏览器地址栏输入:、http://虚拟机IP:8080/项目名
    如:http://192.168.25.140:8080/dubbo-admin

    在这里插入图片描述


    六、SpringBoot 整合 Dubbo :dubbo 服务消费方

    1、打开 springboot-dubbo-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>djh.it</groupId>
        <artifactId>springboot-dubbo-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>
    
        <dependencies>
            <dependency>
                <groupId>djh.it</groupId>
                <artifactId>springboot-dubbo-interface</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
            <!--  web -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <!--  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>
                <exclusions>
                    <exclusion>
                        <artifactId>log4j-to-slf4j</artifactId>
                        <groupId>org.apache.logging.log4j</groupId>
                    </exclusion>
                </exclusions>
            </dependency>
            <!--  zookeeper -->
            <dependency>
                <groupId>org.apache.zookeeper</groupId>
                <artifactId>zookeeper</artifactId>
                <version>3.4.10</version>
                <!--  依赖排除,避免多个日志冲突 -->
                <exclusions>
                    <exclusion>
                        <groupId>org.slf4j</groupId>
                        <artifactId>slf4j-log4j12</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>log4j</groupId>
                        <artifactId>log4j</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <!--  zkclieng -->
            <dependency>
                <groupId>com.101tec</groupId>
                <artifactId>zkclient</artifactId>
                <version>0.9</version>
                <exclusions>
                    <exclusion>
                        <artifactId>slf4j-log4j12</artifactId>
                        <groupId>org.slf4j</groupId>
                    </exclusion>
                </exclusions>
            </dependency>
        </dependencies>
    </project>
    <!-- D:\Java\java-test\idea\springboot-dubbo-consumer\pom.xml -->
    
    

    2、在 springboot-dubbo-consumer 项目中,创建 配置文件 application.properties 。

    
    ##  springboot-dubbo-consumer\src\main\resources\application.properties
    
    spring.application.name=dubbo-demo-consumer
    spring.dubbo.application.id=dubbo-demo-consumer
    spring.dubbo.application.name=dubbo-demo-consumer
    spring.dubbo.registry.address=zookeeper://192.168.25.140:2181;zookeeper://192.168.25.140:2182;zookeeper://192.168.25.140:2183
    
    

    3、在 springboot-dubbo-consumer 项目中,创建 启动类 ConsumerApplication.java 。

    
    /**
     *   springboot-dubbo-consumer\src\main\java\djh\it\shop\springboot\dubbo\ConsumerApplication.java
     *
     *   2024-6-4 创建 启动类 ConsumerApplication.java
     */
    
    package djh.it.shop.springboot.dubbo;
    
    import com.alibaba.dubbo.spring.boot.annotation.EnableDubboConfiguration;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    @EnableDubboConfiguration
    public class ConsumerApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ConsumerApplication.class, args);
        }
    }
    
    
    

    4、在 springboot-dubbo-consumer 项目中,创建 调用服务 的 Controller 类 UserController.java

    
    /**
     *   D:\Java\java-test\idea\springboot-dubbo-consumer\src\main\java\djh\it\shop\springboot\dubbo\controller\UserController.java
     *
     *   2024-6-4 创建 调用服务 的 Controller 类 UserController.java
     */
    
    package djh.it.shop.springboot.dubbo.controller;
    
    import com.alibaba.dubbo.config.annotation.Reference;
    import djh.it.shop.service.IUseService;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @RequestMapping("/user")
    public class UserController {
    
        @Reference  //这里不能使用 @Autowired 注解,因为是RPC远程调用,要使用 dubbo 注解 @Reference
        private IUseService useService;
    
        @RequestMapping("/sayHello")
        public String sayHello(String name){
            return useService.sayHello(name);
        }
    }
    
    

    5、启动,测试 访问 dubbo 控制台。默认用户名、密码:root

    1)dubbo 控制台出现 消费者服务。

    在这里插入图片描述

    2)浏览器地址栏输入:、http://虚拟机IP:8080/类名映射/方法名映射?参数=参数值

    如:http://192.168.25.140:8080/user/sayHello?name=zs
    http://localhost:8080/user/sayHello?name=张三丰

    在这里插入图片描述

    上一节关联链接请点击:
    # RocketMQ 实战:模拟电商网站场景综合案例(一)

  • 相关阅读:
    苏州大学:从PostgreSQL到TDengine
    “Ubuntu终端闪退”的解决方法
    OpenFOAM类库介绍(四)对流项
    CSS:变量函数var和自定义属性
    《SpringBoot篇》18.SpringBoot整合Memcached缓存超详细教程
    PC端 Rockchip RKNN-Toolkit 连接 Rockchip NPU 设备
    2022.11.09第6次Javaweb上机——实现登录欢迎页面
    FFmpeg学习总结
    Java证明尼科梅彻斯定理
    三维GIS可视化技术在城市管理中的作用
  • 原文地址:https://blog.csdn.net/qfyh_djh/article/details/139434262