dubbo框架

dubbo

dubbo介绍

Apache Dubbo |ˈdʌbəʊ| 是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现

中文官网: http://dubbo.apache.org/zh-cn/

dubbo工作原理

title

dubbo+zookeeper入门案例

首先确保zookeeper集群已经运行

1 创建父子项目

父项目: testdubbo

子项目: 测试方便, 均打jar包

  1. consumer 消费者 --> 添加springboot主启动类
  2. interface 接口-SOA思想 --> 不需要主启动类
  3. producer 生产者 --> 添加springboot主启动类

2. maven依赖

在父项目中导入dubbo的依赖

地址: https://mvnrepository.com/artifact/com.alibaba.boot/dubbo-spring-boot-starter

<dependency>
    <groupId>com.alibaba.boot</groupId>
    <artifactId>dubbo-spring-boot-starter</artifactId>
    <version>0.2.0</version>
</dependency>

测试使用的依赖还有spring web, thymeleaf, lombok

3. interface子项目

此项目为SOA思想的接口中间项目

定义User实体类: 此实体类需要实现Serializable序列化接口, 因为底层要实现远程调用

@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true) // 加不加无所谓, lombok中的注解, 用来连续赋值
public class User implements Serializable {

    private static final long serialVersionUID = 1298816803633464735L;
    private String username;
    private String password;
    private String phone;
    private String email;

}

定义测试的service接口

public interface UserService {

    User findUser(); // 查询用户   测试...

}

4. 生产者producer

pom依赖, 需要引入interface子项目

<dependencies>
    <dependency>
        <groupId>com.aarom</groupId>
        <artifactId>interface</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>
</dependencies>

实现interface子项目中的UserService接口

注意@Service注解使用阿里巴巴包下的, 不要使用spring包的com.alibaba.dubbo.config.annotation.Service

// Service注解使用com.alibaba.dubbo.config.annotation.Service包下的
@Service(timeout = 3000) //3秒超时 使用dubbo的注解
public class UserServiceImpl implements UserService {
    
    @Override
    public User findUser() {
        User user = new User();
        user.setUsername("admin");
        user.setPassword("123456");
        user.setPhone("1231231231");
        user.setEmail("231@qq.com");
        return user;
    }
}

application.yml配置文件配置如下:

server:
  port: 8082

logging:
  level:
    com.aaron: debug

dubbo:
  scan:
    basePackages: com.aaron    #指定dubbo的包路径 扫描dubbo的注解
  application:              #应用名称
    name: provider-user     #相同的接口 服务名称必定一致.  不同的接口服务名称一定不一致.
  registry:     #配置注册中心
    address: zookeeper://192.168.126.129:2181?backup=192.168.126.129:2182,192.168.126.129:2183
  protocol:  #指定协议
    name: dubbo  #使用dubbo协议(tcp-ip)  web-controller直接调用sso-Service
    port: 20880  #每一个服务都有自己特定的端口 不能重复.

5. 消费者consumer

消费者负责调用interface子项目中的UserService接口, 此接口的实现有生产者producer完成

注意: 依赖注入使用阿里巴巴下的@Reference注解, 不要使用@Autowired com.alibaba.dubbo.config.annotation.Reference

@RestController
public class UserController {

    // 此注解为阿里巴巴下的 com.alibaba.dubbo.config.annotation.Reference 包
    @Reference //@Reference(check = false) 不检查生产者
    private UserService userService;

    @RequestMapping("/findUser")
    public User findAll() {
        return userService.findUser();
    }

}

application.yml配置文件如下:

server:
  port: 8081

logging:
  level:
    com.aaron: debug

dubbo:
  scan:
    basePackages: com.aaron
  application:
    name: consumer-user   #定义消费者名称
  registry:               #注册中心地址
    address: zookeeper://192.168.126.129:2181?backup=192.168.126.129:2182,192.168.126.129:2183

6. 进行测试

尽量先启动生产者producer, 再启动消费者consumer, 如果@Reference注解加上参数@Reference(check = false), 启动顺序无所谓

浏览器输入: http://localhost:8081/findUser 是否可以正常输出

如果输出了正常信息, 说明配置成功

关于InvocationTargetException异常

java.lang.reflect.InvocationTargetException: null dubbo的异常信息

可能是因为配置文件中dubbo.scan.basePackages的值有问题, 请检查包是否正确

如果还不可以, 试着将属性basePackages 换成 base-packages

dubbo负载均衡

测试负载均衡

在上述的入门案例中, 我们可以再添加一个子项目producer2, 即生产者2, 内容与producer子项目类似, 但是配置文件需要做改动

dubbo:
  scan:
    basePackages: com.aaron    #指定dubbo的包路径 扫描dubbo的注解
  application:              #应用名称
    name: provider-user     #相同的接口 服务名称必定一致.  不同的接口服务名称一定不一致.
  registry:     #配置注册中心
    address: zookeeper://192.168.126.129:2181?backup=192.168.126.129:2182,192.168.126.129:2183
  protocol:  #指定协议
    name: dubbo  #使用dubbo协议(tcp-ip)  web-controller直接调用sso-Service
    port: 20882  #每一个服务都有自己特定的端口 不能重复.

注意的地方有两处:

  1. port 配置文件中dubbo的端口号必须和其他生产者不一样
  2. 如果是同一个模块, 要实现负载均衡, application下的 name属性要和其他生产者名字一致, 这里生产者1和生产者2的值都是provider-user

为了方便区分负载均衡, 可以在UserServiceImpl中添加不同的输出内容, 用户测试区分

上述内容配置就绪以后, 浏览器再次输入: http://localhost:8081/findUser 多次刷新, 查看两个生产者的控制台输出即可

负载均衡策略

dubbo中提供了一个接口Loadbalance 此接口有4个实现类, 就是这4种负载均衡策略

4中策略: 默认为第三种, 随机策略 , 使用负载均衡时, 参数必须全小写!!!

  1. consistenthash hash一致性原则

    根据IP:port进行hash运算,之后绑定固定的提供者进行访问.
    效果: 以后消费者与服务提供者进行了绑定.

    使用方法: 注解 @Reference(loadbalance = "consistenthash")

  2. leastactive 挑选访问压力最小的

    挑选当前服务器压力较小的进行访问.

    使用方法: 注解 @Reference(loadbalance = "leastactive")

  3. random 随机访问

    随机访问策略

    使用方法: 注解 @Reference(loadbalance = "random")

  4. roundrobin 轮循策略

    轮流访问达到负载均衡

    使用方法: 注解 @Reference(loadbalance = "roundrobin")

zookeeper中存储结构

在zookeeper安装目录下, 进入bin目录, 里面有个zkCli.sh 用户启动zookeeper客户端进行访问

进入zookeeper客户端: sh zkCli.sh

退出客户端: quit

在zookeeper客户端中, 我们输入ls指令, 可以查看目录

例如: ls / 查看zookeeper的根路径

例如: ls /dubbo 查看根路径下的dubbo路径

zookeeper的数据存储结果如下:

dubbo的通讯原理

通讯协议: dubbo协议(tcp-ip)

说明: dubbo协议将TCP-IP协议进行封装.

Dubbo框架中使用dubbo协议建立了链接,之后通过IP:20880等端口 (yaml中配置的端口) 进行通讯,与LinuxIP地址无关.

客户端负载均衡/集中式负载均衡

集中式负载均衡

集中式负载均衡例如nginx

特点:

  1. 用户访问服务器时,自己不清楚访问的真实的服务器到底是谁,由nginx服务器动态的反向代理实现.
  2. 统一由负载均衡服务器进行负载. 问题 负载均衡服务器访问压力高.

客户端负载均衡

  1. 消费者在访问服务提供者时清楚的了解 到底应该访问哪台服务器.
  2. 由于每个客户端都进行负载均衡.相当于将压力均匀的分配给客户端.访问压力低.

核心:

  1. nginx一般只负责反向代理
  2. 在微服务框架中 几乎都是客户端负载均衡服务器.
原文地址:https://www.cnblogs.com/zpKang/p/13536592.html