微服务框架(四)Dubbo泛化调用实现

简介:   此系列文章将会描述Java框架Spring Boot、服务治理框架Dubbo、应用容器引擎Docker,及使用Spring Boot集成Dubbo、Mybatis等开源框架,其中穿插着Spring Boot中日志切面等技术的实现,然后通过gitlab-CI以持续集成为Docker镜像。   本文为服务治理框架Dubbo泛化调用的实现

  此系列文章将会描述Java框架Spring Boot、服务治理框架Dubbo、应用容器引擎Docker,及使用Spring Boot集成Dubbo、Mybatis等开源框架,其中穿插着Spring Boot中日志切面等技术的实现,然后通过gitlab-CI以持续集成为Docker镜像。
  本文为服务治理框架Dubbo泛化调用的实现

本系列文章中所使用的框架版本为Spring Boot 2.0.3-RELEASE,Spring 5.0.7-RELEASE,Dubbo 2.6.2。

泛化调用组件

Dubbo一般在内部系统间,通过RPC调用,正常情况下服务消费方需要导入服务提供skeleton的jar包,根据此接口编写服务消费者

为了便于开发及测试,实现泛化调用功能,即使用Controller封装请求,获取对应的服务,转接为RPC调用

泛化调用组件依赖需添加对应服务接口的jar包

控制器

1.获取泛化服务接口
2.组装服务调用参数
3. 调用接口、封装数据

@RestController
@RequestMapping(value = "/")
public class GenericController {
   
   

    @RequestMapping(value = "/generic", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE,
            produces = MediaType.APPLICATION_JSON_UTF8_VALUE,
            method = {
   
   RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    public Object call(@ModelAttribute("reqModel") GenericReqModel reqModel) throws ClassNotFoundException {
   
   
        Object result = null;

        // 1.获取泛化服务接口
        GenericService service = DubboUtils.fetchGenericService(reqModel);

        // 2.组装调用参数
        String method = reqModel.getMethod();

        String[] parameterTypes = DubboUtils.getMethodParamType(
                reqModel.getService(), reqModel.getMethod());

        Object[] args = JSON.parseArray(reqModel.getParamValues()).toArray(
                new Object[] {
   
   });

        // 3.调用接口
        return JSON.toJSONString(service
                .$invoke(method, parameterTypes, args));
    }

}

泛化引用接口

Dubbo支持的泛化引用接口,可通过在 Spring Boot 配置申明 generic="true"使用,详见泛化引用

在此组件中无需配置即可使用

xml

<dubbo:reference id="barService" interface="com.foo.BarService" generic="true" />

Properties

dubbo.reference.generic = true

接口定义:

package com.alibaba.dubbo.rpc.service;

/**
 * Generic service interface
 *
 * @export
 */
public interface GenericService {
   
   

    /**
     * Generic invocation
     *
     * @param method         Method name, e.g. findPerson. If there are overridden methods, parameter info is
     *                       required, e.g. findPerson(java.lang.String)
     * @param parameterTypes Parameter types
     * @param args           Arguments
     * @return invocation return value
     * @throws Throwable potential exception thrown from the invocation
     */
    Object $invoke(String method, String[] parameterTypes, Object[] args) throws GenericException;

}

工具类

DubboUtils:

  1. fetchGenericService:获取泛化引用接口(如有缓存, 则从缓存取)
  2. getMethodParamType:根据接口类名及方法名通过反射获取参数类型
public class DubboUtils {
   
   

    private static Logger logger = LoggerFactory.getLogger(DubboUtils.class);

    private static ApplicationConfig application = new ApplicationConfig(
            "generic-reference");

    private static Map<String, GenericService> serviceCache = Maps.newConcurrentMap();

    /**
     * 获取泛化服务接口(如有缓存, 则从缓存取)
     * @param reqModel
     * @return
     */
    public static GenericService fetchGenericService(GenericReqModel reqModel) {
   
   
        // 参数设置
        String serviceInterface = reqModel.getService();
        String serviceGroup = reqModel.getGroup();
        String serviceVersion = reqModel.getVersion();

        // 从缓存中获取服务
        String serviceCacheKey = serviceInterface + "-" + serviceGroup + "-"
                + serviceVersion;
        GenericService service = serviceCache.get(serviceCacheKey);
        if (service != null) {
   
   
            logger.info("fetched generic service from cache");
            return service;
        }

        // 配置调用信息
        ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>();
        reference.setApplication(application);
        reference.setInterface(serviceInterface);
        reference.setGroup(serviceGroup);
        reference.setVersion(serviceVersion);
        reference.setGeneric(true); // 声明为泛化接口

        // 获取对应服务
        service = reference.get();

        // 缓存
        serviceCache.put(serviceCacheKey, service);

        return service;
    }

    /**
     * 根据接口类名及方法名通过反射获取参数类型
     * 
     * @param interfaceName 接口名
     * @param methodName    方法名
     * @return
     * @throws ClassNotFoundException
     */
    public static String[] getMethodParamType(String interfaceName,
            String methodName) throws ClassNotFoundException {
   
   
        String[] paramTypeList = null;

        // 创建类
        Class<?> clazz = Class.forName(interfaceName);
        // 获取所有的公共的方法
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
   
   
            if (method.getName().equals(methodName)) {
   
   

                Class<?>[] paramClassList = method.getParameterTypes();
                paramTypeList = new String[paramClassList.length];

                int i = 0;
                for (Class<?> className : paramClassList) {
   
   
                    paramTypeList[i] = className.getTypeName();
                    i++;
                }
                break;
            }
        }

        return paramTypeList;
    }
}

启动器

若要使用不同的Web容器,需引入对应的Spring Boot启动依赖,e.g

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jetty</artifactId>
    <version>2.0.3.RELEASE</version>
</dependency>

项目使用Web容器启动

@SpringBootApplication(scanBasePackages = "com.spring.boot.generic.controller")
public class Starter {
   
   

    public static void main(String[] args) {
   
   

        new SpringApplicationBuilder(Starter.class)
            .web(WebApplicationType.SERVLET)
            .run(args);

    }

}

请求模型

public class GenericReqModel implements Serializable {
   
   

    /**
     * 
     */
    private static final long serialVersionUID = -7389007812411509827L;

    private String registry; // 注册中心地址
    private String service; // 服务包下类名
    private String version; // 版本
    private String group; // 服务组
    private String method; // 方法名
    private String paramTypes; // 参数类型
    private String paramValues; // 参数值

    setter/getter
}

POSTMAN使用方法

1.Headers配置

Key Value
Content-Type application/json

2.参数配置(Params)

Key Value
registry zookeeper://localhost
service
version 1.0.0
group
method getWord
paramValues [{}]

3.调用示例

在这里插入图片描述


源码:GitHub

相关文章
|
3月前
|
Dubbo Java 应用服务中间件
Spring Cloud Dubbo:微服务通信的高效解决方案
【10月更文挑战第15天】随着信息技术的发展,微服务架构成为企业应用开发的主流。Spring Cloud Dubbo结合了Dubbo的高性能RPC和Spring Cloud的生态系统,提供高效、稳定的微服务通信解决方案。它支持多种通信协议,具备服务注册与发现、负载均衡及容错机制,简化了服务调用的复杂性,使开发者能更专注于业务逻辑的实现。
80 2
|
3月前
|
XML JSON API
ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
172 3
|
4月前
|
安全 应用服务中间件 API
微服务分布式系统架构之zookeeper与dubbo-2
微服务分布式系统架构之zookeeper与dubbo-2
|
2月前
|
Dubbo Cloud Native 应用服务中间件
阿里云的 Dubbo 和 Nacos 深度整合,提供了高效的服务注册与发现、配置管理等关键功能,简化了微服务治理,提升了系统的灵活性和可靠性。
在云原生时代,微服务架构成为主流。阿里云的 Dubbo 和 Nacos 深度整合,提供了高效的服务注册与发现、配置管理等关键功能,简化了微服务治理,提升了系统的灵活性和可靠性。示例代码展示了如何在项目中实现两者的整合,通过 Nacos 动态调整服务状态和配置,适应多变的业务需求。
51 2
|
2月前
|
分布式计算 Java 持续交付
如何选择合适的微服务框架
如何选择合适的微服务框架
35 0
|
3月前
|
Dubbo Java 应用服务中间件
Dubbo学习圣经:从入门到精通 Dubbo3.0 + SpringCloud Alibaba 微服务基础框架
尼恩团队的15大技术圣经,旨在帮助开发者系统化、体系化地掌握核心技术,提升技术实力,从而在面试和工作中脱颖而出。本文介绍了如何使用Dubbo3.0与Spring Cloud Gateway进行整合,解决传统Dubbo架构缺乏HTTP入口的问题,实现高性能的微服务网关。
|
4月前
|
Dubbo 应用服务中间件 Apache
Star 4w+,Apache Dubbo 3.3 全新发布,Triple X 领衔,开启微服务通信新时代
在 Apache Dubbo 突破 4w Star 之际,Apache Dubbo 团队正式宣布,Dubbo 3.3 正式发布!作为全球领先的开源微服务框架,Dubbo 一直致力于为开发者提供高性能、可扩展且灵活的分布式服务解决方案。此次发布的 Dubbo 3.3,通过 Triple X 的全新升级,突破了以往局限,实现了对南北向与东西向流量的全面支持,并提升了对云原生架构的友好性。
158 12
|
4月前
|
负载均衡 Dubbo NoSQL
Dubbo框架的1个核心设计点
Java领域要说让我最服气的RPC框架当属Dubbo,原因有许多,但是最吸引我的还是它把远程调用这个事情设计得很有艺术。
Dubbo框架的1个核心设计点
|
4月前
|
负载均衡 监控 Dubbo
分布式框架-dubbo
分布式框架-dubbo
|
4月前
|
Kubernetes Java Android开发
用 Quarkus 框架优化 Java 微服务架构的设计与实现
Quarkus 是专为 GraalVM 和 OpenJDK HotSpot 设计的 Kubernetes Native Java 框架,提供快速启动、低内存占用及高效开发体验,显著优化了 Java 在微服务架构中的表现。它采用提前编译和懒加载技术实现毫秒级启动,通过优化类加载机制降低内存消耗,并支持多种技术和框架集成,如 Kubernetes、Docker 及 Eclipse MicroProfile,助力开发者轻松构建强大微服务应用。例如,在电商场景中,可利用 Quarkus 快速搭建商品管理和订单管理等微服务,提升系统响应速度与稳定性。
108 5

热门文章

最新文章