• Dubbo 01 基础概念与入门工程搭建


    Dubbo 01 基础概念与入门工程搭建

    1. 概述基本概念

    定义

    Apache Dubbo |ˈdʌbəʊ| 是一款高性能、轻量级的开源 Java RPC 框架,它提供了三大核心能力:

    1. 面向接口的远程方法调用
    2. 智能容错和负载均衡
    3. 以及服务自动注册和发现。

    架构

    角色

    1. Registry 注册中心,用于服务的注册与发现。
    2. Provider 服务提供者,通过向 Registry 注册服务。
    3. Consumer 服务消费者,通过从 Registry 发现服务。后续直接调用 Provider ,无需经过 Registry 。
    4. Monitor 监控中心,统计服务的调用次数和调用时间。
    5. Container 服务运行容器。

    调用关系

    1. 服务容器负责启动,加载,运行服务提供者。
    2. 服务提供者在启动时,向注册中心注册自己提供的服务。
    3. 服务消费者在启动时,向注册中心订阅自己所需的服务。
    4. 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
    5. 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
    6. 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

    2. 入门工程搭建

    2.0 安装Zookeeper

    以本机为例:官网下载包,安装后有如下环境:

    • 端口:2181
    • 安装地址:E:apache-zookeeper-3.6.1in
    • 启动服务:E:apache-zookeeper-3.6.1inzkServer.cmd
    • 客户端: E:apache-zookeeper-3.6.1inzkCli.cmd

    2.1 XML方式

    dubbo-xml-demo
        ├─user-rpc-service-api
        ├─user-rpc-service-consumer
        └─user-rpc-service-provider
    

    2.1.1 Api

    user-rpc-service-api 项目,服务接口,定义 Dubbo Service API 接口,提供给消费者使用。

    1. UserDTO

    nbyucaidubbo acosdemodto下,新建UserDTO模拟传输对象

    @Data
    public class UserDTO implements Serializable {
        
        /**
         * 用户编号
         */
        private Integer id;
    
        /**
         * 昵称
         */
        private String name;
    
        /**
         * 性别
         */
        private Integer gender;
    
        public UserDTO setName(String name) {
            this.name = name;
            return this;
        }
    
        public UserDTO setId(Integer id) {
            this.id = id;
            return this;
        }
    
        public UserDTO setGender(Integer gender) {
            this.gender = gender;
            return this;
        }
    }
    
    1. UserRpcService

    nbyucaidubbo acosdemo新建UserRpcService.java

    public interface UserRpcService {
        /**
         * 根据指定用户编号,获得用户信息
         *
         * @param id 用户编号
         * @return 用户信息
         */
        UserDTO get(Integer id);
    
        Integer add(UserDTO dto);
    }
    

    2.1.2 Provide

    1. pom.xml添加如下依赖
    <!-- 引入定义的 Dubbo API 接口 -->
    <dependency>
        <groupId>nb.yucai</groupId>
        <artifactId>user-rpc-service-api</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    
    <!-- 引入 Spring Boot 依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    
    <!-- 实现对 Dubbo 的自动化配置 -->
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo</artifactId>
        <version>2.7.4.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-spring-boot-starter</artifactId>
        <version>2.7.4.1</version>
    </dependency>
    
    <!-- 使用 Zookeeper 作为注册中心 -->
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-framework</artifactId>
        <version>2.13.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-recipes</artifactId>
        <version>2.13.0</version>
    </dependency>
    
    1. application.yml中添加dubbo配置
    # dubbo 配置项,对应 DubboConfigurationProperties 配置类
    dubbo:
      # Dubbo 应用配置
      application:
        name: user-service-provider # 应用名
      # Dubbo 注册中心配
      registry:
        address: zookeeper://127.0.0.1:2181 # 注册中心地址。个鞥多注册中心,可见 http://dubbo.apache.org/zh-cn/docs/user/references/registry/introduction.html 文档。
      # Dubbo 服务提供者协议配置
      protocol:
        port: -1 # 协议端口。使用 -1 表示随机端口。
        name: dubbo # 使用 `dubbo://` 协议。更多协议,可见 http://dubbo.apache.org/zh-cn/docs/user/references/protocol/introduction.html 文档
      # Dubbo 服务提供者配置
      provider:
        timeout: 1000 # 【重要】远程服务调用超时时间,单位:毫秒。默认为 1000 毫秒,胖友可以根据自己业务修改
        filter: -exception # 去掉 ExceptionFilter
        UserRpcService:
          version: 1.0.0
        # validation: true 开启将验证所有Service的参数
    
    
    1. UserRpcServiceImpl

    在nb.yucai.dubbo.nacosdemo.service包下创建UserRpcService的实现类

    @Service
    public class UserRpcServiceImpl implements UserRpcService {
    
        @Override
        public UserDTO get(Integer id) {
            return new UserDTO().setId(id)
                    .setName("没有昵称:" + id)
                    .setGender(id % 2 + 1); // 1 - 男;2 - 女
        }
    
        @Override
        public Integer add(UserDTO dto) {
            if("yucai".equals(dto.getName())){
                throw new ServiceException(ServiceExceptionEnum.USER_EXISTS);
            }
            return Math.toIntExact(System.currentTimeMillis() / 1000);
        }
    }
    
    
    1. 新建Dubbo.xml的配置文件:srcmain esourcesdubbo.xml

    <dubbo:service/>可以注册为Dubbo服务的提供者

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
           xmlns="http://www.springframework.org/schema/beans"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://dubbo.apache.org/schema/dubbo
           http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
    
        <!-- 服务提供者暴露服务配置 -->
        <dubbo:service ref="userRpcServiceImpl" interface="nb.yucai.dubbo.nacosdemo.UserRpcService"
            version="${dubbo.provider.UserRpcService.version}" validation="true" />
    
    </beans>
    
    1. ProviderApplication

    ProviderApplication类启动项目,提供Dubbo服务

    @SpringBootApplication
    @ImportResource("classpath:dubbo.xml") //读取Dubbo配置文件
    public class ProviderApplication {
    
        public static void main(String[] args) {
            // 启动 Spring Boot 应用
            SpringApplication.run(ProviderApplication.class, args);
        }
    
    }
    

    此时链接Zookeeper,输入命令ls /dubbo可以看到服务UserRpcService即为成功

    2.1.3 Consumer

    1. pom.xml引入依赖
    <!-- 引入定义的 Dubbo API 接口 -->
    <dependency>
        <groupId>nb.yucai</groupId>
        <artifactId>user-rpc-service-api</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    
    <!-- 引入 Spring Boot 依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    
    <!-- 实现对 Dubbo 的自动化配置 -->
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo</artifactId>
        <version>2.7.4.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-spring-boot-starter</artifactId>
        <version>2.7.4.1</version>
    </dependency>
    
    <!-- 使用 Zookeeper 作为注册中心 -->
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-framework</artifactId>
        <version>2.13.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-recipes</artifactId>
        <version>2.13.0</version>
    </dependency>
    
    1. 配置文件
      resource下创建application.yml文件,添加Dubbo相关的配置,如下所示
    # dubbo 配置项,对应 DubboConfigurationProperties 配置类
    dubbo:
      # Dubbo 应用配置
      application:
        name: user-service-consumer # 应用名
      # Dubbo 注册中心配置
      registry:
        address: zookeeper://127.0.0.1:2181 # 注册中心地址。个鞥多注册中心,可见 http://dubbo.apache.org/zh-cn/docs/user/references/registry/introduction.html 文档。
      # Dubbo 消费者配置
      consumer:
        timeout: 1000 # 【重要】远程服务调用超时时间,单位:毫秒。默认为 1000 毫秒,胖友可以根据自己业务修改
        UserRpcService:
          version: 1.0.0
    
    1. 配置XML文件,添加Dubbo的Service服务引用者
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
           xmlns="http://www.springframework.org/schema/beans"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://dubbo.apache.org/schema/dubbo
           http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
    
        <!-- 服务提供者暴露服务配置 -->
        <dubbo:reference interface="nb.yucai.dubbo.nacosdemo.UserRpcService" id="userService"
                         version="${dubbo.consumer.UserRpcService.version}" validation="true"/>
    </beans>
    
    1. ConsumerApplication
      创建 ConsumerApplication 类,用于启动该项目,调用 Dubbo 服务。
    • 在类上,添加 @ImportResource 注解,引入 dubbo.xml 配置文件。
    • 在 UserRpcServiceTest 中,我们使用 @Resource 注解,引用通过 <dubbo:reference /> 配置的引用的 UserRpcService 服务对应的 UserRpcService Bean 。
    @SpringBootApplication
    @ImportResource("classpath:dubbo.xml")
    public class ConsumerApplication {
    
        public static void main(String[] args) {
            // 启动 Spring Boot 应用
            ConfigurableApplicationContext context = SpringApplication.run(ConsumerApplication.class, args);
        }
    
        @Component
        public class UserRpcServiceTest implements CommandLineRunner {
    
            private final Logger logger = LoggerFactory.getLogger(getClass());
    
            @Resource
            private UserRpcService userRpcService;
    
            @Override
            public void run(String... args) throws Exception {
                UserDTO user = userRpcService.get(1);
                logger.info("[run][发起一次 Dubbo RPC 请求,获得用户为({})]", user);
            }
    
        }
    }|
    

    注解方式

    工程结构如下

    dubbo-api-demo
        ├─user-apirpc-service-api
        ├─user-apirpc-service-consumer
        └─user-apirpc-service-provider
    

    Api

    基本与XML方式实现一致,可参考上文

    Provider

    1. 引入依赖

    基本与XML方式实现一致,可参考上文

    1. 应用配置文件
      application.yml中添加如下代码:
    # dubbo 配置项,对应 DubboConfigurationProperties 配置类
    dubbo:
      # Dubbo 应用配置
      application:
        name: user-service-provider # 应用名
      # Dubbo 注册中心配
      registry:
        address: zookeeper://127.0.0.1:2181 # 注册中心地址。个鞥多注册中心,可见 http://dubbo.apache.org/zh-cn/docs/user/references/registry/introduction.html 文档。
      # Dubbo 服务提供者协议配置
      protocol:
        port: -1 # 协议端口。使用 -1 表示随机端口。
        name: dubbo # 使用 `dubbo://` 协议。更多协议,可见 http://dubbo.apache.org/zh-cn/docs/user/references/protocol/introduction.html 文档
      # Dubbo 服务提供者配置
      provider:
        timeout: 1000 # 【重要】远程服务调用超时时间,单位:毫秒。默认为 1000 毫秒,胖友可以根据自己业务修改
        filter: -exception # 去掉 ExceptionFilter
        UserRpcService:
          version: 1.0.0
      scan:
        base-packages: nb.yucai.dubbo.apidemo.service
    

    多的是dubbo:scan:base-packages配置, Dubbo将根据此配置查找Dubbo中定义的@Service修饰的类,并将其暴露为Dubbo服务的提供者。因此,无需配置Dubbo的XML文件进行配置

    1. UserRpcServiceImpl
      创建Dubbo的Service实现类:nb.yucai.dubbo.apidemo.service.UserRpcServiceImpl
    import org.apache.dubbo.config.annotation.Service;
    
    @Service(version = "${dubbo.provider.UserRpcService.version}")
    public class UserRpcServiceImpl implements UserRpcService {
    
        @Override
        public UserDTO get(Integer id) {
            return new UserDTO().setId(id)
                    .setName("没有昵称:" + id)
                    .setGender(id % 2 + 1); // 1 - 男;2 - 女
        }
    }
    
    1. ProviderApplication

    正常建立即可,无需添加@ImportResource注解,引入dubbo.xml即可

    Consumer

    1. 引入依赖

    基本与XML方式实现一致,可参考上文

    1. 应用配置文件

    application.yml中添加

    # dubbo 配置项,对应 DubboConfigurationProperties 配置类
    dubbo:
      # Dubbo 应用配置
      application:
        name: user-service-consumer # 应用名
      # Dubbo 注册中心配置
      registry:
        address: zookeeper://127.0.0.1:2181 # 注册中心地址。个鞥多注册中心,可见 http://dubbo.apache.org/zh-cn/docs/user/references/registry/introduction.html 文档。
      # Dubbo 消费者配置
      consumer:
        timeout: 1000 # 【重要】远程服务调用超时时间,单位:毫秒。默认为 1000 毫秒,胖友可以根据自己业务修改
        UserRpcService:
          version: 1.0.0
    
    1. ConsumerApplication

    创建ConsumerApplication类

    @SpringBootApplication
    @Slf4j
    public class ConsumerApplication {
        public static void main(String[] args) {
            SpringApplication.run(ConsumerApplication.class);
        }
    
        @Component
        public class UserRpcServiceTest implements CommandLineRunner {
    
    
            @Reference(version = "${dubbo.consumer.UserRpcService.version}")
            private UserRpcService userRpcService;
    
            public void run(String... args) throws Exception {
                UserDTO user = userRpcService.get(1);
                log.info("[run][发起一次 Dubbo RPC 请求,获得用户为({})", user);
            }
    
        }
    }
    
    • 在类上,无需添加 @ImportResource 注解,引入 dubbo.xml 配置文件。
    • 在 UserRpcServiceTest 中,我们使用 Dubbo 定义的 @Reference注解,“直接”引用的 UserRpcService 服务对应的 UserRpcService Bean 。并且,在该注解里,我们可以添加该 Service 服务的配置。当然,每个属性和 <dubbo:reference /> 标签是基本一致的。

    3. 整合开源组件

    整合Nacos

    Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。

    本小节进行 Dubbo 和 Nacos 的整合,使用 Nacos 作为 Dubbo 的注册中心。
    Dubbo 提供了 dubbo-registry-nacos 子项目,已经对 Nacos 进行适配,所以我们只要引入它,基本就完成了 Dubbo 和 Nacos 的整合,贼方便。

    1. Nacos官网下载,运行即可。

    2. API

    以上文注解式配置的方法为例,仍采用上述Service,无需改动

    1. Provider
      引入依赖
    <!-- 使用 Zookeeper 作为注册中心 -->
    <!--<dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-framework</artifactId>
        <version>2.13.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-recipes</artifactId>
        <version>2.13.0</version>
    </dependency>-->
    <!-- 使用 Nacos 作为注册中心 -->
    <dependency>
        <groupId>com.alibaba.nacos</groupId>
        <artifactId>nacos-client</artifactId>
        <version>1.2.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-registry-nacos</artifactId>
        <version>2.7.4.1</version>
    </dependency>
    

    application.yml中配置注册中心为Nacos:

    # dubbo 配置项,对应 DubboConfigurationProperties 配置类
    dubbo:
      # Dubbo 应用配置
      application:
        name: user-service-provider # 应用名
      # Dubbo 注册中心配
      registry:
        address: nacos://99.11.6.32:8848 # 注册中心地址。个鞥多注册中心,可见 http://dubbo.apache.org/zh-cn/docs/user/references/registry/introduction.html 文档。
      # Dubbo 服务提供者协议配置
      protocol:
        port: -1 # 协议端口。使用 -1 表示随机端口。
        name: dubbo # 使用 `dubbo://` 协议。更多协议,可见 http://dubbo.apache.org/zh-cn/docs/user/references/protocol/introduction.html 文档
      # Dubbo 服务提供者配置
      provider:
        timeout: 1000 # 【重要】远程服务调用超时时间,单位:毫秒。默认为 1000 毫秒,胖友可以根据自己业务修改
        filter: -exception # 去掉 ExceptionFilter
        UserRpcService:
          version: 1.0.0
        # validation: true 开启将验证所有Service的参数
      scan:
        base-packages: nb.yucai.dubbo.nacosdemo.service
    
    nacos:
      config:
        password: nacos
        username: nacos
    
    1. Consumer

    整合过程与上述Provider完全一致。

    1. 验证

    登录Nacos控制台即可看见。

    整合Sentinel

    Sentinel 是阿里中间件团队开源的,面向分布式服务架构的轻量级流量控制产品,主要以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度来帮助用户保护服务的稳定性。

    次小节进行 Dubbo 和 Sentinel 的整合,使用 Sentinel 进行 Dubbo 的流量保护。Sentinel已经对 Dubbo 进行适配,所以我们只要引入它,基本就完成了 Dubbo 和 Sentinel 的整合,贼方便。

    1. Api

    与注解配置的Api一致,无需改动

    1. Provider

    引入依赖

    <!-- Sentinel 核心库 -->
    <dependency>
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-core</artifactId>
        <version>1.7.1</version>
    </dependency>
    <!-- Sentinel 接入控制台 -->
    <dependency>
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-transport-simple-http</artifactId>
        <version>1.7.1</version>
    </dependency>
    <!-- Sentinel 对 Dubbo 的支持 -->
    <dependency>
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-apache-dubbo-adapter</artifactId>
        <version>1.7.1</version>
    </dependency>
    

    新建sentinel.properties

    csp.sentinel.dashboard.server=127.0.0.1:7070
    

    创建UserController类,增加调用UserRpcService服务的HttpAPI接口

    @RestController
    @RequestMapping("/user")
    public class UserController {
        @Reference(version = "${dubbo.consumer.UserRpcService.version}")
        private UserRpcService userRpcService;
    
        @GetMapping("/get")
        public UserDTO get(@RequestParam("id") Integer id) {
            return userRpcService.get(id);
        }
    }
    
    1. Consumer
    • 使用 ProviderApplication 启动服务提供者。使用 ConsumerApplication 启动服务消费者。
    • 访问服务消费者的 http://127.0.0.1:8080/user/get?id=1 接口,保证相关资源的初始化。

    下面,我们来演示使用 Sentinel 对服务消费者的流量控制。Sentinel 对服务提供者的流量控制是一样的,胖友可以自己去尝试。

    • 使用浏览器,访问下 http://127.0.0.1:7070/ 地址,进入 Sentinel 控制台。
      然后,点击 Sentinel 控制台的「簇点链路」菜单,可以看到看到 Dubbo 服务消费者产生的 nb.yucai.dubbo.apidemo.UserRpcService:get(java.lang.Integer) 资源。「新增流控规则」。填写流控规则,如下图所示:
    • 这里,我们创建的是比较简单的规则,仅允许该资源被每秒调用一次。
    • 使用浏览器,快速访问 http://127.0.0.1:8080/user/get?id=1 接口两次,会调用 UserService#get(Integer id) 方法两次,会有一次被 Sentinel 流量控制而拒绝,返回结果如下图所示:

    因为默认的错误提示不是很友好,所以胖友可以自定义 SpringMVC 全局错误处理器,对 Sentinel 的异常进行处理。

    4. 下篇预告

    1. 添加参数验证
    2. 自定义实现拓展点
  • 相关阅读:
    AX ERROR: Could not find my mock parent, most likely I am stale 不及格的程序员
    利用Segue在视图控制器间传值的问题 不及格的程序员
    Creating a Singleton Instance 不及格的程序员
    iPad 通知 UIKeyboardWillShowNotification 不会在keyBoard处在Undock状态下接到通知 不及格的程序员
    Why RootViewController's view is rotated Automatically by System when the app first loaded? 不及格的程序员
    如何弹出UIDatePicker最好 不及格的程序员
    jQuery开始做恶了 不及格的程序员
    what is the SEL,id and IMP,Class ,Method? 不及格的程序员
    Objectivec 字符串比较的陷井 不及格的程序员
    Unable to create any keyboard shortcuts after the iOS 6.1.3 update on iPad. 不及格的程序员
  • 原文地址:https://www.cnblogs.com/pipicai96/p/13687528.html
Copyright © 2020-2023  润新知