Home > Article > Backend Development > PHPRPC 让 SOA 从梦想成为现实
PHPRPC 让 SOA 从梦想变成现实
SOA 是一种程序设计思想,其实早在远古时代(计算机史)它就已经出现了。无非就是把系统分解,将数据和业务逻辑部分尽量独立出来,然后以服务形式提供给另外的系统共用。
那时也有一些可以实现 SOA 的工具,比如 DCOM、CORBA 等,不过前者仅限于 Windows,后者又太复杂,而且也仅对 C/C++、Delphi、Java 这等语言有较好支持,而且也都是商业开发软件中才会包含,对于开源的脚本类语言来说支持很差甚至没有支持(因为太复杂了,不是什么人都可以实现的了的,能够把整个 CORBA 规范完整读下来,都需要很好的耐心,还不一定都能够完全理解)。之后互联网发展了,XML-RPC 出现了,XML-RPC 很简单,但是也太过简单(因为它只是一个 SOAP 的实验原型而已),简单的数据可以传输,复杂点的就没办法了,所以后来就发展成了 SOAP 这个名字简单实际却很复杂的怪物,尽管 SOAP 已经够复杂了,但它也不过仅仅是定义了数据格式,于是后来就又有了一堆 WS-* 的补充。这样就变得跟 CORBA 一样了,不再是什么人都能理解,什么人都能实现了,或者说除了大公司和大组织有这个能力外,其他人基本上没有这个能力介入。再之后人们突然想发现了宝一样,发现了几年前就被提出来的 REST,于是一堆号称 REST 的服务又出现了,这东西看上去简单,可是实际上却是把数据转换、传输等等问题全都扔给使用者来自行解决了。最后 REST 教父都把这些号称 REST 的服务给否定了。除了这些以外,当然还有其它的方案,比如 Hessian、ICE、Adobe 的基于 AMF3 的通信方案等等,这些不能不说是好的技术,但不是局限于某几种语言,就是局限于某个特定的应用范围。所以要搞 SOA 就需要在这些不同的协议和解决方案之间进行转换,这就出来了 ESB,到这里之后已经看上去很好很强大了。可是它真的可以解决问题吗?真的不是在制造新问题吗?当然它解决了一定的问题,可是同样也制造了更多新问题。能够在各种技术之间转换固然很好,可是本来要掌握这些很复杂的技术中的一种就已经是一件很困难的事了,还要几种都学,几种都要用,这是多大的挑战啊!还有一个问题就是这些协议中本来就有慢的要命的(比如基于 SOAP 的 Web Service),还要再加个转换的过程,那还有什么效率可言。所以,ESB 最后就变成了“哦,傻逼”!SOA 也就变成了听上去很美,做起来很难的东西。
可是实际上我们回过头来再想想,我们要 SOA 到底是想实现什么?不就是要将系统分解,然后异构重组吗?最后问题就这么简单,我们需要的不一定是基于 SOAP 的 Web Service,不一定是将各种协议都能进行转换的 ESB。我们需要的是一种能够在异构系统间可以有效的进行数据交换的技术,这样我们就已经可以构建 SOA 的系统了。别的技术我不敢说,至少目前 PHPRPC 做到了这一点,你不但可以在 Java、.NET 这些语言之间方便的交换数据,还可以跟 PHP、Ruby、Python、Perl 这些开源脚本语言中以同样的方式交换数据,还可以用 Delphi/BCB 来做 Windows 界面的前台,也可以用 JavaScript 做 Web 前台,还可以用 Flash/Flex/RIA/WPF/SilverLight 这些来做内容更丰富的前台,而所有这些前台都可以共享同一个后台,还不需要关心后台究竟用什么语言来实现。甚至手机上的 J2ME、.NET CF、Flash Lite 和手机浏览器的 JavaScript 都可以完美支持。有了 PHPRPC 之后,你就突然就有了这么多选择,甚至随着 PHPRPC 的发展,你还会有更多更多的选择,SOA 从现在开始就不再是遥不可及的梦了。
hessian 对于 在
class xx
{
IList
}
里面的 xxx 一律映射为hashmap..变成 IList
偶的rpcfx对于List Collection一律序列化成Array,
然后加个实际类型的标签~
不知道phprpc怎么处理的~
hessian 对于 在
class xx
{
IList
}
里面的 xxx 一律映射为hashmap..变成 IList
这个是 C# 的吧?C# 的泛型比 Java 的好,可以获取到 xxx 的实际类型,所以在反序列化时,完全按照你声明的类型还原。
hessian 对于 在
class xx
{
IList
}
里面的 xxx 一律映射为hashmap..变成 IList
这个是 C# 的吧?C# 的泛型比 Java 的好,可以获取到 xxx 的实际类型,所以在反序列化时,完全按照你声明的类型还原。
搞错 是 List
不知道phprpc对这种有什么改进。毕竟hashmap性能不好。
我对轻量级的远程调用很感兴趣。想问一下楼主,抛开性能问题,PHPRPC与XML-RPC和Hession/Burlap相比,在功能上主要有哪些优点?
hessian 对于 在
class xx
{
IList
}
里面的 xxx 一律映射为hashmap..变成 IList
偶的rpcfx对于List Collection一律序列化成Array,
然后加个实际类型的标签~
不知道phprpc怎么处理的~
因为Java是擦除式的泛型,所以运行时绝对获取不到泛型的定义xxx类型。
但问题是,通过反射getClass方法不就能得到每个元素的Class类型了么?
hessian 对于 在
class xx
{
IList
}
里面的 xxx 一律映射为hashmap..变成 IList
这个是 C# 的吧?C# 的泛型比 Java 的好,可以获取到 xxx 的实际类型,所以在反序列化时,完全按照你声明的类型还原。
搞错 是 List
不知道phprpc对这种有什么改进。毕竟hashmap性能不好。
那看来是 Java 了,Java 的泛型就没 C# 那么好了(没有运行期类型信息)。因此只有 xxx 是自定义类时,才可以正确处理。其它的如果是容器,应该是 AssocArray,其它基本类型就别用这种泛型容器方式了,直接用数组才能正确转型。
hessian 对于 在
class xx
{
IList
}
里面的 xxx 一律映射为hashmap..变成 IList
偶的rpcfx对于List Collection一律序列化成Array,
然后加个实际类型的标签~
不知道phprpc怎么处理的~
因为Java是擦除式的泛型,所以运行时绝对获取不到泛型的定义xxx类型。
但问题是,通过反射getClass方法不就能得到每个元素的Class类型了么?
hmmm.....上一个项目 客户端用的 c++/cli。那边显示类型就是 hashtable。晚上试试phprpc效果如何。
hessian 对于 在
class xx
{
IList
}
里面的 xxx 一律映射为hashmap..变成 IList
偶的rpcfx对于List Collection一律序列化成Array,
然后加个实际类型的标签~
不知道phprpc怎么处理的~
因为Java是擦除式的泛型,所以运行时绝对获取不到泛型的定义xxx类型。
但问题是,通过反射getClass方法不就能得到每个元素的Class类型了么?
hmmm.....上一个项目 客户端用的 c++/cli。那边显示类型就是 hashtable。晚上试试phprpc效果如何。
我说的运行期,是指序列化程序(Java端)的运行期,不是rpc客户端的运行期。
应该在底层协议上,让SOA摆脱束缚,真正回到 服务和服务集成 的思维上。
应该在底层协议上,让SOA摆脱束缚,真正回到 服务和服务集成 的思维上。
SOA的三个问题这个框架一个都没有解决:
1)怎么非常快速的通过配置把一个Java,Spring,BPEL修改成这种协议?
2)怎么把别人用JMS,WS写好的服务用这种协议去访问?
3)怎么通过这个协议之上的框架把满足相关通信协议的组件形成一个流程
应该在底层协议上,让SOA摆脱束缚,真正回到 服务和服务集成 的思维上。
SOA的三个问题这个框架一个都没有解决:
1)怎么非常快速的通过配置把一个Java,Spring,BPEL修改成这种协议?
2)怎么把别人用JMS,WS写好的服务用这种协议去访问?
3)怎么通过这个协议之上的框架把满足相关通信协议的组件形成一个流程
我试着解答一下
1:写代码。phprpc就是做这个使的
2:还是写代码。既然phprpc可以支持多种语言,你就写java代码去掉jms呗,ws随便你了,用什么语言不行
3:依然是写代码。
1)定义一个类似workflow或者bepl的“流程服务”去封装及这个组件(如果你用java写的,我建议你使用jbpm;如果是多语言的,那你最好暴露出ws接口后用bpel封装),然后在phprpc中写代码调这个“流程服务”就可以了。
2)直接用phprpc一个一个调,然后自己写流程逻辑不就可以了吗。
哈哈,瞎扯的,别当真
另外,我记得还看到有人把Tibico看作是消息队列,我不知道有没有实际使用过Tibico,其实Tibico是一个中间融合剂。上面所谓的系统数据异构转换,完全可以采用Tibico这样的东西来做。Tibico是可以做数据转换与映射的,我觉得在SOA这样的“假、大、空”理论体系中最有用的部分应该就是Tibico这样的东东(IBM也有好像是叫做Interface change server简称ICS)有了这个东西,一开始提出的a1系统的融合就没有问题。比如如果a1使用的是ws,如果要融合,使用Tibico开发一个响应的适配器就可以很方便的进行融合,Tibico这样的东西应该说是屏蔽了协议。
还有,楼主确实不必要将PHPRPC与SOA扯上关系,PHPRPC的目的是什么?我觉得不是为了SOA,PHPRPC有自己的特色有自己的应用场景。
还有一点,我觉得PHPRPC今后的发展应该逐渐转移到使用的易用性,方便性,简洁性上。性能我觉得已经足够强大,不一定作为主要的目的。看看soap在一开始其目的就是面向易用的,使用xml的消息,人人都能看得懂,都能用。
楼主还是需要考虑一下如何将服务的定义能够统一描述,做到类似wsdl一样的定义。毕竟要做服务整合这个还是很有必要的,且还是很有用处的。
说了一堆废话,自己的见解不知道对不对,欢迎拍砖!
SOA已经成为了现实,
现在的问题是能不能让这种现实更美好
PHPRPC 跨语言吗?只是你在不断支持更多语言
在我看来PHPRPC更像一个RPC框架
应该在底层协议上,让SOA摆脱束缚,真正回到 服务和服务集成 的思维上。
SOA的三个问题这个框架一个都没有解决:
1)怎么非常快速的通过配置把一个Java,Spring,BPEL修改成这种协议?
2)怎么把别人用JMS,WS写好的服务用这种协议去访问?
3)怎么通过这个协议之上的框架把满足相关通信协议的组件形成一个流程
JMS是异步的,和WS能放在一起说么?理念和应用场景差异很大的。
应该在底层协议上,让SOA摆脱束缚,真正回到 服务和服务集成 的思维上。
SOA的三个问题这个框架一个都没有解决:
1)怎么非常快速的通过配置把一个Java,Spring,BPEL修改成这种协议?
2)怎么把别人用JMS,WS写好的服务用这种协议去访问?
3)怎么通过这个协议之上的框架把满足相关通信协议的组件形成一个流程
JMS是异步的,和WS能放在一起说么?理念和应用场景差异很大的。
怎么不能放在一起说....是你见识少而已, 没见过什么大的商业产品
譬如说sap的pi就支持这种场景
应该在底层协议上,让SOA摆脱束缚,真正回到 服务和服务集成 的思维上。
SOA的三个问题这个框架一个都没有解决:
1)怎么非常快速的通过配置把一个Java,Spring,BPEL修改成这种协议?
2)怎么把别人用JMS,WS写好的服务用这种协议去访问?
3)怎么通过这个协议之上的框架把满足相关通信协议的组件形成一个流程
JMS是异步的,和WS能放在一起说么?理念和应用场景差异很大的。
怎么不能放在一起说....是你见识少而已, 没见过什么大的商业产品
譬如说sap的pi就支持这种场景
请联系上下文看贴,不要鸡同鸭讲。
我的意思是:PHPRPC又不是异步的,和JMS有什么好比的,是和SOAP(Web Service)比。
我现在就碰到类似困境.在楼主另一篇大作中,我也咨询过.phprpc若能推广,我们都受益,呵呵.
如:
当在客户端取数据时,
List list = user.getList();
数据的确在list内,可通过list.size()知道list的大小,但在访问list内字符串数据时,总是报java.lang.ClassCastException: [B.........
请问一下这是什么原因呢?
我个人认为,应该是客户端根本就不知道服务端返回的list的数据是什么类型(就算知道list服务端传过来的是String List,强行转型也会出错),应该是直接以字节数组的形式传过来的,
那么我要获取list的字符串,是不是要挨过的将每一个字节数组转换成字符串哟,如果真是这样,那传一个自定义对象list
岂不是非常的麻烦。
您的判断非常的正确,确实字符串是以 byte[] 形式返回的,在不能明确获知字符串类型的情况下,字符串和字符数组都是以字节数组的形式表示的。
Java 的泛型只是一个语法糖,所以它的泛型元素类型是无法通过反射来获取的(这点与 .NET 泛型完全不同),因此,Java 的泛型元素类型如果设置为基本类型(包括String)和容器类型的话,则无法正确接收,只有自定义类型对象才可以用泛型容器来接受,因为自定义类型对象在序列化时是包含准确的类型信息的。
不过向这种类型,你可以在客户端通过声明成 String[] 来接收,因为这样就可以获取到元素类型,并自动进行正确的转换。否则,你就只能用非泛型接口(如List)或非泛型类(如ArrayList)接收了,接收之后,对于元素需要用 org.phprpc.util.Cast.cast 方法来进行类型转换。
测试时我也遇到这个情况,作者能解决吗?不然转换很麻烦
如:
当在客户端取数据时,
List list = user.getList();
数据的确在list内,可通过list.size()知道list的大小,但在访问list内字符串数据时,总是报java.lang.ClassCastException: [B.........
请问一下这是什么原因呢?
我个人认为,应该是客户端根本就不知道服务端返回的list的数据是什么类型(就算知道list服务端传过来的是String List,强行转型也会出错),应该是直接以字节数组的形式传过来的,
那么我要获取list的字符串,是不是要挨过的将每一个字节数组转换成字符串哟,如果真是这样,那传一个自定义对象list
岂不是非常的麻烦。
您的判断非常的正确,确实字符串是以 byte[] 形式返回的,在不能明确获知字符串类型的情况下,字符串和字符数组都是以字节数组的形式表示的。
Java 的泛型只是一个语法糖,所以它的泛型元素类型是无法通过反射来获取的(这点与 .NET 泛型完全不同),因此,Java 的泛型元素类型如果设置为基本类型(包括String)和容器类型的话,则无法正确接收,只有自定义类型对象才可以用泛型容器来接受,因为自定义类型对象在序列化时是包含准确的类型信息的。
不过向这种类型,你可以在客户端通过声明成 String[] 来接收,因为这样就可以获取到元素类型,并自动进行正确的转换。否则,你就只能用非泛型接口(如List)或非泛型类(如ArrayList)接收了,接收之后,对于元素需要用 org.phprpc.util.Cast.cast 方法来进行类型转换。
测试时我也遇到这个情况,作者能解决吗?不然转换很麻烦
这个问题产生的原因是PHPRPC所用的序列化格式不能区分二进制字符串和Unicode字符串,所以这个在PHPRPC里是硬伤,没办法修改。不过好消息是,我们的商业开源版软件Hprose中,这个硬伤被解决啦,而且是彻底的解决,所有类型都不需要做类型转化了(甚至连org.phprpc.util.Cast这样的帮助类都不存在了,因为完全不需要了)。Hprose在性能上还有大幅提升,效率是PHPRPC的10几倍,在易用性上也有了更大的改善,如果您有兴趣的话,可以测试一下。