• dubbo泛化调用


    官方文档:泛化调用(客户端泛化) | Apache Dubbo

    官方dubbo项目案例:dubbo-samples/dubbo-samples-generic at master · apache/dubbo-samples · GitHub

    下载下案例源码,本地启动下zk即可debug调试

    使用场景

    泛化调用主要用于实现一个通用的远程服务 Mock 框架,可通过实现 GenericService 接口处理所有服务请求。比如如下场景:

    1. 网关服务:如果要搭建一个网关服务,那么服务网关要作为所有RPC服务的调用端。但是网关本身不应该依赖于服务提供方的接口API(这样会导致每有一个新的服务发布,就需要修改网关的代码以及重新部署),所以需要泛化调用的支持。

    2. 测试平台:如果要搭建一个可以测试RPC调用的平台,用户输入分组名、接口、方法名等信息,就可以测试对应的RPC服务。那么由于同样的原因(即会导致每有一个新的服务发布,就需要修改网关的代码以及重新部署),所以平台本身不应该依赖于服务提供方的接口API。所以需要泛化调用的支持

    dubbo泛化调用主要API

    com.alibaba.dubbo.config.RegistryConfig; //注册中心配置 com.alibaba.dubbo.config.ApplicationConfig; //应用配置 com.alibaba.dubbo.config.ReferenceConfig; //引用的服务配置(类似reference注解或xml配置) com.alibaba.dubbo.rpc.service.GenericService;//实际调用的服务(泛化服务)
    其中com.alibaba.dubbo.rpc.service.GenericService#$invoke是泛化调用方法


    其中com.alibaba.dubbo.rpc.service.GenericService#$invoke是泛化调用方法

    方法入参分别为方法名称、参数类型数组、入参对象数组

    GenericService只有一个方法Object$invoke(String method,String[] parameterTypes,Object[] args)throwsGenericException;invoke接受三个参数,分别为方法名,参数类型组以及参数值组,其中参数类型和参数值一一对应。

    GenericService的实例化是通过ReferenceConfig的单例调用方法得到的。ReferenceConfig配置了诸如服务接口名等参数。需要注意的是,在使用泛化调用时,generic属性要置为true

    1. package com.alibaba.dubbo.rpc.service;
    2. public interface GenericService {
    3. /**
    4. * Generic invocation
    5. *
    6. * @param method Method name, e.g. findPerson. If there are overridden methods, parameter info is
    7. * required, e.g. findPerson(java.lang.String)
    8. * @param parameterTypes Parameter types
    9. * @param args Arguments
    10. * @return invocation return value
    11. * @throws Throwable potential exception thrown from the invocation
    12. */
    13. Object $invoke(String method, String[] parameterTypes, Object[] args) throws GenericException;
    14. }

    GenericService的实例化实例化案例:

    1. public static void main(String[] args) throws Exception {
    2. ApplicationConfig applicationConfig = new ApplicationConfig();
    3. applicationConfig.setName("generic-call-consumer");
    4. RegistryConfig registryConfig = new RegistryConfig();
    5. registryConfig.setAddress("zookeeper://127.0.0.1:2181");
    6. ReferenceConfig referenceConfig = new ReferenceConfig<>();
    7. referenceConfig.setInterface("org.apache.dubbo.samples.generic.call.api.HelloService");
    8. applicationConfig.setRegistry(registryConfig);
    9. referenceConfig.setApplication(applicationConfig);
    10. referenceConfig.setGeneric(true);
    11. referenceConfig.setAsync(true);
    12. referenceConfig.setTimeout(7000);
    13. genericService = referenceConfig.get();
    14. }

    调用流程:

    调用 <-> GenericImplFilter <-> 网络 <-> GenericFilter <-> 服务实现

    其中在GenericImplFilter中会在Consumer端,对泛化调用相关参数重新构建和处理,使用invoke.invoke发起调用

     然后会调用服务端的对应的接口和方法,会被GenericFilter拦截

    注意:GenericImplFilter并不是GenericFilter的实现,他们两个是Filter接口的实现

    参数封装案例:如果是多重对象参数,可以传入json,例如

    1. // 实体类
    2. public class User implements Serializable {
    3. private static final long serialVersionUID = 4741417427705290705L;
    4. private String name;
    5. private int gender;
    6. //getter & setter & constructor
    7. }
    8. // 实体类
    9. public class PageReq implements Serializable {
    10. private static final long serialVersionUID = -6720015744986291779L;
    11. private int pageSize;
    12. private int pageNum;
    13. private T queryParam;
    14. //getter & setter & constructor
    15. }
    16. // 接口
    17. public interface TestGenericService {
    18. String genericTypeParam(PageReq userReq);
    19. }
    20. // 参数封装,并调用
    21. public static void main(String[] args) {
    22. //方法名
    23. String methodName = "genericTypeParam";
    24. //参数类型
    25. String[] parameterTypes = new String[1]; //1个参数类型
    26. parameterTypes[0] = "service.PageReq"; //参数类的全限定名
    27. //参数对象
    28. Object[] objectParams = new Object[1]; //1个参数值
    29. JSONObject paramPage = new JSONObject(); //看作是对象转换为JSONObject的过程
    30. paramPage.put("pageNum", 10);
    31. paramPage.put("pageSize", 1);
    32. JSONObject paramUser = new JSONObject();
    33. paramUser.put("name", "nicolimine");
    34. paramUser.put("gender", 1);
    35. paramUser.put("class", "service.User");//注意这里,PojoUtils解析Map类型,如果存在key=class时,会直接指定该Object类型
    36. paramPage.put("queryParam", paramUser);
    37. objectParams[0] = paramPage;
    38. //执行泛化调用,genericService如何实例化可以参考官方案例
    39. genericService.$invoke(methodName, parameterTypes, objectParams);
    40. }
  • 相关阅读:
    docker-ubuntu
    无线键盘RED认证
    input改造文件上传,el-table的改造,点击上传,拖拽上传,多选上传
    【数据库系统概论】实验五 SQL数据库安全控制
    字节码增强技术-ASM
    JSON概念、基础语法及数据和对象转换
    Rust错误处理
    如何打造智慧公厕管理系统,提升公共厕所智能化服务质量?
    26、Stream流式计算,链式编程
    Doris扩容和缩容
  • 原文地址:https://blog.csdn.net/qq_36042938/article/details/126679602