Dubbo+Zookeeper分布式demo搭建

HarryZhang 2019年08月26日 107次浏览

大概一个多月没有更新过博客了,本人在不断的沉淀、积累。也在忙着工作的事情。

本文基于springboot2来搭建,zookper单机,dubbo 2.6

国内springcloud用得相对少一点,最近dubbo+zookeeper国内比较火,毕竟阿里的,跟着大厂走!

zookeeper

Zookeeper 是 Apacahe Hadoop 的子项目,是一个树型的目录服务,支持变更推送,适合作为 Dubbo 服务的注册中心,工业强度较高,可用于生产环境,并推荐使用 。

zookeeper

具体zookeeper怎么安装就不说了,自己看Zookeeper安装手册

dubbo

  1. 简介 (1)Apache Dubbo 是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用、智能容错和负载均衡、服务自动注册和发现。

    (2)官网:http://dubbo.apache.org

    (3)发展历程 2011,发布到github 2014.10,2.4.11版本发布后停更版本,dubbox(当当)、dubbok(网易考拉)还在继续更新 2017,SpringCloud大红大紫后,又开始连续更新数个版本到2.6版本(合并dubbox) 2018.2.15 除夕夜,dubbo贡献给了Apache组织。 (4)dubbo的优良特性: 面向接口代理的高性能RPC调用 智能负载均衡 服务自动注册与发现(注册中心) 高度可扩展能力(微内核和插件模式) 运行期流量调度(配置不同的负责,实现灰度发布) 可视化的服务治理与运维

  2. dubbo加载顺序

    1. 最高优先级:JVM启动参数设置,例如:-Ddubbo.protocol.port=20882,观察启动日志的输出,验证结果
    2. 优先级次之:springboot的配置文件,application.properties,观察启动日志的输出,验证结果
    3. 最低优先级:dubbo的配置文件dubbo.properties,观察启动日志的输出,验证结果 注意:配置项一般都是放在application.properties当中

下面开始上代码(先开zookeeper服务)

common-interface

先定义一个公共接口模块,下面是项目结构

common-interface

这个模块就不上pom文件了,就一个lombok

User.java

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
    private String username;
    private Integer age;
    private String gender;
}

需要实现Serializable接口,不然序列化不了。

UserService.java

import com.debugers.common.model.User;

import java.util.List;

/**
 * user service
 * @author HarryZhang
 */
public interface UserService {
    List<User> getUserList();
}

就欧克了这个模块。

dubbo-provider

老规矩,项目结构:

dubbo-provider

pom.xml

            <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>
		<!--公共接口-->
        <dependency>
            <groupId>com.debugers</groupId>
            <artifactId>common-interface</artifactId>
            <version>1.0.0</version>
        </dependency>
		<!--如果是springboot 1.x 请改为0.1.0-->
		<!--对应的dubbo版本好像是2.6的-->
        <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>0.2.0</version>
        </dependency>

注意:如果是springboot 1.x 请改为0.1.0,只截取了一部分。

UserServiceImpl.java

import com.alibaba.dubbo.config.annotation.Service;
import com.debugers.common.model.User;
import com.debugers.common.service.UserService;

import java.util.Arrays;
import java.util.List;

@Service
public class UserServiceImpl implements UserService {
    @Override
    public List<User> getUserList() {
        User user1=new User("HarryZhang",19,"男");
        User user2=new User("james",25,"男");
        User user3=new User("stranger",18,"女");
        return Arrays.asList(user1,user2,user3);
    }
}

注意这里的@Service不是spring包的,而是dubbo下面的。

这里模拟数据库请求返回数据,并没有搞得很复杂。

application.yaml

dubbo:
  application:
    name: dubbo-provider # 服务名
  registry:
    address: zookeeper://127.0.0.1:2181 # 注册中心地址
  protocol:
    name: dubbo # 指定通信协议
    port: 20880 # 通信端口  这里指的是与消费者间的通信协议与端口
  provider:
    timeout: 10000 # 配置全局调用服务超时时间,dubbo默认是1s,肯定不够用呀
    retries: 3 # 重试3次
    delay: -1

启动类

注意:启动类上一定要加上@EnableDubbo注解,允许dubbo。到这这个模块也欧克了。

dubbo-consumer

老规矩:

dubbo-consumer

Tips:图上模块名打错了,不要在意。

pom.xml

跟上面的一样,没有什么大改动

UserController

import com.alibaba.dubbo.config.annotation.Reference;
import com.debugers.common.model.User;
import com.debugers.common.service.UserService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class UserController {
    @Reference(check = false,timeout = 2000,retries = 2,loadbalance = "roundrobin" )
    private UserService userService;
    @GetMapping("user")
    public List<User> getUserList(){
        return userService.getUserList();
    }
}

调用采用@Reference注解

  • 启动检查 check = false
    • 设置单个dubbo服务,check = false:启动不检查远程的服务是否存在。
    • 远程服务调用很多,一一配置麻烦,可以配置当前消费者的统一规则:所有服务都启动不检 dubbo.consumer.check=false
    • 默认需要检查;如果没有远程服务没有,启动的时候会输出如下异常:Failed to check the status of the service
  • 服务超时设置 timeout = 5000
    • 解决因为服务端一致没有响应的情况下,可能导致调用端大量线程的阻塞,可以设置服务超时时间。
    • 默认超时时间为1s
  • 重试次数 retries = 2(默认为)
    • 因为网络等原因,服务调用失败的时候,服务会重新调用
    • 当服务提供者有多个的时候,会分别取调用,不会再一棵树上吊死
    • 幂等性的操作,例如查询、修改和删除,才可以加重试次数
    • dubbo默认的重试次数为2
    • 重试次数一般和超时设置同时使用
  • 多版本 version = "1.0.0" 或者 version = "1.1.0" 或者 version = "*"(随机调用)
    • 当服务升级,为了兼容需求,可以根据版本号可以实现平滑过渡
    • 或者实现灰度发布的
  • 负载均衡机制
    • loadbalance = “random”,基于权重的随机负载均衡机制(默认负载均衡策略)
    • loadbalance = "roundrobin",基于权重的轮询负载均衡机制
    • loadbalance = "leastactive",最少活跃数负载均衡(挑选上一次请求调用时间最少的访问)

application.yaml

dubbo:
  application:
    name: dubbo-consumer # 消息者名字
  registry:
    address: zookeeper://127.0.0.1:2181 # 注册中心地址
server:
  port: 8090

注意:启动类同样要加上@EnableDubbo注解

这个模块也就欧克了.下面先跑起来.

启动

  • 先保证zookeeper的服务是启动的.
  • 再运行dubbo-provider模块
  • 最后启动dubbo-consumer模块

访问:localhost:8090/user

result

没毛病,到这里.本篇文章只是搭建一个入门demo,需要详细信息还请参考官网.

如有错误,请积极指出,谢谢!