dubbo泛化调用使用及问题总结

最近在项目开发中需要使用到dubbo泛化调用功能 ,以前使用一直用xml配置方式,没研究过dubbo泛化调用。通过查看官方文档、网上查找dubbo泛化调用资料最终完成了dubbo泛化调用功能。在此总结一下dubbo泛化调用开发过程及遇到的一些问题以及处理方法,还有部分问题尚未成功处理,欢迎大家有兴趣的朋友留言讨论

dubbo版本:2.8.4

1、dubbo泛化功能说明

dubbo泛化调用就是服务消费端不需要引入接口jar包,通过GenericService接口就能处理完成所有服务的调用,参数及返回值中的所有POJO均用Map表示。

2、dubbo泛化调用功能实现代码

public class DubboServiceFactory {
	public static Logger logger = LoggerFactory.getLogger(DubboServiceFactory.class);
	private ApplicationConfig application;
	private RegistryConfig registry;
	private String version;

	private static class SingletonHolder {
		private static DubboServiceFactory INSTANCE = new DubboServiceFactory();
	}

	public static DubboServiceFactory getInstance() {
		return SingletonHolder.INSTANCE;
	}

	private DubboServiceFactory() {
		ApplicationConfig applicationConfig = new ApplicationConfig();
		applicationConfig.setName("");
		applicationConfig.setVersion("");
		// 这里配置了dubbo的application信息*(demo只配置了name)*,因此demo没有额外的dubbo.xml配置文件
		RegistryConfig registryConfig = new RegistryConfig();
		registryConfig.setAddress("");
		registryConfig.setFile("/tmp/dubbo.cachr");
		// 这里配置dubbo的注册中心信息,因此demo没有额外的dubbo.xml配置文件
		this.application = applicationConfig;
		this.registry = registryConfig;
	}

	public Object genericInvoke(String interfaceClass, String methodName, String parameterType, Object param) {
		ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>();
		reference.setApplication(application);
		reference.setRegistry(registry);
		reference.setVersion(version);
		reference.setInterface(interfaceClass); // 接口名
		reference.setGeneric(true); // 声明为泛化接口
		// ReferenceConfig实例很重,封装了与注册中心的连接以及与提供者的连接,
		// 需要缓存,否则重复生成ReferenceConfig可能造成性能问题并且会有内存和连接泄漏。
		// API方式编程时,容易忽略此问题。
		// 这里使用dubbo内置的简单缓存工具类进行缓存
		ReferenceConfigCache cache = ReferenceConfigCache.getCache();
		GenericService genericService = cache.get(reference);
		if (genericService == null) {
			cache.destroy(reference);
			throw new IllegalStateException("服务不可用");
		}

		if (parameterType == null) {
			return genericService.$invoke(methodName, new String[] {}, new Object[] {});
		}
		return genericService.$invoke(methodName, new String[] { parameterType }, new Object[] { param });
	}
}

只需要配置应用名、版本、注册中心地址。

Object result = DubboServiceFactory.getInstance().genericInvoke(interfaceClass, methodName, parameterType, object);

3、问题总结

a、

1、问题:若泛化调用服务消费端先启动,在服务提供端未启动之前,泛化调用服务消费端某接口(a)进行了一次调用,在后续即使服务提供端成功启动,泛化调用服务消费端依然不能正常访问某接口(a)
2、原因:因为ReferenceConfig实例很重,封装了与注册中心的连接以及与提供者的连接,需要缓存,否则重复生成ReferenceConfig可能造成性能问题并且会有内存和连接泄漏。所以在调用服务时,不论服务提供端接口服务是否存在,ReferenceConfigCache都会缓存ReferenceConfig实例(若调用服务提供端不存在,ReferenceConfig实例的ref参数为空,即不能生成GenericService对象),再下次请求时,即使服务提供端正常提供服务,但因为ReferenceConfigCache已经缓存了ReferenceConfig实例,所以不会再重新创建链接,直接从ReferenceConfigCach缓存中获取GenericService对象,导致GenericService实例一直报空指针(因为ref参数为空),最终导致一直调用不到真正的服务
3、处理方法:在GenericService对象调用方法($invoke)之前,先判断GenericService是否为空,若为空,则调用ReferenceConfigCache对象的destroy方法,下次调用时即会重新生成ReferenceConfig实例,不会再从缓存中取。

b、

1、问题:在正常调用过程中,若服务提供端中断,再重启,即使服务提供端已经重新正常提供服务,但泛化调用服务消费端仍会有一断时间无法成功消费服务

2、原因:

3、处理方法:

 

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值