• dubbo漫谈(一)


    分布式入门教程记录。由于dubbo依赖zookeeper,前置条件需掌握zookeeper相关知识,可跳转至zookeeper指南提前进行了解。

    一. 什么是dubbo

    官网解释如下:Apache Dubbo 是一款微服务框架,为大规模微服务实践提供高性能 RPC 通信、流量治理、可观测性等解决方案,
    涵盖 Java、Golang 等多种语言 SDK 实现。

    主要为了实现生产环境中单体服务无法满足日趋增长的访问量所做的横向扩展,使用以下粗略的草图来表示使用dubbo前和使用dubbo后的区别:

    在这里插入图片描述
    (简单表示单点服务)
    在这里插入图片描述
    (引入dubbo/zookeeper后)

    我们可以横向扩展多个服务,有多种场景可以适用,例如在一个系统中我们将用户中心作为单独一个服务A,订单系统作为单独一个服务B,并且服务A和服务B都可以作为多个副本部署在不同的服务器并注册到dubbo上。

    当用户访问的时候就会经过dubbo来分配请求,其中在dubbo这一层还有zookeeper的参与。本文重点突出dubbo的使用,故假设读者已经具备zookeeper的使用能力,若有疑问可以转至笔者的另一篇文章进行了解:zookeeper指南

    二. dubbo实战

    talk is cheap,show me the code,我们直接上手玩一把。

    网上也有较多的例子,这里以保姆教学的心态将每个细节都呈现给读者。

    我们首先需要建立一个多模块聚合工程,包含以下三个模块:

    1. api:接口定义,实体类定义
    2. consumer:消费者
    3. provider:生产者

    pom依赖

    其中,consumer和provider都依赖api模块,这里将关键的pom文件展示出来:

    root父工程的pom依赖:

    <modelVersion>4.0.0modelVersion>
    <packaging>pompackaging>
    <name>mydubboname>
    <groupId>org.vainycosgroupId>
    <artifactId>mydubboartifactId>
    <version>1.0version>
    
    <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.7.2version>
        <relativePath/> 
    parent>
    
    <modules>
        <module>apimodule>
        <module>consumermodule>
        <module>providermodule>
    modules>
    
    <properties>
        <java.version>1.8java.version>
        <maven.compiler.source>8maven.compiler.source>
        <maven.compiler.target>8maven.compiler.target>
    properties>
    
    • 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

    api模块:

    <parent>
        <groupId>org.vainycosgroupId>
        <artifactId>mydubboartifactId>
        <version>1.0version>
    parent>
    
    <groupId>com.vainycosgroupId>
    <artifactId>apiartifactId>
    <version>0.0.1-SNAPSHOTversion>
    <name>apiname>
    <description>apidescription>
    
    <dependencies>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <optional>trueoptional>
        dependency>
    dependencies>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    provider模块:

    <parent>
        <groupId>org.vainycosgroupId>
        <artifactId>mydubboartifactId>
        <version>1.0version>
    parent>
    
    <dependencies>
        <dependency>
            <groupId>com.vainycosgroupId>
            <artifactId>apiartifactId>
            <version>0.0.1-SNAPSHOTversion>
        dependency>
    
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starterartifactId>
        dependency>
    
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>
    
        
        <dependency>
            <groupId>org.apache.dubbogroupId>
            <artifactId>dubbo-spring-boot-starterartifactId>
            <version>2.7.6version>
        dependency>
    
        
        <dependency>
            <groupId>org.apache.dubbogroupId>
            <artifactId>dubbo-dependencies-zookeeperartifactId>
            <version>2.7.6version>
            <type>pomtype>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4jgroupId>
                    <artifactId>slf4j-log4j12artifactId>
                exclusion>
            exclusions>
        dependency>
    
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <optional>trueoptional>
        dependency>
    dependencies>
    
    <build>
        
        <finalName>dubbo-providerfinalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
                
                <configuration>
                    <mainClass>com.vainycos.provider.ProviderApplicationmainClass>
                configuration>
                <executions>
                    <execution>
                        <goals>
                            
                            <goal>repackagegoal>
                        goals>
                    execution>
                executions>
            plugin>
            <plugin>
                <groupId>org.apache.maven.pluginsgroupId>
                <artifactId>maven-surefire-pluginartifactId>
                <version>2.21.0version>
                <configuration>
                    
                    <skipTests>trueskipTests>
                configuration>
            plugin>
        plugins>
    build>
    
    • 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
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83

    consumer模块:

    <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.7.2version>
        <relativePath/> 
    parent>
    
    <dependencies>
        <dependency>
            <groupId>com.vainycosgroupId>
            <artifactId>apiartifactId>
            <version>0.0.1-SNAPSHOTversion>
        dependency>
    
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
    
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>
    
        
        <dependency>
            <groupId>org.apache.dubbogroupId>
            <artifactId>dubbo-spring-boot-starterartifactId>
            <version>2.7.6version>
        dependency>
    
        
        <dependency>
            <groupId>org.apache.dubbogroupId>
            <artifactId>dubbo-dependencies-zookeeperartifactId>
            <version>2.7.6version>
            <type>pomtype>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4jgroupId>
                    <artifactId>slf4j-log4j12artifactId>
                exclusion>
            exclusions>
        dependency>
    dependencies>
    
    <build>
        
        <finalName>dubbo-consumerfinalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
                
                <configuration>
                    <mainClass>com.vainycos.consumer.ConsumerApplicationmainClass>
                configuration>
                <executions>
                    <execution>
                        <goals>
                            
                            <goal>repackagegoal>
                        goals>
                    execution>
                executions>
            plugin>
            <plugin>
                <groupId>org.apache.maven.pluginsgroupId>
                <artifactId>maven-surefire-pluginartifactId>
                <version>2.21.0version>
                <configuration>
                    
                    <skipTests>trueskipTests>
                configuration>
            plugin>
        plugins>
    build>
    
    • 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
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78

    配置文件

    1. provider
    spring:
      application:
        name: provider
    
    server:
      port: 60001
    
    dubbo:
      registry:
      	# zookeeper的注册地址
        address: zookeeper://x.x.x.x:2181
        timeout: 10000
    
      protocol:
        name: dubbo
        # 线上环境可使用-1,由dubbo分配端口
        port: 20880
      scan:
        base-packages: com.vainycos.provider.service
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    1. consumer
    spring:
      application:
        name: consumer
    
    server:
      port: 50001
    
    dubbo:
      registry:
        address: zookeeper://x.x.x.x:2181
        timeout: 10000
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    关键代码

    1. api

    定义接口

    public interface OrderService {
        List<Order> findOrdersByUserId(Integer userId);
    }
    
    • 1
    • 2
    • 3

    定义model

    @Data
    public class Order implements Serializable {
        private Long id;
        private Date createTime;
        private Integer userId;
        private List<OrderItem> orderItemList;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    @Data
    public class Order implements Serializable {
        private Long id;
        private Date createTime;
        private Integer userId;
        private List<OrderItem> orderItemList;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    1. provider

    服务实现类

    import lombok.extern.slf4j.Slf4j;
    import org.apache.dubbo.config.annotation.Service;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @author: Vainycos
     * @description
     * @date: 2022/8/4 15:29
     */
    // 需注意这里引入@Service注解是dubbo包下的
    @Slf4j
    @Service
    public class OrderServiceImpl implements OrderService {
        @Override
        public List<Order> findOrdersByUserId(Integer userId) {
            // do something
            log.info("获取订单消息...");
            Order order = new Order();
            order.setId(1L);
            order.setUserId(userId);
            List<Order> list = new ArrayList<>();
            list.add(order);
            return list;
        }
    }
    
    • 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
    1. consumer

    service:

    public interface UserService {
        List<Order> findOrdersByUserId(Integer id);
    }
    
    • 1
    • 2
    • 3
    import com.vainycos.consumer.service.UserService;
    import org.apache.dubbo.config.annotation.Reference;
    import org.springframework.stereotype.Service;
    
    import java.util.List;
    
    /**
     * @author: Vainycos
     * @description
     * @date: 2022/8/4 15:57
     */
    // Spring的Service注解
    @Service
    public class UserServiceImpl implements UserService {
    
        @Reference
        private OrderService orderService;
    
    
        @Override
        public List<Order> findOrdersByUserId(Integer id) {
            return orderService.findOrdersByUserId(id);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    controller:

    @RequestMapping("/test")
    @RestController
    public class UserController {
    
        @Autowired
        private UserService userService;
    
        @GetMapping("/getUser")
        public List<Order> getUser(Integer userId){
            List<Order> ordersByUserId = userService.findOrdersByUserId(userId);
            return ordersByUserId;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    此时,我们分别启动provider以及consumer,并访问consumer的接口:localhost:50001/test/getUser,观察provider的日志正确输出:获取订单消息…即表示成功了。

    三. dubbo-admin

    前期准备

    dubbo-admin是一个官方的可视化服务,这里我们通过Github的源代码仓库进行构建。

    1. 访问Github地址:https://github.com/apache/dubbo-admin,并clone至本地

    2. 目录结构如下

    dubbo-admin目录结构

    重点关注dubbo-admin-server以及dubbo-admin-ui模块,前者是springboot后端项目,后者是vue前端项目。

    1. 调整dubbo-admin-server配置文件中的zookeeper指向,启动端口,访问账号密码调整(可选)
    server.port=10080
    
    admin.registry.address=zookeeper://10.8.3.173:2181
    admin.config-center=zookeeper://10.8.3.173:2181
    admin.metadata-report.address=zookeeper://10.8.3.173:2181
    
    # 可选调整
    admin.root.user.name=root
    admin.root.user.password=root
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    启动

    本地调试模式启动:前后端分开启动;或者在根目录下打包后直接用根目录的jar包启动,两种启动结果是一致的。

    • 启动后端,以下两种方式

      1. org.apache.dubbo.admin.DubboAdminApplication,直接启动main主入口
      2. 在项目根目录下执行打包命令:mvn clean install ‘-Dmaven.test.skip=true’,打包完成后进入到dubbo-admin-distribution\target目录下找到dubbo-admin-0.4.0.jar并进行启动即可
    • 启动前端

      1. 首先需要准备node环境

      2. 切换到dubbo-admin-ui目录下,运行命令npm install

      3. 修改dubbo-admin-ui/vue.config.js的代理后端地址,需要与dubbo-admin-server配置文件中的启动端口保持一致

        proxy: {
            '/': {
                // 实际后端访问地址
                target: 'http://localhost:10080/',
                changeOrigin: true,
                pathRewrite: {
                    '^/': '/'
                }
            }
        }
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
      4. 执行启动命令,默认启动端口为8082

        npm run dev
        
        • 1

        在这里插入图片描述

    启动完成之后访问localhost:8082,默认账号密码是root/root。

    dubbo-admin-ui

    四. 总结

    ​ 作为dubbo的使用,仅仅作为开始,后续将会不断地丰富该项目,将以上代码在gitee上进行开源:https://gitee.com/dearvainycos/mydubbo.git。

    参考资料:

  • 相关阅读:
    net-java-php-python-网上书店管理系统设计计算机毕业设计程序
    Spring(五):Spring Boot 的配置和日志
    SMT贴片加工厂之红胶工艺基本知识
    对前端项目打包产物分析入库的好处
    牛客小白月赛61 B.柜台结账(模拟+字符串)
    Docker安装redis
    Oracle(2-3) Basic Oracle Net Server Side Configuration
    DevOps落地实践点滴和踩坑记录-(1)
    Spring介绍
    操作系统考研笔记
  • 原文地址:https://blog.csdn.net/imVainiycos/article/details/126177849