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.0</modelVersion>
<packaging>pom</packaging>
<name>mydubbo</name>
<groupId>org.vainycos</groupId>
<artifactId>mydubbo</artifactId>
<version>1.0</version>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.2</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<modules>
    <module>api</module>
    <module>consumer</module>
    <module>provider</module>
</modules>

<properties>
    <java.version>1.8</java.version>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
</properties>

api模块:

<parent>
    <groupId>org.vainycos</groupId>
    <artifactId>mydubbo</artifactId>
    <version>1.0</version>
</parent>

<groupId>com.vainycos</groupId>
<artifactId>api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>api</name>
<description>api</description>

<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

provider模块:

<parent>
    <groupId>org.vainycos</groupId>
    <artifactId>mydubbo</artifactId>
    <version>1.0</version>
</parent>

<dependencies>
    <dependency>
        <groupId>com.vainycos</groupId>
        <artifactId>api</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    <!-- dubbo的依赖 -->
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-spring-boot-starter</artifactId>
        <version>2.7.6</version>
    </dependency>

    <!-- zk的依赖 -->
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-dependencies-zookeeper</artifactId>
        <version>2.7.6</version>
        <type>pom</type>
        <exclusions>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

<build>
    <!-- 包名称 -->
    <finalName>dubbo-provider</finalName>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <!--添加自己的启动类路径!-->
            <configuration>
                <mainClass>com.vainycos.provider.ProviderApplication</mainClass>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <!--可以把依赖的包都打包到生成的Jar包中-->
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.21.0</version>
            <configuration>
                <!-- 跳过测试 -->
                <skipTests>true</skipTests>
            </configuration>
        </plugin>
    </plugins>
</build>

consumer模块:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.2</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<dependencies>
    <dependency>
        <groupId>com.vainycos</groupId>
        <artifactId>api</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    <!-- dubbo的依赖 -->
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-spring-boot-starter</artifactId>
        <version>2.7.6</version>
    </dependency>

    <!-- zk的依赖 -->
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-dependencies-zookeeper</artifactId>
        <version>2.7.6</version>
        <type>pom</type>
        <exclusions>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

<build>
    <!-- 包名称 -->
    <finalName>dubbo-consumer</finalName>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <!--添加自己的启动类路径!-->
            <configuration>
                <mainClass>com.vainycos.consumer.ConsumerApplication</mainClass>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <!--可以把依赖的包都打包到生成的Jar包中-->
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.21.0</version>
            <configuration>
                <!-- 跳过测试 -->
                <skipTests>true</skipTests>
            </configuration>
        </plugin>
    </plugins>
</build>

配置文件

  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. consumer
spring:
  application:
    name: consumer

server:
  port: 50001

dubbo:
  registry:
    address: zookeeper://x.x.x.x:2181
    timeout: 10000

关键代码

  1. api

定义接口

public interface OrderService {
    List<Order> findOrdersByUserId(Integer userId);
}

定义model

@Data
public class Order implements Serializable {
    private Long id;
    private Date createTime;
    private Integer userId;
    private List<OrderItem> orderItemList;
}
@Data
public class Order implements Serializable {
    private Long id;
    private Date createTime;
    private Integer userId;
    private List<OrderItem> orderItemList;
}
  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. consumer

service:

public interface UserService {
    List<Order> findOrdersByUserId(Integer id);
}
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);
    }
}

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;
    }
}

此时,我们分别启动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

启动

本地调试模式启动:前后端分开启动;或者在根目录下打包后直接用根目录的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: {
                  '^/': '/'
              }
          }
      }
      
    4. 执行启动命令,默认启动端口为8082

      npm run dev
      

      在这里插入图片描述

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

dubbo-admin-ui

四. 总结

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

参考资料:

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值