SpringBoot - 集成Dubbo

Posted MinggeQingchun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBoot - 集成Dubbo相关的知识,希望对你有一定的参考价值。

一、Dubbo

 Apache Dubbo 是一款高性能、轻量级的开源 Java RPC服务框架

Apache Dubbo |ˈdʌbəʊ| 提供了六大核心能力:

1、面向接口代理的高性能RPC调用

2、智能容错和负载均衡

3、服务自动注册和发现

4、高度可扩展能力

5、运行期流量调度

6、可视化的服务治理与运维

Dubbo官网 https://dubbo.apache.org/zh/

Dubbo主要核心部件
Remoting: 网络通信框架,实现了 sync-over-async 和 request-response 消息机制.

RPC: 一个远程过程调用的抽象,支持负载均衡、容灾和集群功能

Registry: 服务目录框架用于服务的注册和服务事件发布和订阅

Dubbo基本架构


服务提供者(Provider):暴露服务的服务提供方,服务提供者在启动时,向注册中心注册自己提供的服务

服务消费者(Consumer):调用远程服务的服务消费方,服务消费者在启动时,向注册中心订阅自己所需的服务,服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用

注册中心(Registry):注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者

监控中心(Monitor):服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心

Dubbo支持多种协议:dubbo , hessian , rmi , http, webservice , thrift , memcached , redis

dubbo 官方推荐使用 dubbo 协议;dubbo 协议默认端口 20880

使用 dubbo 协议,spring 配置文件加入:

<dubbo:protocol name="dubbo" port="20880" />

二、SpringBoot集成Dubbo

1、创建接口模块

创建普通maven模块

创建实体类对象

import java.io.Serializable;

public class Student implements Serializable 

    private static final long serialVersionUID = -6171595679925305788L;

    private Integer id;
    private String name;
    private Integer age;


    public Integer getId() 
        return id;
    

    public void setId(Integer id) 
        this.id = id;
    

    public String getName() 
        return name;
    

    public void setName(String name) 
        this.name = name;
    

    public Integer getAge() 
        return age;
    

    public void setAge(Integer age) 
        this.age = age;
    

    @Override
    public String toString() 
        return "Student" +
                "id=" + id +
                ", name='" + name + '\\'' +
                ", age=" + age +
                '';
    

创建一个接口类

import com.company.model.Student;

public interface StudentService 

    Student queryStudent(Integer id);

2、创建服务提供者模块

创建一个springboot模块,pom.xml引入dubbo,zookeeper,接口依赖

<dependencies>

        <!--加入公共项目的坐标gav-->
        <dependency>
            <groupId>com.company</groupId>
            <artifactId>springboot-dubbo-interface-api</artifactId>
            <version>1.0.0</version>
        </dependency>

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

        <!--zookeeper依赖-->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-dependencies-zookeeper</artifactId>
            <version>2.7.8</version>
            <type>pom</type>

            <!-- 报错:SLF4J: Actual binding is of type [org.slf4j.impl.Reload4jLoggerFactory]
                在产生日志信息的时候有两个桥接器,发生冲突导致error
                消除冲突的一个日志桥接器
            -->
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-log4j12</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </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>
    </dependencies>

application.yml配置文件配置dubbo的服务提供者应用名称,以及扫描包,注册中心

server:
  port: 8081

# 设置服务提供者名称 等同xml配置文件中 dubbo:application name="名称"
spring:
  application:
    name: student-service-provider

#配置扫描的包, 扫描的@DubboService
dubbo:
  scan:
    base-packages: com.company.service
  #配置dubbo协议
  protocol:
    name: dubbo
    port: 20881
  #注册中心
  registry:
    address: zookeeper://localhost:2181

实现服务接口

import com.company.model.Student;
import com.company.service.StudentService;
import org.apache.dubbo.config.annotation.DubboService;

/**
 * 使用dubbo中的注解暴露服务
 */
@DubboService(interfaceClass = StudentService.class,version = "1.0.0",timeout = 5000)
public class StudentServiceImpl implements StudentService 
    @Override
    public Student queryStudent(Integer id) 
        Student student = new Student();
        if(1001 == id)
            student.setId(1001);
            student.setName("--1001-张三");
            student.setAge(20);
         else if(1002 == id)
            student.setId(1002);
            student.setName("##1002-李四");
            student.setAge(22);
        
        return student;
    

启动类中启用Dubbo


/**
 * @EnableDubbo 启用Dubbo;复合注解
 * @EnableDubboConfig
 * @DubboComponentScan
 */
@EnableDubbo
@SpringBootApplication
public class DubboServiceProviderApplication 

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

3、创建消费者模块

创建一个springboot模块,pom.xml文件依赖

<dependencies>

        <!--加入公共项目的坐标gav-->
        <dependency>
            <groupId>com.company</groupId>
            <artifactId>springboot-18-dubbo-interface-api</artifactId>
            <version>1.0.0</version>
        </dependency>

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

        <!--zookeeper依赖-->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-dependencies-zookeeper</artifactId>
            <version>2.7.8</version>
            <type>pom</type>
            <!-- 报错:SLF4J: Actual binding is of type [org.slf4j.impl.Reload4jLoggerFactory]
                在产生日志信息的时候有两个桥接器,发生冲突导致error
                消除冲突的一个日志桥接器
            -->
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-log4j12</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </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>
    </dependencies>

application.yml配置dubbo

server:
  port: 8082

# 设置服务提供者名称 等同xml配置文件中 dubbo:application name="名称"
spring:
  application:
    name: student-consumer

#配置扫描的包, 扫描的@DubboService
dubbo:
  #注册中心
  registry:
    address: zookeeper://localhost:2181

controller中引用远程服务

import com.company.model.Student;
import com.company.service.StudentService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ConsumerController 

    /**
     * 引用远程服务, 把创建好的代理对象,注入给studentService
     * 没有使用interfaceClass,默认的就是 引用类型的 数据类型
     */
    @DubboReference(interfaceClass = StudentService.class,version = "1.0.0")
//    @DubboReference(version = "1.0")
    private StudentService studentService;

    @GetMapping("/query/stuId")
    public String queryStudent(@PathVariable("stuId") Integer stuId)
        Student student  = studentService.queryStudent(stuId);
        return "调用远程接口,获取对象:"+student;
    

启动类上启用dubbo

/**
 * @EnableDubbo 启用Dubbo;复合注解
 * @EnableDubboConfig
 * @DubboComponentScan
 */
@EnableDubbo
@SpringBootApplication
public class DubboServiceProviderApplication 

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

先启动服务提供者 service-provider;再启动消费者consumer

这里会报一个错:

SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]

原因:日志依赖 SLF4j 多次加入了;只需要依赖一次即可

因此在服务者和消费者pom.xml依赖中需要加入过滤

<!--zookeeper依赖-->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-dependencies-zookeeper</artifactId>
            <version>2.7.8</version>
            <type>pom</type>

            <!-- 报错:SLF4J: Actual binding is of type [org.slf4j.impl.Reload4jLoggerFactory]
                在产生日志信息的时候有两个桥接器,发生冲突导致error
                消除冲突的一个日志桥接器
            -->
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-log4j12</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>

启动zookeeper服务,再重新运行提供者,消费者,测试结果如下:

zookeeper介绍如下:

三、Dubbo推荐使用 Zookeeper 注册中心

Zookeeper是Apache下一个高性能的,分布式的,开放源码的分布式应用程序协调服务。简称 zk

ZooKeeper主要服务于分布式系统,可以用ZooKeeper来做:统一配置管理、统一命名服务、分布式锁、集群管理

ZooKeeper官网

Apache ZooKeeper

注:

Zookeeper 运行需要 java 环境

(一)Windows下安装ZooKeeper

1、zookeeper官网

Apache ZooKeeper

Apache ZooKeeper

 2、下载之后解压到目标路径即可

(二)zoo.cfg配置文件

1、进入conf目录下,复制 zoo_sample.cfg文件,并将其改名为 zoo.cfg

2、修改zoo.cfg 配置文件

 配置文件主要参数如下: 

#ZK中的时间配置最小但域,其他时间配置以整数倍tickTime计算
tickTime=2000
#Leader允许Follower启动时在initLimit时间内完成数据同步,单位:tickTime
initLimit=10
#Leader发送心跳包给集群中所有Follower,若Follower在syncLimit时间内没有响应,那么Leader就认为该follower已经挂掉了,单位:tickTime
syncLimit=5
#配置ZK的数据目录
dataDir=/usr/local/zookeeper/data
#用于接收客户端请求的端口号
clientPort=2181
#配置ZK的日志目录
dataLogDir=/usr/local/zookeeper/logs
#ZK集群节点配置,端口号2888用于集群节点之间数据通信,端口号3888用于集群中Leader选举
server.1=192.168.123.100:2888:3888
server.2=192.168.123.101:2888:3888

进入到 bin 目录下,点击 zkServer.cmd

或者 在 bin 目录下 输入 “cmd”命令 

看到绑定成功即可

以上是关于SpringBoot - 集成Dubbo的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot系列之集成Dubbo的方式

SpringBoot——SpringBoot集成Dubbo

SpringBoot——SpringBoot集成Dubbo

#yyds干货盘点#动力节点王鹤Springboot教程笔记SpringBoot集成Dubbo

dubbo入门和springboot集成dubbo小例子

SpringBoot06-Dubbo和Zookper集成