泛化调用,针对消费端不是标准的注入了服务端的,可以直接在消费端用泛化的方式处理,类似直接用resttemplate基于url调用---类似springcloud的sidecar
注入服务的是注入的时候就反射生产服务,泛化是在请求url到了之后临时根据接口,方法,参数,反射调用
当后端Java服务用Dubbo协议作为RPC方案的基础,但部分消费方是前端Restful的PHP服务,不能直接调用,于是在中间架设了Router服务提供统一的基于HTTP的后端调用入口。
而Router调用后端Java服务就应用了Dubbo的高级特性–泛化调用
- 直接消费方(Router服务)不需要引入接口jar包
- 通过GenericService接口来处理所有服务请求
- 以PHP到Router的request body中的方法名和方法参数作为Router远程调用后端Java服务的入参,最后将远程调用的result返回给PHP端
本文将用一个小Demo来演示上面所述的泛化调用应用场景
零.Dubbo简介
DUBBO是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,是阿里巴巴SOA服务化治理方案的核心框架,每天为2,000+个服务提供3,000,000,000+次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点。
– Dubbo官方描述Dubbo能做什么:
- 透明化的远程方法调用
- 就像调用本地方法一样调用远程方法
- 只需简单配置,没有任何API侵入。
- 软负载均衡及容错机制
- 可在内网替代F5等硬件负载均衡器
- 服务自动注册与发现
- 不再需要写死服务提供方地址,注册中心基于接口名查询服务提 供者的IP地址,并且能够平滑添加或删除服务提供者
– 《Dubbo功能介绍》(官方资料)
注:Dubbo的基本使用介绍不在本文范畴,如有需要请自行参考官方资料
泛接口调用方式主要用于客户端没有API接口及模型类元的情况,参数及返回值中的所有POJO均用Map表示,通常用于框架集成,比如:实现一个通用的服务测试框架,可通过GenericService调用所有服务实现。
– Dubbo用户指南
一.后端API
public interface UserInfoService {
public Map<String, String> getUser(String id);
public Map<String, String>[] getUsers();
}
二.Router端dubbo配置
dubboconf.properties:
application.name=router
registry.address=zookeeper://address1?buckup=address2,address3
三.前端服务post到Router的Request Body示例:
{
"interfaceName": "foo",
"methodName": "bar",
"methodParams": [
{
"id": "xxx"
}
]
}
四.处理前端参数用的Dto
RequestDto.java:
import java.util.Map;
/**
* Created by Luo
*/
public class RequestDto {
private String interfaceName;
private String methodName
private Map[] methodParams;
public String getInterfaceName() {
return interfaceName;
}
public void setInterfaceName(String interfaceName) {
this.interfaceName = interfaceName;
}
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
public Map[] getMethodParams() {
return methodParams;
}
public void setMethodParam(Map[] methodParams) {
this.methodParams = methodParams;
}
}
五.Router服务入口
RouterController.java:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by Luo
*/
@RestController
public class App {
@RequestMapping(value = "/router/", method = RequestMethod.POST)
public Object getUser(@ModelAttribute RequestDto dto) {
Map map = new HashMap<>();
map.put("ParamType", "java.lang.String"); //后端接口参数类型
map.put("Object", dto.getMethodParams()[0].get("id")); //用以调用后端接口的实参
List<Map<String, Object>> paramInfos= new ArrayList<>();
paramInfos.add(map);
DubboServiceFactory dubbo = DubboServiceFactory.getInstance();
return dubbo.genericInvoke(dto.getInterfaceName(), dto.getMethodName(), paramInfos);
}
}
注:本文旨在演示泛化调用的一种应用方式,为简明起见,代码中直接从dto中获取了指定参数,而并没有完整实现其路由功能,望见谅。
六.通过GenericService进行泛化调用
DubboServiceFactory.java
package local.demo.genericservice;
import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ReferenceConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.utils.ReferenceConfigCache;
import com.alibaba.dubbo.rpc.service.GenericService;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Properties;
/**
* Created by Luo
*/
public class DubboServiceFactory {
private ApplicationConfig application;
private RegistryConfig registry;
private static class SingletonHolder {
private static DubboServiceFactory INSTANCE = new DubboServiceFactory();
}
private DubboServiceFactory(){
Properties prop = new Properties();
ClassLoader loader = DubboServiceFactory.class.getClassLoader();
try {
prop.load(loader.getResourceAsStream("dubboconf.properties"));
} catch (IOException e) {
e.printStackTrace();
}
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName(prop.getProperty("application.name"));
//这里配置了dubbo的application信息*(demo只配置了name)*,因此demo没有额外的dubbo.xml配置文件
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setAddress(prop.getProperty("registry.address"));
//这里配置dubbo的注册中心信息,因此demo没有额外的dubbo.xml配置文件
this.application = applicationConfig;
this.registry = registryConfig;
}
public static DubboServiceFactory getInstance() {
return SingletonHolder.INSTANCE;
}
public Object genericInvoke(String interfaceClass, String methodName, List<Map<String, Object>> parameters){
ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>();
reference.setApplication(application);
reference.setRegistry(registry);
reference.setInterface(interfaceClass); // 接口名
reference.setGeneric(true); // 声明为泛化接口
//ReferenceConfig实例很重,封装了与注册中心的连接以及与提供者的连接,
//需要缓存,否则重复生成ReferenceConfig可能造成性能问题并且会有内存和连接泄漏。
//API方式编程时,容易忽略此问题。
//这里使用dubbo内置的简单缓存工具类进行缓存
ReferenceConfigCache cache = ReferenceConfigCache.getCache();
GenericService genericService = cache.get(reference);
// 用com.alibaba.dubbo.rpc.service.GenericService可以替代所有接口引用
int len = parameters.size();
String[] invokeParamTyeps = new String[len];
Object[] invokeParams = new Object[len];
for(int i = 0; i < len; i++){
invokeParamTyeps[i] = parameters.get(i).get("ParamType") + "";
invokeParams[i] = parameters.get(i).get("Object");
}
return genericService.$invoke(methodName, invokeParamTyeps, invokeParams);
}
}
七.部署
将Router部署到Jetty/Tomcat等容器,或者直接使用SpringBoot开发,发布为内嵌Jetty/Tomcat的独立jar包,即可向前端服务提供服务。
相关推荐
。。。
。。。
dubbo泛化的简单应用
Dubbo服务者,消费者,接口API基础结构 项目说明 provider为项目服务者(支持mysql和redis) 消费者为消费者(springboot的war包内置方式) 通过Dubbo通信,projectAPI统一接口定义
泛化调用 12、监控 Opentracing API Prometheus 13、Tracing For jsonrpc For dubbo For grpc 14、元数据中心 Nacos Zookeeper Etcd Consul 15、服务发现 Nacos Zookeeper Etcd 16、其他功能支持: 启动时检查 服务直...
一款Apache Dubbo漏洞检测工具。包含了信息收集、参数爆破等功能,利用获取到的信息一键完成对Dubbo的Provider和Consumer的漏洞利用...修改目标的检测类代码,从而在发起新的泛化调用时,执行用户指定的任意命令并回显
用户指南 ...服务化最佳实践 分包 粒度 版本 兼容性 枚举值 序列化 异常 调用 推荐用法 容量规划 基准测试工具包 性能测试报告 测试说明 测试环境 测试目的 测试脚本 测试结果 测试分析 测试覆盖率报告
+ Dubbo泛化调用的地址为一致性哈希负载均衡算法计算所得 + 解决了自定义协议在传输中导致的粘包、拆包问题 + 群聊批量ACK处理,避免因创建过多的超时计时器导致的压力过大 + 利用leaf-sno 【备注】 1、该资源内项目...
RPC是一个泛化的概念,严格来说一切远程过程调用手段都属于RPC范畴。各种开发语言都有自己的RPC框架。Java中的RPC框架比较多,广泛使用的有RMI、Hessian、Dubbo等。 Dubbo官网地址:http://dubbo.apache.org Dubbo...
上堂课回顾1、异步调用 ---- future模式2、事件机制 --- 异步回调3、回声测试 --- 服务就绪清单4、泛化调用 -- 不通过接口类: 救急5、d
给大家讲解什么是dubbo,dubbo用来解决什么问题,如何使用Dubbo在目前主流的三种环境下搭建一个分布式系统,为后面篇源码剖析做准备,如何搭建dubbo服务治理平台,Dubbo中服务泛化与异步调用概念与使用,谈谈作者在使用...
理论上并发数量接近服务器带宽,客户端采用thrift协议,服务端支持netty和thrift的TThreadedSelectorServer半同步半异步线程模型,支持动态扩容,服务上下线,权重动态,可用性配置,泛化调用,页面流量统计,泛化...
1:为什么要写这个RPC市面上常见的RPC框架很多,grpc,motan,dubbo等,但是随着越来越多的元素加入,复杂的架构设计等因素似使得这些框架和spring一样,虽然号称是轻量级,但是用起来却是让我们很蹩脚,大量的配置...
支持同步、单向、回调、泛化等多种调用方式 支持集群容错、服务预热、自动故障隔离 强大的扩展功能,可以按需扩展各个功能组件 关联项目 sofa-rpc-boot-project SOFABoot 扩展项目,包括 starter 工程及使用示例。...
支持同步、单向、回调、泛化等多种调用方式 支持集群容错、服务预热、自动故障隔离 强大的扩展功能,可以按需扩展各个功能组件 需要 编译需要 JDK 8 及以上、Maven 3.2.5 及以上。 运行需求 JDK 8 及以上。
支持同步、单向、回调、泛化等多种调用方式 支持集群容错、服务预热、自动故障隔离 强大的扩展功能,可以按需扩展各个功能组件 开发环境支持 1、编译需要 JDK 7 及以上、Maven 3.2.5 及以上 2、运行需求 JDK 6 及...