• springcloudalibaba架构(30):Dubbo的使用入门


    前言

    Apache Dubbo时一款高性能的Java RPC框架。

    第一节 RPC 通信

    服务调用

    在微服务架构中,通常存在多个服务之间的远程调用需求。目前主流的远程调用技术有基于HTTP的RESTful接口以及基于TCP的RPC协议。

    • REST(Representational State Transfer)
      这是一种http调用的格式,更标准、更通用,无论哪种语言都支持http协议。
    • RPC(Remote Promote Call)
      一种进程间通信方式。允许像调用本地服务一样调用远程服务。RPC框架的主要目标就是让远程服务调用更简单、透明。RPC框架负责屏蔽底层的传输方式、序列化方式和通信细节。开发人员在调用的时候只需要了解谁在什么位置提供了什么样的远程服务接口即可,并不需要关系底层通信细节和调用过程。

    Dubbo介绍

    Dubbo是阿里巴巴开源的基于Java的高性能RPC分布式服务框架,致力于提供搞性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。
    Spring-Cloud-alibaba-dubbo是基于SpringCloudAlibaba技术栈对 dubbo技术的一种封装,目的在于实现基于RPC的服务调用。

    第二节 环境准备

    • 需要先启动nacos
      nacos版本1.4.3

    • 版本说明
      版本信息:
      springboot版本2.3.2.RELEASE
      springcloud版本Hoxton.SR8
      springcloud-alibaba版本2.2.5.RELEASE

    本章代码已分享至Gitee:https://gitee.com/lengcz/springcloudalibaba-dubbo.git

    第三节 如何使用dubbo进行远程调用

    1. 图解调用关系

    下面的示例是service-2微服务调用service-1微服务
    在这里插入图片描述

    2. 工程结构

    springcloudalibaba-dubbo  整个父工程
    |-service-1               服务1
    |-|- service-1-api        服务1  api
    |-|- service-1-server     服务1 实现,port:10020
    |-service-2               服务2             
    |-|- service-2-api        服务2  api
    |-|- service-2-server     服务2 实现,port:10030
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3. 创建maven项目

    1. 创建项目,项目名称为springcloudalibaba-dubbo
      在这里插入图片描述

    在这里插入图片描述

    1. pom文件内容
    <packaging>pompackaging>
    
    • 1
    1. 定义包管理(下面是pom文件的全部内容)
    
    <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.0modelVersion>
    
        <groupId>com.it2groupId>
        <artifactId>springcloudalibaba-dubboartifactId>
        <version>1.0-SNAPSHOTversion>
        <packaging>pompackaging>
    
        
        <parent>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-parentartifactId>
            <version>2.3.2.RELEASEversion>
        parent>
    
        
        <properties>
            <java.version>1.8java.version>
            <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
            <spring-cloud.version>Hoxton.SR8spring-cloud.version>
            <spring-cloud-alibaba.version>2.2.5.RELEASEspring-cloud-alibaba.version>
        properties>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloudgroupId>
                    <artifactId>spring-cloud-dependenciesartifactId>
                    <version>${spring-cloud.version}version>
                    <type>pomtype>
                    <scope>importscope>
                dependency>
                <dependency>
                    <groupId>com.alibaba.cloudgroupId>
                    <artifactId>spring-cloud-alibaba-dependenciesartifactId>
                    <version>${spring-cloud-alibaba.version}version>
                    <type>pomtype>
                    <scope>importscope>
                dependency>
    
            dependencies>
        dependencyManagement>
    
        <build>
            
            <plugins>
                <plugin>
                    <groupId>org.springframework.bootgroupId>
                    <artifactId>spring-boot-maven-pluginartifactId>
                plugin>
            plugins>
        build>
    project>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    1. 删除src文件夹,因为项目的所有代码都在模块里,src没有作用,所以可以删除。
      在这里插入图片描述

    4. service-1模块

    4.1 创建service-1模块

    1. 在根项目下,新建service-1模块
      在这里插入图片描述
      在这里插入图片描述
    2. 删除src文件夹,因为项目的所有代码都在模块里,src没有作用,所以可以删除。

    在这里插入图片描述

    4.2. 创建service-1-api模块

    1. 创建模块
      在这里插入图片描述
      service-1-api的parent是service-1,service-1-api是service-1的子模块
      在这里插入图片描述

    2. 删除test和resources目录,因为xxx-api模块只是用于定义接口的,没有实现,不需要配置文件,也不需要测试用例。
      在这里插入图片描述

    4.3 创建service-1-server模块

    1. 创建模块
      在这里插入图片描述
      在这里插入图片描述

    5. service-2 模块

    按照service-1的步骤创建service-2即可,此处步骤省略。

    6. 实现service-1

    6.1 service-1-api定义接口

    在service-1-api里定义接口

    package com.it2.service1.api;
    
    
    public interface ConsumerService {
    
        public String service();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述

    6.2 service-1-server实现

    1. 引入需要使用到的依赖
    <dependencies>
    		<dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-webartifactId>
            dependency>
            
            <dependency>
                <groupId>com.it2groupId>
                <artifactId>service-1-apiartifactId>
                <version>1.0-SNAPSHOTversion>
            dependency>
    
            
            <dependency>
                <groupId>com.alibaba.cloudgroupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
            dependency>
            
            <dependency>
                <groupId>com.alibaba.cloudgroupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-configartifactId>
            dependency>
            
            <dependency>
                <groupId>com.alibaba.cloudgroupId>
                <artifactId>spring-cloud-starter-dubboartifactId>
            dependency>
        dependencies>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    1. 实现service-1-api的接口
    package com.it2.service1.service;
    
    import com.it2.service1.api.ConsumerService;
    
    //注解标记此类表示此方法暴露为dubbo接口
    //@org.apache.dubbo.config.annotation.Service  //(已不推荐)不是spring的Service,是dubbo的service,推荐写类全名
    @org.apache.dubbo.config.annotation.DubboService
    public class ConsumerServiceImpl implements ConsumerService {
    
        //dubbo接口实现
        public String service() {
            System.out.println("我被调用了--");
            return "consumer invoke ";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    1. 编写启动类
    package com.it2.service1;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    
    @SpringBootApplication
    @EnableDiscoveryClient //开启nacos服务发现
    @EnableDubbo //开启dubbo
    public class Service1Bootstrap {
    
        public static void main(String[] args) {
            SpringApplication.run(Service1Bootstrap.class,args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    7. 实现service-2

    7.1 service-2-server模块

    1. 引入依赖
    		<dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-webartifactId>
            dependency>
            <dependency>
                <groupId>com.it2groupId>
                <artifactId>service-1-apiartifactId>
                <version>1.0-SNAPSHOTversion>
            dependency>
            
            <dependency>
                <groupId>com.alibaba.cloudgroupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
            dependency>
            
            <dependency>
                <groupId>com.alibaba.cloudgroupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-configartifactId>
            dependency>
            
            <dependency>
                <groupId>com.alibaba.cloudgroupId>
                <artifactId>spring-cloud-starter-dubboartifactId>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    1. 配置bootstrap.yaml
    server:
      port: ${port:10030}  #启动端口
    spring:
      application:
        name: service2
      cloud:
        nacos:
          discovery:  #注册发现
            server-addr: 127.0.0.1:8848
            namespace: public
            cluster-name: DEFAULT #集群
          config:     #配置中心
            server-addr: 127.0.0.1:8848
            file-extension: yaml
            namespace: public
            group: NACOS_MICROSERVICE_GROUP #业务组
      main:
        allow-bean-definition-overriding: true # spring boot 2.1 需要设定(防止bean重复覆盖问题)
    
    #dubbo相关
    dubbo:
      scan:
        base-packages: com.it2.service2  #服务扫描基准包(扫描被dubbo注解的类)
      protocol:
        name: dubbo  #协议
        port: ${dubbo_port:20891}  #协议端口 -1 表示不限制
      registry:
        address: spring-cloud://localhost #注册中心,表示使用配置文件中的注册中心
      application:
        qos-enable: false #dubbo运维服务是否开启
      consumer:
        check: false #启动时就检查依赖的服务
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    1. 编写controller
    package com.it2.service2.controller;
    
    import com.it2.service1.api.ConsumerService;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class HelloController {
    
        //注入service
    //    @org.apache.dubbo.config.annotation.Reference  //(已不推荐)生成代理对象
        @org.apache.dubbo.config.annotation.DubboReference //生成代理对象
        private ConsumerService consumerService;
    
        @GetMapping("/hello")
        public String hello() {
            System.out.println("==========hello============");
            return "hello,"+consumerService.service();//dubbo远程调用
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    1. 编写启动类
    package com.it2.service2;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    
    @SpringBootApplication
    @EnableDiscoveryClient //开启nacos服务发现
    @EnableDubbo //开启dubbo
    public class Service2Bootstrap {
    
        public static void main(String[] args) {
            SpringApplication.run(Service2Bootstrap.class,args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    8. 启动服务器测试

    先启动service-1-server,再启动service-2-server,按照依赖顺序,先启动被依赖的服务。启动之后,清空日志。

    在这里插入图片描述

    发起调用请求http://localhost:10030/hello
    在这里插入图片描述
    在这里插入图片描述
    nacos后台看到的dubbo注册到nacos的元数据(dubbo相关内容)
    在这里插入图片描述
    在这里插入图片描述

    第四节 注意的问题

    1. 对象序列化Serializable

    上面的示例service1提供的返回值是String,如果我们改成对象,如下。

    //注解标记此类表示此方法暴露为dubbo接口
    //@org.apache.dubbo.config.annotation.Service  //(已不推荐)不是spring的Service,是dubbo的service,推荐写类全名
    @org.apache.dubbo.config.annotation.DubboService
    public class ConsumerServiceImpl implements ConsumerService {
    
        //dubbo接口实现
        public User service() {
            System.out.println("我被调用了--");
            return new User();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    那么我们的实体类就需要实现序列化接口Serializable

    //网络传输或者存储需要实现序列化接口
    public class User implements Serializable {
    }
    
    • 1
    • 2
    • 3

    2. 调用失败或者无法访问

    注意检查是否引入了spring-boot-starter-web

            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-webartifactId>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
  • 相关阅读:
    使用.NET源生成器(SG)实现一个自动注入的生成器
    角速度变化时四元数和旋转矩阵微分方程的证明
    如何找到能商用的背景纯音乐
    Mips架构安装mysql问题
    【信创】麒麟v10(arm)-mysql8-mongo-redis-oceanbase
    记一次 .NET 某医疗住院系统 崩溃分析
    2022高教社杯数学建模国赛C题思路代码实现
    双冠王!华为云领跑政务市场
    C语言04、操作符
    直播预约丨《实时湖仓实践五讲》第三讲:实时湖仓在袋鼠云的落地实践之路
  • 原文地址:https://blog.csdn.net/u011628753/article/details/126446401