Dubbo泛化调用

  dubbo消费端,一般必须依赖服务端提供的api包,服务端api包一旦升级,消费端也要跟着升级(依赖的情况下),不像spring cloud一样,采用rest协议,对服务端的api依赖几乎可以没有,不过dubbo也有rest协议扩展,见当当网dubbox,也有jsonrpc协议的扩展,见https://github.com/apache/incubator-dubbo-rpc-jsonrpc ,都不依赖服务端提供的api包。

    dubbo消费端做到不依赖服务端提供的api,除了rest协议及jsonrpc协议扩展,dubbo也有一个功能可以做到,这个功能就是dubbo的泛化调用:

   泛化接口调用方式主要用于客户端没有 API 接口及模型类元的情况,参数及返回值中的所有 POJO 均用 Map 表示,通常用于框架集成,比如:实现一个通用的服务测试框架,可通过 GenericService 调用所有服务实现。

--引文:官方文档http://dubbo.apache.org/#/docs/user/demos/generic-reference.md?lang=zh-cn

 

 泛化调用的实现主要涉及到两个filter类:

    com.alibaba.dubbo.rpc.filter.GenericFilter
    com.alibaba.dubbo.rpc.filter.GenericImplFilter
分别在服务端和消费端做处理。

先看个简单的例子:

package com.sdcuike.dubbo.learning.service;
 
import com.alibaba.fastjson.JSONObject;
 
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
 
/**
 * @author sdcuike
 * @date 2018/5/31
 * @since 2018/5/31
 */
public interface HystrixService {
 
    String echo();
 
    int echo(int primitive);
 
    JSONObject testGener(String para);
 
    String testGenerRe(String para);
 
    String test(Par par);
 
    Set<String> testSet(Set<String> set);
 
    Object testMap(Map<String, Object> map);
 
    int[] testArray(int[] array);
 
    String[] testArray2(String[] strings);
 
    Date testDate(Date date);
 
    List<Object> testList(List<Object> list);
 
    public static class Par {
        private String name;
        private int age;
 
        public String getName() {
            return name;
        }
 
        public void setName(String name) {
            this.name = name;
        }
 
        public int getAge() {
            return age;
        }
 
        public void setAge(int age) {
            this.age = age;
        }
    }
 
    public static void main(String[] args) {
        System.out.println(Par.class.toString());
    }
}
package com.sdcuike.dubbo.learning.service.impl;
 
import com.alibaba.fastjson.JSONObject;
import com.sdcuike.dubbo.learning.service.HystrixService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
 
/**
 * @author sdcuike
 * @date 2018/5/31
 * @since 2018/5/31
 */
public class HystrixServiceImpl implements HystrixService {
    private Logger logger = LoggerFactory.getLogger(getClass());
 
    private AtomicLong atomicLong = new AtomicLong(0);
 
    private long startTimeMill = 0;
 
 
    @Override
    public String echo() {
        return "hello no param";
    }
 
    @Override
    public int echo(int primitive) {
        return primitive;
    }
 
    @Override
    public JSONObject testGener(String para) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("para", para);
        return jsonObject;
    }
 
    @Override
    public String testGenerRe(String para) {
 
        return "haha " + para;
    }
 
    @Override
    public String test(Par par) {
        return "wowo " + par.getName() + par.getAge();
    }
 
    @Override
    public Date testDate(Date date) {
        return date;
    }
 
    @Override
    public List<Object> testList(List<Object> list) {
        return list;
    }
 
 
    @Override
    public Set<String> testSet(Set<String> set) {
        return set;
    }
 
    @Override
    public Object testMap(Map<String, Object> map) {
        return map;
    }
 
    @Override
    public int[] testArray(int[] array) {
        return array;
    }
 
    @Override
    public String[] testArray2(String[] strings) {
        return strings;
    }
}

 上面代码定义了一个接口一个该接口对应的实现类。

 服务端的配置和普通的没区别:provider.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">


    <!-- 提供方应用信息,用于计算依赖关系 -->
    <dubbo:application name="provider-test"/>
 
    <!-- 使用multicast广播注册中心暴露服务地址 -->
    <dubbo:registry address="zookeeper://127.0.0.1:2181"/>
    <!-- 用dubbo协议在20880端口暴露服务 -->
    <dubbo:protocol name="dubbo" port="20088" host="127.0.0.1"/>
 
    <!-- 声明需要暴露的服务接口 -->
    <dubbo:service interface="com.sdcuike.dubbo.learning.service.HystrixService" ref="hystrixService" />
 
    <!-- 和本地bean一样实现服务 -->
    <bean id="hystrixService" class="com.sdcuike.dubbo.learning.service.impl.HystrixServiceImpl"/>
 
 
</beans>

消费端的配置就有些不同了,consumer.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
 
 
    <!-- 提供方应用信息,用于计算依赖关系 -->
    <dubbo:application name="consumer-test"/>
 
    <!-- 使用multicast广播注册中心暴露服务地址 -->
    <dubbo:registry address="zookeeper://127.0.0.1:2181"/>
    <dubbo:protocol name="dubbo"/>
    <dubbo:consumer timeout="3000" check="false"/>
 
    <!-- 声明需要暴露的服务接口 -->
    <dubbo:reference id="hystrixService" interface="com.sdcuike.dubbo.learning.service.HystrixService"
                     generic="true"
                     retries="0"/>
 
</beans>

不同点在于泛化的启用:generic="true"。

写个测试用例:启动服务端:

ProviderTest
package com.sdcuike.dubbo.learning.service;
 
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
import java.util.concurrent.TimeUnit;
 
/**
 * @author sdcuike
 * @date 2018/5/31
 * @since 2018/5/31
 */
public class ProviderTest {
 
    @Test
    public void test() throws Exception {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"provider.xml"});
        context.start();
 
        TimeUnit.HOURS.sleep(1);
 
    }
}

消费端测试用例:DubboGenericConsumerXmlTest,

package com.sdcuike.dubbo.learning.service;
 
import com.alibaba.dubbo.rpc.service.GenericService;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
/**
 * @author sdcuike
 * @date 2018/7/14
 * @since 2018/7/14
 */
public class DubboGenericConsumerXmlTest {
 
    GenericService hystrixService;
 
    @Before
    public void init() {
 
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"consumer.xml"});
 
        hystrixService = (GenericService) context.getBean("hystrixService");
    }
 
 
    @Test
    public void testGenerRe_参数为基本类型_参数类型传递() throws InterruptedException {
 
 
        Object result = hystrixService.$invoke("testGenerRe", new String[]{"java.lang.String"}, new Object[]{"test"});
 
        Assert.assertEquals("haha test", result.toString());
 
    }
 
    @Test
    public void testGenerRe_参数为基本类型_参数类型不传递() throws InterruptedException {
 
 
        Object result = hystrixService.$invoke("testGenerRe", null, new Object[]{"test"});
 
        Assert.assertEquals("haha test", result.toString());
 
    }
 
    @Test
    public void test_echo_无参数_有重载方法() {
 
        final Object echo = hystrixService.$invoke("echo", new String[]{}, null);
 
        Assert.assertEquals("hello no param", echo.toString());
    }
 
}

不同以往的消费端服务引用,我们这里引用的泛化接口com.alibaba.dubbo.rpc.service.GenericService。

再调用相应服务方法的时候,我们必须显示的传递方法名及参数,但对于参数类型我们可以不必传递, 但方法重载的情况下,我们必须传递

源码见:

https://github.com/sdcuike/all_learning_201806/tree/master/dubbo-learning/src/test/java/com/sdcuike/dubbo/learning/service

dubbo泛化调用-泛化调用平台 

https://blog.csdn.net/doctor_who2004/article/details/81051226

原文:https://blog.csdn.net/doctor_who2004/article/details/80961426 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
用户指南 入门 背景 需求 架构 用法 快速启动 服务提供者 服务消费者 依赖 必需依赖 缺省依赖 可选依赖 成熟度 功能成熟度 策略成熟度 配置 Xml配置 属性配置 注解配置 API配置 示例 启动时检查 集群容错 负载均衡 线程模型 直连提供者 只订阅 只注册 静态服务 多协议 多注册中心 服务分组 多版本 分组聚合 参数验证 结果缓存 泛化引用 泛化实现 回声测试 上下文信息 隐式传参 异步调用 本地调用 参数回调 事件通知 本地存根 本地伪装 延迟暴露 并发控制 连接控制 延迟连接 粘滞连接 令牌验证 路由规则 配置规则 服务降级 优雅停机 主机绑定 日志适配 访问日志 服务容器 Reference Config缓存 分布式事务13-1-13 U serG uide-zh -D ubbo -A libaba O pen S esam e code.alibabatech.com /w iki/display/dubbo/U ser+G uide-zh#U serG uide-zh-S im ple% E 7% 9B % 91% E 6% κ 2/100 API参考手册 配置API 注解API 模型API 上下文API 服务API 配置参考手册 <dubbo:service/> <dubbo:reference/> <dubbo:protocol/> <dubbo:registry/> <dubbo:monitor/> <dubbo:application/> <dubbo:module/> <dubbo:provider/> <dubbo:consumer/> <dubbo:method/> <dubbo:argument/> <dubbo:parameter/> 协议参考手册 dubbo:// rmi:// hessian:// http:// webservice:// thrift:// memcached:// redis:// 注册中心参考手册 Multicast注册中心 Zookeeper注册中心 Redis注册中心 Simple注册中心 Simple监控中心 Telnet命令参考手册 ls ps cd pwd trace count invoke status log help clear exit Maven插件参考手册 mvn dubbo:registry mvn dubbo:create 服务化最佳实践 分包 粒度 版本 兼容性 枚举值 序列化 异常 调用 推荐用法 容量规划 基准测试工具包 性能测试报告 测试说明 测试环境 测试目的 测试脚本 测试结果 测试分析 测试覆盖率报告

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值