Apache Dubbo 框架的使用(四)

Springboot_Dubbo_Zookeeper相关配置

yml相关配置信息(生产者——拓展):

# 关于Dubbo相关的配置
# 1:指定当前服务/应用的名字(同样的服务名字相同,不要和别的服务同名)
dubbo:
  application:
    name: boot-provider

# 2:指定注册中心的位置
  registry:
    address: 127.0.0.1:2181
    protocol: zookeeper
    check: true

# 3:指定通信规则(通信协议?通信端口)
  protocol:
    name: dubbo
    port: 20880

# 4:声明需要暴露的服务接口 (ref:指向服务的真正的实现对象)
# ref:指向服务的真正的实现对象(服务的实现)------------在FoodServiceImpl实现类加入注解@Service(注意是com.alibaba.dubbo包下面的)

# 5:配置监控中心
  monitor:
    protocol: registry

# 6:超时属性
  provider:
    timeout: 1000

# 7:重试次数(配合超时使用,不包括第一次调用)
    retries: 3 # 0代表不重试

# 8:多版本
    version: 1.0.0

yml相关配置信息(消费者——拓展):

# 关于Dubbo相关的配置
# 1:指定当前服务/应用的名字(同样的服务名字相同,不要和别的服务同名)
dubbo:
  application:
    name: boot-consumer

# 2:指定注册中心的位置
  registry:
    protocol: zookeeper
    address: 127.0.0.1:2181
    check: true

# 3:声明需要调用的远程服务的接口:生成远程服务代理-----在实现类依赖注入使用@Reference注解

# 4:配置监控中心
  monitor:
    protocol: registry

# 5:启动时检查
  consumer:
    check: true

# 6:超时属性(消费者调用生产者时,超出设置时间)
    timeout: 6000

# 7:重试次数(配合超时使用,不包括第一次调用)
    retries: 3 # 0代表不重试

# 8:多版本
    version: 1.0.0

# 9:本地存根(可以避免一些没必要的远程调用,类的完全限定名)
    stub: com.kd.opt.service.impl.FoodServiceImpl3

注意(关于配置覆盖关系):
1:方法级优先,接口级次之,全局配置再次之(先考虑)
2:如果级别一样,则消费方优先,提供方次之

1.启动时检查

当生产者服务关闭,消费者服务开启时:
Apache Dubbo 框架的使用(四)
消费者添加yml配置信息(取消启动时检查):

dubbo:
  consumer:
    check: false

Apache Dubbo 框架的使用(四)

2.超时(生产者提供时间较长,造成多线程阻塞)

利用线程睡眠模拟生产者超时:

package com.kd.opt.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.kd.opt.entity.Food;
import com.kd.opt.service.FoodService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * 实现FoodService接口
 *
 * @author 小辰哥哥
 */

// 暴露服务(注意是com.alibaba.dubbo包下面的)
@Service

// 之前的@Service(spring家的)可以用@Component代替
@Component
public class FoodServiceImpl implements FoodService {

  // 打印日志
  private static final Logger LOGGER = LoggerFactory.getLogger(FoodServiceImpl.class);

  @Override
  public List<Food> getFoodAll() {

    // 创建一个ArrayList集合模拟数据库
    List<Food> foodList = new ArrayList<>();
    foodList.add(new Food("1","蓝色妖姬"));
    foodList.add(new Food("2","骨肉相连"));
    foodList.add(new Food("3","螺蛳粉"));


    // 测试Dubbo超时属性(睡眠5秒)
    try {
      Thread.sleep(5000);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

    LOGGER.debug("调用完成");

    return foodList;
  }
}

当消费者调用生产者时会报错,因为消费者默认超时时间为1秒:
Apache Dubbo 框架的使用(四)
消费者添加yml配置信息(增加超时时间):

dubbo:
  consumer:
    timeout: 6000

再次调用将会成功:
Apache Dubbo 框架的使用(四)

3.重试次数(配合超时使用,不包含第一次调用)

消费者添加yml配置信息(当发生超时,开启重试次数):

dubbo:
  consumer:
    retries: 3 # 0代表不重试

Apache Dubbo 框架的使用(四)
注意:
1:幂等(无论重试多少次,结果都是一个效果,可以设置重试次数)
例如:查询、删除、修改
2:非幂等(不能设置重试次数)
例如:插入(新增)

4.多版本(当一个接口实现,出现不兼容升级时,可以用版本号过渡,版本号不同的服务相互间不引用),通过注解的方式配置

生产者version=1.0.0相关代码:

package com.kd.opt.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.kd.opt.entity.Food;
import com.kd.opt.service.FoodService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * 实现FoodService接口
 *
 * @author 小辰哥哥
 */

// 暴露服务(注意是com.alibaba.dubbo包下面的)
@Service(timeout = 1000,retries = 3,version = "1.0.0")

// 之前的@Service(spring家的)可以用@Component代替
@Component
public class FoodServiceImpl implements FoodService {

  // 打印日志
  private static final Logger LOGGER = LoggerFactory.getLogger(FoodServiceImpl.class);

  @Override
  public List<Food> getFoodAll() {

    // 创建一个ArrayList集合模拟数据库
    List<Food> foodList = new ArrayList<>();
    foodList.add(new Food("1","蓝色妖姬"));
    foodList.add(new Food("2","骨肉相连"));
    foodList.add(new Food("3","螺蛳粉"));


    // 测试Dubbo超时属性(睡眠5秒)
    try {
      Thread.sleep(5000);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

    LOGGER.debug("调用完成");

    return foodList;
  }
}

生产者version=2.0.0相关代码:

package com.kd.opt.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.kd.opt.entity.Food;
import com.kd.opt.service.FoodService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * 实现FoodService接口
 *
 * @author 小辰哥哥
 */

// 暴露服务(注意是com.alibaba.dubbo包下面的)
@Service(timeout = 1000,retries = 3,version = "2.0.0")

// 之前的@Service(spring家的)可以用@Component代替
@Component
public class FoodServiceImpl2 implements FoodService {

  // 打印日志
  private static final Logger LOGGER = LoggerFactory.getLogger(FoodServiceImpl2.class);

  @Override
  public List<Food> getFoodAll() {

    // 创建一个ArrayList集合模拟数据库
    List<Food> foodList = new ArrayList<>();
    foodList.add(new Food("4","麻辣烫"));
    foodList.add(new Food("5","土豆粉"));
    foodList.add(new Food("6","冷面"));


    // 测试Dubbo超时属性(睡眠5秒)
    try {
      Thread.sleep(5000);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

    LOGGER.debug("调用完成");

    return foodList;
  }
}

消费者调用version=2.0.0的生产者(相关代码):

package com.kd.opt.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.kd.opt.entity.Food;
import com.kd.opt.entity.User;
import com.kd.opt.service.FoodService;
import com.kd.opt.service.UserService;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 实现UserService接口
 *
 * @author 小辰哥哥
 */
// org.springframework.stereotype.Service(Spring家的)
@Service
public class UserServiceImpl implements UserService {

  // 引入食物业务层(依赖注入)
  // 不在使用@Autowired注解
  @Reference(check = true,timeout = 6000,retries = 3,version = "2.0.0")
  private FoodService foodService;

  @Override
  public User getUserAndFood() {

    // 获取食物相关信息
    List<Food> foodList = foodService.getFoodAll();

    // 创建一个用户对象
    User user = new User();
    user.setUserId("001");
    user.setUserName("小辰哥哥");
    user.setUserAge("18");
    user.setFoodList(foodList);

    return user;
  }
}

Apache Dubbo 框架的使用(四)
消费者添加yml配置信息(版本更替全局配置):

dubbo:
  consumer:
    version: 1.0.0
dubbo:
  provider:
    version: 1.0.0

可以按照以下的步骤进行版本迁移:
1:在低压力时间段,先升级一半提供者为新版本
2:再将所有消费者升级为新版本
3:然后将剩下的一半提供者升级为新版本

5.本地存根(可以避免一些没必要的远程调用)

boot-interface-all模块,新增生产者实现类(实现本地存根):
Apache Dubbo 框架的使用(四)
FoodServiceImpl3.java相关代码:

package com.kd.opt.service.impl;

import com.kd.opt.entity.Food;
import com.kd.opt.service.FoodService;

import java.util.List;

/**
 * 实现FoodService接口(本地存根)
 *
 * @author 小辰哥哥
 */
public class FoodServiceImpl3 implements FoodService {


  private final FoodService foodService;

  /**
   * 传入的是FoodService远程代理对象
   *
   * @author 小辰哥哥
   * @param foodService
   */
  public FoodServiceImpl3(FoodService foodService) {
    this.foodService = foodService;
  }

  @Override
  public List<Food> getFoodAll() {

    // 相当于个拦截器,可以先进行一系列的小验证
    if(!"1".equals("0")){

      // 当不满足某种条件时,返回值为Null
      return null;
    }
    return foodService.getFoodAll();
  }
}

消费者添加yml配置信息(实现本地存根,可以避免一些没必要的远程调用,类的完全限定名):

dubbo:
  consumer:
    stub: com.kd.opt.service.impl.FoodServiceImpl3

开始调用:
Apache Dubbo 框架的使用(四)

Apache Dubbo 框架的使用(四)


总结

每天一个提升小技巧!!!

上一篇:震荡示波法血压测量


下一篇:从理解到改进:非自回归翻译中的词汇选择 | 腾讯 AI 论文解读