Dubbo
4 Dubbo 高级特性
文章目录
- Dubbo
- 4 Dubbo 高级特性
- 4.2 Dubbo 常用高级配置
- 4.2.2 地址缓存
- 4.2.3 超时
4.2 Dubbo 常用高级配置
4.2.2 地址缓存
【一个问题】
如果 注册中心挂了,服务是否可以正常访问?
- 可以,因为dubbo服务消费者在第一次调用时,会将服务提供方地址缓存到本地,以后在调用则不会访问注册中心。
- 当服务提供者地址发生变化时,注册中心会通知服务消费者。
【试试】
上次我们 已经实现了 一次访问,OK,我现在把 zookeeper 停掉
./zkServer.sh stop
OK
再试一次,能否 正常访问
OK,效果很明显, 就算注册中心 挂掉了, 【老的】服务依然可以正常 访问
4.2.3 超时
【一个场景】
现在还是 有一个 消费者 和一个 提供者
而且它俩 分别 部署在了 A B 两台 机器上
现在来了 一个 用户来访问 服务消费者
这时 服务消费者 内部会单独地创建 一个线程 来去访问服务提供者来 调用 服务
服务提供者 把数据处理好 后,把数据返回 给服务消费者
消费者拿到后,再把数据封装一下,就可以返回 给用户了
这样整个请求过程 就算结束了【线程 也就被释放了【或者 归还到线程池】】
这是正常理想情况。
【不正常 的情况】
- 服务消费者在调用服务提供者的时候发生了阻塞、等待的情形,这个时候,服务消费者会一直等待下去。
- 在某个峰值时刻,大量的请求都在同时请求服务消费者,会造成线程的大量堆积,势必会造成雪崩。
这样A 机器可能 就会因为 资源被用光 而就会挂掉了 。
【Dubbo的解决办法】
- dubbo 利用超时机制来解决这个问题,设置一个超时时间,在这个时间段内,无法完成服务访问,则自动断开连接。
- 使用timeout属性配置超时时间,默认值1000,单位毫秒。
比如说这里, 3s 种之内,你B 不给我响应,我当前一定断开 这个请求
这样就 不会 造成 ‘积压’ 了
【试试】
① 在服务提供方,在@Service 注解上配置 :
现在给查 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。重启两个 服务
访问测试测试
OK, 基本一致 ,3 s钟 到了,该超时 了,就开始报错了
大概就是这么 个意思
现在 把timeout 删掉 ,看看默认是多少
OK, 重启 service
嗯,timeout 默认值是 1s
现在 在服务 提供方配个 3s,在服务消费方配 个1s
试试现在会是多少
OK, 是1