Dubbo

4 Dubbo 高级特性


文章目录

  • Dubbo
  • 4 Dubbo 高级特性
  • 4.2 Dubbo 常用高级配置
  • 4.2.2 地址缓存
  • 4.2.3 超时


4.2 Dubbo 常用高级配置
4.2.2 地址缓存

dubbo 本地服务列表默认缓存时间 dubbo服务缓存什么时候更新_缓存

【一个问题】

如果 注册中心挂了,服务是否可以正常访问?

  • 可以,因为dubbo服务消费者在第一次调用时,会将服务提供方地址缓存到本地,以后在调用则不会访问注册中心。
  • 当服务提供者地址发生变化时,注册中心会通知服务消费者。

【试试】

dubbo 本地服务列表默认缓存时间 dubbo服务缓存什么时候更新_dubbo_02

上次我们 已经实现了 一次访问,OK,我现在把 zookeeper 停掉

./zkServer.sh stop

dubbo 本地服务列表默认缓存时间 dubbo服务缓存什么时候更新_缓存_03

OK

再试一次,能否 正常访问

dubbo 本地服务列表默认缓存时间 dubbo服务缓存什么时候更新_缓存_04

OK,效果很明显, 就算注册中心 挂掉了, 【老的】服务依然可以正常 访问

4.2.3 超时

【一个场景】

dubbo 本地服务列表默认缓存时间 dubbo服务缓存什么时候更新_dubbo_05

现在还是 有一个 消费者 和一个 提供者

而且它俩 分别 部署在了 A B 两台 机器上

现在来了 一个 用户来访问 服务消费者

dubbo 本地服务列表默认缓存时间 dubbo服务缓存什么时候更新_缓存_06

dubbo 本地服务列表默认缓存时间 dubbo服务缓存什么时候更新_dubbo_07

这时 服务消费者 内部会单独地创建 一个线程 来去访问服务提供者来 调用 服务

服务提供者 把数据处理好 后,把数据返回 给服务消费者

dubbo 本地服务列表默认缓存时间 dubbo服务缓存什么时候更新_java-zookeeper_08

消费者拿到后,再把数据封装一下,就可以返回 给用户了

这样整个请求过程 就算结束了【线程 也就被释放了【或者 归还到线程池】】

这是正常理想情况。

【不正常 的情况】

  • 服务消费者在调用服务提供者的时候发生了阻塞、等待的情形,这个时候,服务消费者会一直等待下去。

dubbo 本地服务列表默认缓存时间 dubbo服务缓存什么时候更新_dubbo_09

  • 在某个峰值时刻,大量的请求都在同时请求服务消费者,会造成线程的大量堆积,势必会造成雪崩。

dubbo 本地服务列表默认缓存时间 dubbo服务缓存什么时候更新_User_10

这样A 机器可能 就会因为 资源被用光 而就会挂掉了 。

【Dubbo的解决办法】

  • dubbo 利用超时机制来解决这个问题,设置一个超时时间,在这个时间段内,无法完成服务访问,则自动断开连接。
  • 使用timeout属性配置超时时间,默认值1000,单位毫秒。

dubbo 本地服务列表默认缓存时间 dubbo服务缓存什么时候更新_dubbo_11

比如说这里, 3s 种之内,你B 不给我响应,我当前一定断开 这个请求

dubbo 本地服务列表默认缓存时间 dubbo服务缓存什么时候更新_dubbo_12

这样就 不会 造成 ‘积压’ 了

【试试】

① 在服务提供方,在@Service 注解上配置 :

dubbo 本地服务列表默认缓存时间 dubbo服务缓存什么时候更新_缓存_13

现在给查 User ,让它睡一会儿

package com.dingjiaxiong.service.impl;

import com.dingjiaxiong.pojo.User;
import com.dingjiaxiong.service.UserService;
import org.apache.dubbo.config.annotation.Service;

/**
 * ClassName: UserServiceImpl
 * date: 2022/11/13 20:27
 *
 * @author DingJiaxiong
 */

//@Service

@Service(timeout = 3000,retries = 0) // 将这个类提供的方法【服务】对外发布,将访问的地址ip、端口、路径注册到 注册中心 中
public class UserServiceImpl implements UserService {
    public String sayHello() {
        return "Hello , Dubbo! DingJiaxiong";
    }

    public User findUserById(int id) {

        // 查询User 对象【这里躲懒了,不走数据库】
        User user = new User(1,"zhangsan","123");

        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return user;
    }
}

OK。

为了测试效果 更明显,修改一下控制器

package com.dingjiaxiong.controller;

import com.dingjiaxiong.pojo.User;
import com.dingjiaxiong.service.UserService;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * ClassName: UserController
 * date: 2022/11/13 20:39
 *
 * @author DingJiaxiong
 */

@RestController
@RequestMapping("/user")
public class UserController {

    //注入 Service
//    @Autowired  //这个是本地 注入
    @Reference
    private UserService userService;

    @RequestMapping("/sayHello")
    public String sayHello(){

        return userService.sayHello();
    }

    int i = 1;

    // 根据ID 查询用户信息
    @RequestMapping("/find")
    public User find(int id){

        new Thread(new Runnable() {
            public void run() {
                while (true){
                    System.out.println(i ++);
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }).start();


        return userService.findUserById(id);
    }

}

OK。重启两个 服务

dubbo 本地服务列表默认缓存时间 dubbo服务缓存什么时候更新_缓存_14

访问测试测试

dubbo 本地服务列表默认缓存时间 dubbo服务缓存什么时候更新_java-zookeeper_15

OK, 基本一致 ,3 s钟 到了,该超时 了,就开始报错了

dubbo 本地服务列表默认缓存时间 dubbo服务缓存什么时候更新_User_16

大概就是这么 个意思

现在 把timeout 删掉 ,看看默认是多少

dubbo 本地服务列表默认缓存时间 dubbo服务缓存什么时候更新_dubbo 本地服务列表默认缓存时间_17

OK, 重启 service

dubbo 本地服务列表默认缓存时间 dubbo服务缓存什么时候更新_dubbo_18

嗯,timeout 默认值是 1s

现在 在服务 提供方配个 3s,在服务消费方配 个1s

dubbo 本地服务列表默认缓存时间 dubbo服务缓存什么时候更新_User_19

试试现在会是多少

dubbo 本地服务列表默认缓存时间 dubbo服务缓存什么时候更新_缓存_20

OK, 是1