dubbo泛化引发的生产故障之dubbo隐藏的坑

本文讲述了由于Dubbo泛化调用引发的生产故障,详细分析了故障原因:当provider未启动时,泛化调用会在Zookeeper中创建大量消费者节点。通过实验和源码分析,揭示了check=true情况下,每次请求都会创建新的消费节点,可能导致Zookeeper崩溃和本地应用OOM。解决方案是避免使用泛化调用或确保check=false,并关注官方修复的2.7.5版本。
摘要由CSDN通过智能技术生成

Python微信订餐小程序课程视频

https://edu.csdn.net/course/detail/36074

Python实战量化交易理财系统

https://edu.csdn.net/course/detail/35475

dubbo泛化引发的生产故障之dubbo隐藏的坑

上个月公司zk集群发生了一次故障,然后要求所有项目组自检有无使用Dubbo编程式/泛化调用,强制使用@Reference生成Consumer。具体原因是线上某服务访问量在短时间大量访问zk并创建了240万+的节点,导致zk所有节点陆续崩溃导致,多个应用因无法连接到zk报错。原因是听说泛化调用时候,provider没启动,导致每次请求都在zk创建消费节点。

由于是和自己关联性不大的项目组,了解的并不是很清楚,但是想搞明白这个事情,因此就进行了如下实验:

试验1:泛化不使用缓存

dubbo泛化写法

public Result getProductGenericCache(ProductDTO dto) {
    ReferenceConfig reference = new ReferenceConfig();
 ApplicationConfig application = new ApplicationConfig();
 application.setName("pangu-client-consumer-generic");
 // 连接注册中心配置
 RegistryConfig registry = new RegistryConfig();
 registry.setAddress("zookeeper://127.0.0.1:2181");
 // 服务消费者缺省值配置
 ConsumerConfig consumer = new ConsumerConfig();
 consumer.setTimeout(5000);
 consumer.setRetries(0);

 reference.setApplication(application);
 reference.setRegistry(registry);
 reference.setConsumer(consumer);
 reference.setInterface(org.pangu.api.ProductService.class); // 弱类型接口名
 // reference.setVersion("");
 // reference.setGroup("");
 reference.setGeneric(true); // 声明为泛化接口
 GenericService svc = reference.get();
 Object target = svc.$invoke("findProduct", new String[]{ProductDTO.class.getName()}, new Object[]{dto});//实际网关中,方法名、参数类型、参数是作为参数传入
 return Result.success((Map)target);
}

这个写法,就没有缓存reference,因此每次请求这个方法,就会在zk创建个消费节点(无论provider是否启动),请求量大的时候,就会导致zk所有节点陆续崩溃。使用泛化不缓存,这个估计稍微看了官方文档都不会出现这个错误。引发这次故障的这个应用功能,又不是初次上线,运行了一段时间了,生产有zk节点数监控,不然初次就发现这个问题了。因此基本可以排除对方是没有使用缓存的问题。

试验2:泛化使用缓存

@Override
public Result getProductGenericCache(ProductDTO dto) {
    ReferenceConfigCache referenceCache = ReferenceConfigCache.getCache();

    ReferenceConfig reference = new ReferenceConfig();//缓存,否则每次请求都会创建一个ReferenceConfig,并在zk注册节点,最终可能导致zk节点过多影响性能
 ApplicationConfig application = new ApplicationConfig();
 application.setName("pangu-client-consumer-generic");
 // 连接注册中心配置
 RegistryConfig registry = new RegistryConfig();
 registry.setAddress("zookeeper://127.0.0.1:2181");

 // 服务消费者缺省值配置
 ConsumerConfig consumer = new ConsumerConfig();
 consumer.setTimeout(5000);
 consumer.setRetries(0);

 reference.setApplication(application);
 reference.setRegistry(registry);
 reference.setConsumer(consumer);
 reference.setInterface(org.pangu.api.ProductService.class); // 弱类型接口名
 // reference.setVersion("");
 // reference.setGroup("");
 reference.setGeneric(true); // 声明为泛化接口
 GenericService svc = referenceCache.get(reference);//cache.get方法中会缓存 Reference对象,并且调用ReferenceConfig.get方法启动ReferenceConfig
 Object target = svc.$invoke("findProduct", new String[]{ProductDTO.class.getName()}, new Object[]{dto});//实际网关中,方法名、参数类型、参数是作为参数传入
 return Result.success((Map)target);
}

在provider端无论是否启动,都只会在zk创建一个消费节点

试验3:设置服务检查为true

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值