Dubbo、Zookeeper、SpringBoot实例

版权声明:谁不是在与生活苦战。狼性的年级,就不要做个俗人 https://blog.csdn.net/Axela30W/article/details/85233671

一、背景:

摘自Dubbo官网:http://dubbo.apache.org
在这里插入图片描述

  • 当流量非常低时,只有一个应用程序,所有特性一起部署,以减少部署节点和成本。此时,数据访问框架(ORM)是简化CRUD工作负载的关键。
  • 当流量增加时,添加单片应用程序实例并不能很好地加速访问,提高访问效率的方法之一是将单片应用程序分割成离散应用程序。此时,用于加速前端页面开发的Web框架(MVC)是关键。
  • 随着垂直应用的不断增多,应用之间的交互不可避免,一些核心业务被提取出来,作为独立的服务,逐渐形成一个稳定的服务中心,这样前端应用可以更快地响应多变的市场需求。此时,用于业务重用和集成的分布式服务框架(RPC)是关键。
  • 当服务数量不断增加时,容量评估变得困难,而且规模较小的服务常常造成资源的浪费。为了解决这些问题,需要增加调度中心,根据业务量管理集群容量,提高集群的利用率。此时,用于提高机器利用率的资源调度和治理中心(SOA)是关键。
    Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。
    Dubbo的主要功能:
  • 透明化的远程方法调用,就像调用本地方法一样调用远程方法。不同服务之间方法的相互调用(说的更直白一点就是借口调用),一个服务可能是服务提供者也可能服务消费者
  • 负载均衡及容错机制,负载均衡策略默认是随机,可配置选择。
  • 服务自动注册与发现,不再需要写死服务提供方地址,注册中心基于接口名查询服务提供者的IP地址,并且能够平滑添加或删除服务提供者。常用Zookeeper做注册中心。

二:核心角色

Dubbo官网的Quick start模块有入门实例,不过是基于xml配置方式的。这里介绍基于SpringBoot注解方式。

核心角色组成:

在这里插入图片描述
有微服务基础的应该一看就懂了这张图。这里的各个角色类比于SpringCloud的Eureka注册中心,路由,监控等组件。


三、代码

整个项目模块分为3部分:

  1. dubbo-api: the common service api:通用api
  2. dubbo-provider: the provider codes:服务提供者
  3. dubbo-consumer: the consumer codes:服务消费者
    在这里插入图片描述
    父pom.xml主要依赖
<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.4.RELEASE</version>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <curator-framework.version>4.0.1</curator-framework.version>
        <zookeeper.version>3.4.13</zookeeper.version>
        <dubbo.starter.version>0.2.0</dubbo.starter.version>
    </properties>

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

        <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>${dubbo.starter.version}</version>
        </dependency>

        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>${curator-framework.version}</version>
        </dependency>

        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>${zookeeper.version}</version>
        </dependency>

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

这里加入了Zookeeper依赖,启动的时候会发现它以默认参数启动了注册中心服务,就不需要再本机手动启动Zookeeper服务了。

1、dubbo-api

pom文件继承父pom(另两个模块同理):

<?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>com.mistra</groupId>
    <artifactId>dubbo.api</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>dubbo-api</name>
    <description>Dubbo api for Spring Boot</description>
    
    <parent>
        <groupId>com.mistra</groupId>
        <artifactId>dubbo</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

</project>

次公共模块定义好一个Service就好了

public interface MistraService {

    /**
     *
     * @param name
     * @return
     */
    String welcome(String name);
}

2、dubbo-provider

resources文件夹下定义配置文件application.properties

spring.application.name = dubbo-provider
server.port = 9090
dubbo.application.name = dubbo-provider
mistra.service.version = 1.0.0
dubbo.protocol.name = dubbo
dubbo.protocol.port = 20880
dubbo.registry.address = zookeeper://localhost:2181
dubbo.provider.timeout = 1000

定义服务实现类

@Service(version = "${mistra.service.version}")
public class MistraServiceImpl implements MistraService {

    @Override
    public String welcome(String name) {
        return "Hello" + name;
    }
}

注意,此处的@Service注解来源于dubbo包,而非spring包,version标注了此服务的版本信息
SpringBoot的启动类除了原来的@SpringBootApplication,还需要加上@EnableDubbo

@SpringBootApplication
@EnableDubbo
public class DubboConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(DubboConsumerApplication.class, args);
    }
}

3、dubbo-consumer

resources文件夹下定义配置文件application.properties

spring.application.name = dubbo-consumer
server.port = 9091
dubbo.application.name = dubbo-consumer
mistra.service.version = 1.0.0
dubbo.protocol.name = dubbo
dubbo.protocol.port = 20880
dubbo.registry.address = zookeeper://localhost:2181
dubbo.consumer.timeout = 5000

定义一个controller

@RestController
public class ConsumerController {

    @Reference(version = "${mistra.service.version}")
    private MistraService mistraService;

    @RequestMapping("/sayHello/{name}")
    public String sayHello(@PathVariable("name") String name) {
        return mistraService.welcome(name);
    }
}

@Reference注解是dubbo包下定义的,注入service时要依赖配置文件配置的版本号
SpringBoot启动类写法同上。


四、测试

正常启动顺序是先启动服务提供者模块,再启动服务消费者模块。浏览器访问正常。
如果先启动了服务消费者模块,后启动服务提供者模块,调用方法的时候会报空指针异常。应该启动消费者服务订阅服务的时候没找到对应的服务。
代码地址:GitHub


在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Axela30W/article/details/85233671