普遍RPC在客户端需要提供接口,如果不提供则无法进行调用。同时,因为客户端也依赖提供的接口,服务端的升级、优化所带来的更新,客户端也要及时的更新API,否则会带来影响。这样,就带来了依赖接口,常常更新API(接口)的麻烦。为了解决这个问题,需要进行泛化调用。

参考RPC
Sofa例子: 具体如下:

根据方法名称得到序列化的类型,例如普通序列化,泛型序列化,混合序列化。我们这里的例子返回的值是 0(普通序列化),然后设置序列化工厂类型,即普通序列化(根据方法名不同而不同)。
从 Request 对象中拿到方法名称,参数类型的字符串,方法参数。并重新设置到 Request 对象中,相当于重新整理了一遍。
然后根据刚刚设置的方法名重新设置调用类型。
ConsumerConfig<GenericService> consumerConfig = new ConsumerConfig<GenericService>()
.setApplication(applicationConfig)
.setInterfaceId(TestGenericService.class.getName())
.setGeneric(true)
.setTimeout(50000)
.setDirectUrl("bolt://127.0.0.1:22222?appName=generic-server");
GenericService testService = consumerConfig.refer();
// 上面这行中,生成GenericService的动态代理类

LOGGER.warn("started at pid {}", RpcRuntimeContext.PID);

while (true) {
try {
String s1 = (String) testService.$invoke("echoStr", new String[] { "java.lang.String" },
new Object[] { "1111" });

public GenericService assembleSofaRPCGenericService(String packageName, String rpcServer) {
ConsumerConfig<GenericService> consumerConfig = new ConsumerConfig<GenericService>()
.setInterfaceId(packageName)
.setGeneric(true)
.setDirectUrl(rpcServer)
.setTimeout(3000);
GenericService proxy = consumerConfig.refer();
return proxy;
}

String packageName1 = "com.test.endpoint.facade.SampleService";
GenericService genericService1 = assembleSofaRPCGenericService(packageName1, "bolt://10.167.24.122:12200");
SofaRPCDataSource sofaRPCDataSource = new SofaRPCDataSource();
sofaRPCDataSource.setGenericBean(genericService1);
pool.put(packageName1, sofaRPCDataSource);
String packageName2 = "com.test.endpoint.facade.SamplePeopleService";
GenericService genericService2 = assembleSofaRPCGenericService(packageName2, "bolt://10.167.24.122:12200");
SofaRPCDataSource sofaRPCDataSource2 = new SofaRPCDataSource();
sofaRPCDataSource2.setGenericBean(genericService2);
pool.put(packageName2, sofaRPCDataSource2);

public Object callSync() {
Object result = genericService.$genericInvoke(${目标方法名}, ${参数类型String串}, ${参数值object串}, Response.class).getContent();
return result;
}
Dubbo例子:

以下几种场景可以考虑使用泛化调用:

服务测试平台
API 服务网关
泛化调用主要用于消费端没有 API 接口的情况;不需要引入接口 jar 包,而是直接通过 GenericService 接口来发起服务调用,参数及返回值中的所有 POJO 均用 Map 表示。泛化调用对于服务端无需关注,按正常服务进行暴露即可。

<dubbo:reference id="userService" interface="com.alibaba.dubbo.samples.generic.api.IUserService" generic="true"/>
// 需要使用的地方,通过强制类型转化为 GenericService 进行调用:
GenericService userService = (GenericService) context.getBean("userService");
// primary param and return value
String name = (String) userService.$invoke("delete", new String[]{int.class.getName()}, new Object[]{1});
System.out.println(name);
其中:

GenericService 这个接口只有一个方法,名为 $invoke,它接受三个参数,分别为方法名、方法参数类型数组和参数值数组;
对于方法参数类型数组
如果是基本类型,如 int 或 long,可以使用 int.class.getName()获取其类型;
如果是基本类型数组,如 int[],则可以使用 int[].class.getName();
如果是 POJO,则直接使用全类名,如 com.alibaba.dubbo.samples.generic.api.Params。
Dubbo 框架会自动将 POJO 的返回值转换成 Map。可以看到,返回值 user 是一个 HashMap,里面分别存放了 name、id、class 三个 k/v。

原理
原理无非就是将泛化调用转化为普通调用,关键在于对象的表示和序列化。

首先,Client会通过动态代理创建GenericService的代理类; 然后,会经过一系列过滤链(优先级排序,默认不需要,大的优先级高)

ConsumerExceptionFilter order =www.mcyulegw.com -20000 RpcReferenceContextFilter order = -19500 ConsumerGenericFilter order = -18000 ConsumerTracerFilter order = -10000 ConsumerInvoker 这里会进行真正的业务的调用

在泛化调用过滤器(ConsumerGenericFilter)中,会进行下列操作:

★设置序列化工厂类型为普通序列化(序列化反序列化均使用SofaSerializerFactory,值为0),并设置到Request参数中。

★进行调用参数($invoke参数)的修正,变成普通的调用参数(调用方法,调用参数类型,调用参数值)

★设置调用类型

最后,使用SOFABolt协议进行进行网络调用。
<form action="staffindex3.php" method=www.michenggw.com "post" enctype="multipart/form-data">//传值方式必须是post
请选择要上传的文件:<input type="file" name="myFile"/><br>
<input type="submit" value="上传"/>
</form>
PHP代码:

session_start();
include 'mysql.php';
//获取图片所有的属性
$filename=$_FILES['myFile']['name'];
$type=$_FILES['myFile'www.18037.cn]['type'];
$tmp_name=$_FILES['myFile']['tmp_name'];
$size=$_FILES['myFile']['size'];
$error=$_FILES['myFile']['error'];
move_uploaded_file($tmp_name,"../goods/".$filename);
$a = "../goods/".$filename;
$filePath = array();//文件路径数组
function traverse($path = '.') {
global $filePath;//得到外部定义的数组
$current_dir = opendir($path); //opendir()返回一个目录句柄,失败返回false
while(($file = readdir($current_dir)) !== false) { //readdir()返回打开目录句柄中的一个条目
$sub_dir www.yisengyule.com= $path . DIRECTORY_SEPARATOR . $file; //构建子目录路径
if($file == '.' || $file == '.www.078881.cn/.') {
continue;
}else if(is_dir($sub_dir)) { //如果是目录,进行递归
// echo 'Directory ' . $file . ':'; //如果是文件夹,输出文件夹名称
traverse(www.shengyue157.com$sub_dir); //嵌套遍历子文件夹
}else{ //如果是文件,直接输出路径和文件名
// echo '../' . $file .'<br/ www.tianjiuyule178.com>';
$filePath[$path . '/' . $file] = '../goods/' .www.iqushipin.com $file;//把文件路径赋值给数组

}
}
return $filePath;
}

$gname=$_POST['name'];
$price=$_POST['price'];
$num=$_POST['num'];
//$_SESSION['uname www.honglanggjpt.cn]=$name;
$name=$_SESSION['uname'];
$array = traverse("D:/wamp/w www.dasheng178.com");
$sql="insert into wait(name,picture,price,num,time,fname) values('$gname','$a','$price','$num',now(),'$name') ";
$res=$res=$db->query($sql);

参考RPC的更多相关文章

  1. Swoole和Swoft的那些事 (Http/Rpc服务篇)

    https://www.jianshu.com/p/4c0f625d5e11 Swoft在PHPer圈中是一个门槛较高的Web框架,不仅仅由于框架本身带来了很多新概念和前沿的设计,还在于Swoft是一 ...

  2. [源码解析] PyTorch 分布式(16) --- 使用异步执行实现批处理 RPC

    [源码解析] PyTorch 分布式(16) --- 使用异步执行实现批处理 RPC 目录 [源码解析] PyTorch 分布式(16) --- 使用异步执行实现批处理 RPC 0x00 摘要 0x0 ...

  3. Flume+Kafka+Storm整合

    Flume+Kafka+Storm整合 1. 需求: 有一个客户端Client可以产生日志信息,我们需要通过Flume获取日志信息,再把该日志信息放入到Kafka的一个Topic:flume-to-k ...

  4. C#以太坊基础入门

    在这一部分,我们将使用C#开发一个最简单的.Net控制台应用,来接入以太坊节点,并打印 所连接节点旳版本信息.通过这一部分的学习,你将掌握以下技能: 如何使用节点仿真器 如何在命令行访问以太坊节点 如 ...

  5. 以太坊 Geth 环境搭建(Ubuntu)

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u014409380/article/details/79897335 时隔多日,我又想起来更新博客, ...

  6. .NET WEB API关键过程 思维导图

    背景说明 近期在去面试的过程中,被问及有关WEB API的一些特性,一时竟不知该如何回答,故根据自己已知的知识,加上网上搜索的,详细列举了一下,期望对WEB API有一个比较开阔和全面的认知. 关键要 ...

  7. OpenStack Trove组件WSGI和RPC调用流程(参考调用的整个过程)

    参考博文:https://blog.csdn.net/bill_xiang_/article/details/72909927

  8. 谈谈如何使用Netty开发实现高性能的RPC服务器

    RPC(Remote Procedure Call Protocol)远程过程调用协议,它是一种通过网络,从远程计算机程序上请求服务,而不必了解底层网络技术的协议.说的再直白一点,就是客户端在不必知道 ...

  9. python通过protobuf实现rpc

    由于项目组现在用的rpc是基于google protobuf rpc协议实现的,所以花了点时间了解下protobuf rpc.rpc对于做分布式系统的人来说肯定不陌生,对于rpc不了解的童鞋可以自行g ...

随机推荐

  1. Two distinct points CodeForces - 1108A (签到)

    You are given two segments [l1;r1][l1;r1] and [l2;r2][l2;r2] on the xx-axis. It is guaranteed that l ...

  2. scrapy框架爬取妹子图片

    首先,建立一个项目#可在github账户下载完整代码:https://github.com/connordb/scrapy-jiandan2 scrapy startproject jiandan2 ...

  3. gin框架学习手册

    前言 gin框架是go语言的一个框架,框架的github地址是:https://github.com/gin-gonic/gin 转载本文,请标注原文地址:https://www.cnblogs.co ...

  4. semantic-ui 下拉框

    注意:在使用semantic的下拉框的时候,不仅需要引入semantic.css,还要引入semantic.js,最重要的是引入jquery.否则下拉效果不会显示. 并且,jquery必须先于sema ...

  5. 13 Connectors: show contrast/oppistion

    1 "but" 和 "yet" 用来显示两个意思之间的对比关系.在写作中,当 "but" 和"yet" 将两个分句连为一 ...

  6. [转帖]SQL Server 索引中include的魅力(具有包含性列的索引)

    SQL Server 索引中include的魅力(具有包含性列的索引) http://www.cnblogs.com/gaizai/archive/2010/01/11/1644358.html 上个 ...

  7. css特殊样式

    span{ color: blue; border:1px solid black;}.extra span{ color: inherit;} 清除原有样式 text-decoration: non ...

  8. VMWARE中NAT下获取不到IP

    1.编辑-虚拟网络编辑器-dhcp设置 2.虚拟机-可移动设备-网络适配器-设置,注意:这里一定要选nat,当初我就是选了桥接,死活上不去,搞了2个小时.

  9. Kettle 变量(arg位置参数)

    1.表输入中使用?占位作为kettle转换变量 数据预览: 获取变量数据: 使用?传入变量 需要勾选替换sql语句中的变量,并选则从步骤插入数据中所在步骤 数据预览

  10. Django--CRM--菜单展示, 删除合并, 权限展示

    一 . 菜单展示 二 . 合并删除 我们可以把所有的删除都合并成一个函数这样就会减少很多的代码. 思路: 在url里面需要传两个参数,一个是要删的id 一个是名字 三 .权限展示 我们要实现两个功能 ...