一、HTTP JSON方式的缺点

  1. JSON序列化效率低
  2. 多语言服务治理功能低

二、关于RPC框架

RPC 框架大致分为两类,一种是偏重服务治理,另一种侧重跨语言调用

2.1 服务治理型

特点

功能丰富,提供高性能的远程调用、服务发现及服务治理能力,适用于大型服务的服务解耦及服务治理,对于特定语言(Java)的项目可以实现透明化接入。缺点是语言耦合度较高,跨语言支持难度较大。

常用框架

  • Dubbo
  • Motan

2.2 跨语言调用型

特点

侧重于服务的跨语言调用,能够支持大部分的语言进行语言无关的调用,非常适合多语言调用场景。但这类框架没有服务发现相关机制,实际使用时需要代理层进行请求转发和负载均衡策略控制。

常用框架

  • Thrift
  • gRPC

三、如何提供服务给PHP系统

Dubbo(阿里开源)

3.1 Dubbo + dubbo-php-framework

特点

可以实现php调用php,php调用java(dubbo),java(dubbo)调用php,Java调Java,真正的跨语言

缺点

开发活跃程度极低,社区小,资料少,没有release版本

3.2 Dubbo Restful(合并自Dubbox)

特点

显著简化企业内部的异构系统之间的(跨语言)调用。
服务消费场景:

  1. 非dubbo的消费端调用dubbo的REST服务(non-dubbo --> dubbo)
  2. dubbo消费端调用dubbo的REST服务 (dubbo --> dubbo)
  3. dubbo的消费端调用非dubbo的REST服务 (dubbo --> non-dubbo)
问题
  1. Dubbo REST的服务能和Dubbo注册中心、监控中心集成吗?

    可以的,而且是自动集成的,也就是你在dubbo中开发的所有REST服务都会自动注册到服务册中心和监控中心,可以通过它们做管理。
    但是,只有当REST的消费端也是基于dubbo的时候,注册中心中的许多服务治理操作才能完全起作用。而如果消费端是非dubbo的,自然不受注册中心管理,所以其中很多操作是不会对消费端起作用的。

  2. Dubbo REST中如何实现负载均衡和容错(failover)?

    如果dubbo REST的消费端也是dubbo的,则Dubbo REST和其他dubbo远程调用协议基本完全一样,由dubbo框架透明的在消费端做load balance、failover等等。
    如果dubbo REST的消费端是非dubbo的,甚至是非java的,则最好配置服务提供端的软负载均衡机制,目前可考虑用LVS、HAProxy、 Nginx等等对HTTP请求做负载均衡。

montan(微博开源)

3.3 motan + motan-php

Java系统使用motan提供服务,php系统使用Motan-PHP(PHP client)调用服务。

特点

motan暂不支持以服务注入方式引用yar 服务(使用motan作为yar client)。
目前yar协议主要解决java与php互通的问题,当java作为服务端,php作为client端,php可以在不做任何修改的情况下通过yar 协议使用java的服务。
而使用php做server、java做client的场景下(一般这种场景比较少),php的yar server不支持注册服务等功能,所以java作为client 时也没有必要通过motan调用服务。yarclient是个单独的小模块,是个类似httpclient这样的简易客户端,只能通过域名或ip访问yar服务。

缺点

只支持PHP系统调用Java系统,没有stable release版本,文档很少,社区小,开发活跃程度低。整体不如Dubbo+dubbo-php-framework方式

3.4 motan Restful

模仿Dubbo Restful,很类似,从文档上对比,不如Dubbo Restful

3.5 Client + Agent(还未完全开源)

大概是使用motan + motan-go(agent)等实现。朝着weibo mesh的服务化方向,将 Motan Agent定位为统一服务管理的执行节点。

实现方式

为不同语言提供非常轻量的 Client,只实现与 Agent 的交互和必要的请求序列化能力;提供一个 local 的 Agent 代理,能够提供不同 RPC 协议交互能力,以及统一的服务治理能力与标准,服务治理的绝大部分功能都在语言无关的 Agent 中实现。通过使用 Agent,可以为类似 PHP 这样的解释型语言提供长链接复用能力,提高请求性能。

四、跨语言服务化

阿里Dubbo和微博motan都称自己框架有多语言服务化功能,都在开发中,都还不够成熟

4.1 挑战

HTTP RESTful API

HTTP 本身就是语言无关的协议,一般由服务提供方与使用方通过文档来进行服务约定。这也是目前使用非常广泛的跨语言交互方式,HTTP服务的服务治理能力一般依赖于代理层和服务调用方自己实现,一般代理服务需要单独部署,所有请求流量经由代理服务进行转发。例如使用 nginx 提供基础的负载均衡与流量控制等治理能力就是最简单的跨语言服务治理方案。

HTTP的跨语言服务化,有些方案选择了为特定语言实现强大服务治理能力,对其他语言提供兼容能力,例如Spring Cloud为Java 服务提供完整的服务治理能力,包括服务发现、路由器、过滤器、配置管理、熔断器等等。但很难为不同语言提供统一的服务治理能力,特别是在 Client 侧的一些服务治理能力,不同语言都需要做相同功能的开发。

还有一些方案使用本机代理的方式,例如envoy、linkerd等可以部署到单机的 HTTP 代理服务,在代理服务中集成统一服务发现与治理能力。这种方案能够做到不同语言的Client和 Server 都提供相同的服务治理能力,但服务治理的功能很难做到前一种方案那么强大。

RPC

使用 RPC 作为服务调用方式时,跨语言与服务治理也很难同时满足,对于跨语言型的 RPC 协议,例如 gRPC 等,都能够提供不同语言交互的能力,但是相关的服务治理功能还没有那么完善,做到了’交互’,但还无法做到’治理’。使用跨语言型 RPC 框架时一般会选择使用 HTTP(HTTP2)作为通信协议,这样可以直接应用 HTTP 方式的服务治理功能;

对于服务治理型RPC,由于选择了在 Client 端进行服务发现与治理,如果要实现不同语言统一的服务治理能力,需要在不同语言的一侧都实现相同的功能。实现起来也相当的困难。因此大部分服务治理型 RPC 专注与为特定语言提供完善的治理能力。

4.2 方式

1. 兼容HTTP协议,增加HTTP RESTful协议

例如Dubbo Restful和motan Restful。这种方案将 Java 语言的 RPC 调用方式与其他语言独立开来,只针对 Java Server 端提供,没有为其他语言提供服务治理能力。由于只需要做 Java 协议的开发,这种方案研发和维护成本很低,不过能够提供的统一服务治理能力就很低了。

2. 为不同语言提供RPC模块

例如Dubbo + dubbo-php-framework方式。这种方案能做到最贴近不同语言的使用习惯,可以为不同语言提供完全一致的服务治理能力,不论是作为 Server 端还是 Client 端。但这种方式也是成本最高的,包括开发不同语言的版本,以及后续的功能升级与版本维护代价都非常高。

3. 开发一个 Agent 模块,实现绝大部分的服务治理能力

例如motan Client + Agent方式。Agent在不同服务的Server或Client侧运行。然后为不同语言开发一个很轻量的 Client 与 Agent 进行交互,由于 Client 只实现必要的交互功能,降低了不同语言版本的开发量与维护的成本。

五、可考虑的方案

  1. (如果是JSON效率低)考虑使用Google Protocol Buffers, thrift, Hessian等更高效序列化方式。
  2. (如果是服务治理功能低)保持原来HTTP+JSON方式不变,优化服务治理功能
  3. 自己基于已有开源框架二次开发(参考motan Client + Agent思路)
  4. 使用Dubbo Restful

六、参考资料

  1. 微博轻量级RPC框架Motan正式开源:支撑千亿调用
  2. 微博开源的Motan RPC最新进展:新增跨语言及服务治理支持
  3. 跨语言统一治理、Golang,谈谈另辟蹊径的开源RPC框架Motan
  4. 在Dubbo中开发REST风格的远程调用(RESTful Remoting)
  5. https://github.com/weibocom/motan/issues/186#issuecomment-243055131
  6. 跨语言统一治理、Golang,谈谈另辟蹊径的开源RPC框架Motan

七、其他相关资料

  1. 贝聊系统架构服务化之路
  2. 逆天:蘑菇街下单平台演进,从PHP到Java
  3. 服务化框架技术选型实践
  4. 饿了么分布式服务治理及优化经验
  5. 微博平台的RPC服务化实践
  6. 多语言支持

Java系统和PHP系统相互调用的更多相关文章

  1. java JNI 的实现(2)-java和C/C++的相互调用.

    目录 概述 一,java代码 二,稍微注意通过javah生成的'C/C++'.h头文件和源java代码的关系 三,在C/C++中实现java的native方法(完整C/C++) 1,修改age,即Ja ...

  2. android系统和ios系统是如何实现推送的,ios为什么没有后台推送

    ios系统为什么没有后台推送? iOS 为了真正地为用户体验负责,不允许应用在后台活动.有了这个限制,但是对于终端设备,应用又是有必要“通知”到达用户的,随时与用户主动沟通起来的(典型的如聊天应用). ...

  3. 扫盲--CRM系统和ERP系统的区别

    企业规模在逐步扩大的时候,为了提高生产和管理的效率,经常需要用到相关管理软件.很多企业管理者在选择管理软件的时候犯了难,面对CRM系统和ERP系统不知如何选择无法下手.那么,CRM和ERP的区别是什么 ...

  4. Java(JCo3)与SAP系统相互调用

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  5. Java与.NET的WebServices相互调用

    一:简介 本文介绍了Java与.NET开发的Web Services相互调用的技术.本文包括两个部分,第一部分介绍了如何用.NET做客户端调用Java写的Web Services,第二部分介绍了如何用 ...

  6. java与js交互,相互调用传参

    随着前端技术的发展与H5的广泛使用,移动端采用native+h5的方式越来越多了,对于Android来说就涉及到java与js的交互,相互调用传参等.下面就来看一下java与js交互的简单demo. ...

  7. 对比Linux系统和Windows系统哪个更好

    最近半年来,我一直在读一本叫做<Linux就该这么学>的Linux教材,确实让我进步的很快,也慢慢的让Linux系统走入了我的知识认知中,那么学习前我们来对比下Windows和Linux的 ...

  8. iOS如何兼容的应用程序32位系统和64Bit系统

    苹果发布iPhone5S时刻,64应用程序位去了眼前.当时我看到苹果公布的官方数据iOS7.x的SDK支撑64位应用程序.而内置的应用程序已经64位置. 我记得自己刚刚接触电脑时还有16位的系统,指针 ...

  9. 安装JDK+Eclipse+Maven+Git/Gitee(windows系统和linux系统)

    1. 安装JDK 官网下载 下载java SE 下载 Java SE 7 1.1 windows配置jdk windows配置jdk 1.2 Ubuntu配置jdk Ubuntu 安装 JDK 7 / ...

随机推荐

  1. delphi char数组、string和Pchar的相互转换

    因为要调用windows的api或者给vc++写接口,很多地方都要用到pchar,现在将char数组.string和pchar之间的相互转换都列出来,都是网上找的资料,我总结一下,先直接上代码,再讲原 ...

  2. 浅谈 Web 缓存

    在前端开发中,性能一直都是被大家所重视的一点,然而判断一个网站的性能最直观的就是看网页打开的速度.其中提高网页反应速度的一个方式就是使用缓存.一个优秀的缓存策略可以缩短网页请求资源的距离,减少延迟,并 ...

  3. odoo开发笔记--自定义server action页面跳转注意

    场景描述: 在添加自定义服务器动作 “复制全部”后发现直接创建了新的记录,并且直接进入到form保存完的状态. 如何解决: if yourself_obj_copy: return { 'type': ...

  4. django views视图函数返回值 return redirect httpresponse总结

    django views视图函数返回值 return redirect  render httpresponse总结

  5. How To Scan QRCode For UWP (1)

    本文将介绍实现一个类似于微信扫一扫功能的UI界面,后续会再实现具体的识别二维码的功能. 实例使用的Win10 SDK Version是Windows 10 Anniversary Edition(10 ...

  6. mvc大对象json传输报错

    public ActionResult GetLargeJsonResult() { return new ContentResult { Content = new JavaScriptSerial ...

  7. C++中:默认构造函数、析构函数、拷贝构造函数和赋值函数——转

    对于一个空类,编译器默认产生4个成员函数:默认构造函数.析构函数.拷贝构造函数和赋值函数.1.构造函数:构造函数是一种特殊的类成员,是当创建一个类的时候,它被调用来对类的数据成员进行初始化和分配内存. ...

  8. ES6箭头函数this指向

    普通函数中的this: 1. this总是代表它的直接调用者(js的this是执行上下文), 例如 obj.func ,那么func中的this就是obj 2.在默认情况(非严格模式下,未使用 'us ...

  9. php交叉合并数组

    如数组 array1 = array('a', 'b', 'c');     array2 = array('1', '2', '3'); 希望能实现结果 array3 = array('a', '1 ...

  10. async & await 异步编程小示例,一看就懂

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...