目录

  • 一、介绍
  • 二、自定义负载均衡器
  • (一)自定义负载均衡
  • 1、引入dubbo依赖
  • 2、编写类并实现LoadBalance
  • 3、配置
  • (二)使用自定义负载均衡
  • 1、服务方
  • ①设置idea,允许一个类启动多个实例
  • ②启动provider1
  • ③启动provider2
  • ④启动provider3
  • 2、消费方(以在消费方使用负载均衡为例)
  • ①首先使用dubbo自带的轮询策略
  • ②使用自定义负载均衡器 onlyFirst


一、介绍

  1. 负载均衡(Load Balance), 其实就是将请求分摊到多个操作单元上进行执行,从而共同完成工作任务。
  2. 负载均衡策略主要用于客户端存在多个提供者时进行选择某个提供者。
  3. 在集群负载均衡时,Dubbo 提供了多种均衡策略(包括随机、轮询、最少活跃调用数、一致性Hash),缺省为random随机调用。
    详见官方文档,已经写得很详细了
    配置负载均衡策略,既可以在服务提供者一方配置,也可以在服务消费者一方配置,如下:
//在服务消费者一方配置负载均衡策略
 @Reference(loadbalance = "random")
//在服务提供者一方配置负载均衡
@Service(loadbalance = "random")
public class HelloServiceImpl implements HelloService {
  public String sayHello(String name) {
    return "hello " + name;
 }
}

二、自定义负载均衡器

在基本案例基础上创建名称为dubbo-spi-loadbalance的Maven模块,并创建负载均衡器OnlyFirstLoadbalancer。这里功能只是简单的选取所有机器中的第一个(按照字母排序 + 端口排序)。

(一)自定义负载均衡

1、引入dubbo依赖

<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo</artifactId>
</dependency>

2、编写类并实现LoadBalance

package com.lagou;

import org.apache.dubbo.common.URL;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.cluster.LoadBalance;

import java.util.Comparator;
import java.util.List;

/**
 * 负载均衡
 */
public class OnlyFirstLoadBalance implements LoadBalance {
    @Override
    public <T> Invoker<T> select(List<Invoker<T>> list, URL url, Invocation invocation) throws RpcException {
        // 所有的服务提供者 按照IP  + 端口排序   选择第一
        return list.stream().sorted(Comparator.comparing(tInvoker -> tInvoker.getUrl().getIp())
        ).sorted(Comparator.comparing(tInvoker -> tInvoker.getUrl().getPort())).findFirst().get();

    }
}

3、配置

在dubbo-spi-loadbalance工程的 META-INF/dubbo 目录下新建org.apache.dubbo.rpc.cluster.LoadBalance 文件,并将当前类的全名写入

# onlyFirst=包名.负载均衡器
onlyFirst=com.lagou.OnlyFirstLoadBalance

dubbo 负载均衡自定义 dubbo做负载均衡_ide

(二)使用自定义负载均衡

  • 在服务提供者工程实现类中编写用于测试负载均衡效果的方法 启动不同端口时 方法返回的信息不同
  • 启动多个服务 要求他们使用同一个接口注册到同一个注册中心 但是他们的dubbo通信端口不同
  • 本地测试时,可以直接复制多份配置(也可以像本例一样,开始idea允许一个类启动多个实例的配置),并在每个配置启动时,修改HelloServiceImpl中方法的返回值以及dubbo-provider.properties中的端口号

1、服务方

①设置idea,允许一个类启动多个实例

dubbo 负载均衡自定义 dubbo做负载均衡_dubbo_02

②启动provider1

dubbo 负载均衡自定义 dubbo做负载均衡_dubbo 负载均衡自定义_03


dubbo 负载均衡自定义 dubbo做负载均衡_负载均衡_04

③启动provider2

修改为:

dubbo.protocol.port=20882

return “【这里是服务端】hello 2:” + name;

dubbo 负载均衡自定义 dubbo做负载均衡_dubbo 负载均衡自定义_05


dubbo 负载均衡自定义 dubbo做负载均衡_负载均衡_06

④启动provider3

修改为:

dubbo.protocol.port=20883

return “【这里是服务端】hello 3:” + name;

dubbo 负载均衡自定义 dubbo做负载均衡_自定义_07


dubbo 负载均衡自定义 dubbo做负载均衡_ide_08

2、消费方(以在消费方使用负载均衡为例)

①首先使用dubbo自带的轮询策略

dubbo 负载均衡自定义 dubbo做负载均衡_负载均衡_09


输入1111,回车(5次调用)

结果如下:

dubbo 负载均衡自定义 dubbo做负载均衡_dubbo_10

②使用自定义负载均衡器 onlyFirst

策略改为自定义的

首先,需要consumer的pom中引入负载均衡的依赖

<!-- 引入负载均衡 -->
<dependency>
    <groupId>com.lagou</groupId>
    <artifactId>dubbo-spi-loadbalance</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

dubbo 负载均衡自定义 dubbo做负载均衡_ide_11

重启consumer端,再测试,结果如下:

dubbo 负载均衡自定义 dubbo做负载均衡_ide_12