首页 » 网站建设 » apachethriftphp技巧_架构设计系统间通信11RPC实例ApacheThrift

apachethriftphp技巧_架构设计系统间通信11RPC实例ApacheThrift

duote123 2024-11-27 0

扫一扫用手机浏览

文章目录 [+]

为了支持多种措辞,Apache Thrift有一套自己的接口定义措辞,并且通过Apache Thrift的代码天生程序,能够天生各种编程措辞的代码。
这样是担保各种措辞进行通讯的条件条件。
为了能够实现大略的Apache Thrift实例,首先我们就须要讲解一下Apache Thrift的IDL。

2-1、Thrift代码天生程序安装

如果您是在windows环境下运行进行Apache Thrift的试验,那么您无需安装任何工具,直接下载Apache Thrift在windows下的代码天生程序http://www.apache.org/dyn/closer.cgi?path=/thrift/0.9.3/thrift-0.9.3.exe(在这篇文章写作时,利用的是Apache Thrift的0.9.3版本);如果您运行在Linux系统下,那么下载http://www.apache.org/dyn/closer.cgi?path=/thrift/0.9.3/thrift-0.9.3.tar.gz,并进行编译、安装(过程很大略,这里就不再赘述了)。
安装后记得添加运行位置到环境变量中。

apachethriftphp技巧_架构设计系统间通信11RPC实例ApacheThrift

2-2、IDL格式概要

以下是一个大略的IDL文件定义:

apachethriftphp技巧_架构设计系统间通信11RPC实例ApacheThrift
(图片来自网络侵删)

# 命名空间的定义 把稳‘java’的关键字namespace java testThrift.iface# 构造体定义struct Request { 1:required string paramJSON; 2:required string serviceName;}# 另一个构造体定义struct Reponse { 1:required RESCODE responeCode; 2:required string responseJSON;}# 非常描述定义exception ServiceException { 1:required EXCCODE exceptionCode; 2:required string exceptionMess;}# 列举定义enum RESCODE { _200=200; _500=500; _400=400;}# 另一个列举enum EXCCODE { PARAMNOTFOUND = 2001; SERVICENOTFOUND = 2002;}# 做事定义service HelloWorldService { Reponse send(1:Request request) throws (1:ServiceException e);}

以上IDL文件是可以直接用来天生各种措辞的代码的。
下面给出常用的各种不同措辞的代码天生命令:

# 天生javathrift-0.9.3 -gen java ./demoHello.thrift# 天生c++thrift-0.9.3 -gen cpp ./demoHello.thrift# 天生phpthrift-0.9.3 -gen php ./demoHello.thrift# 天生node.jsthrift-0.9.3 -gen js:node ./demoHello.thrift# 天生c#thrift-0.9.3 -gen csharp ./demoHello.thrift# 您可以通过以下命令查看天生命令的格式thrift-0.9.3 -help12345678910111213141516172-2-1、基本类型

基本类型便是:不管哪一种措辞,都支持的数据形式表现。
Apache Thrift中支持以下几种基本类型:

bool: 布尔值 (true or false), one bytebyte: 有符号字节i16: 16位有符号整型i32: 32位有符号整型i64: 64位有符号整型double: 64位浮点型string: 字符串/字符数组binary: 二进制数据(在java中表现为java.nio.ByteBuffer)2-2-2、struct构造

在面向工具措辞中,表现为“类定义”;在弱类型措辞、动态措辞中,表现为“构造/构造体”。
定义格式如下:

struct <构造体名称> { <序号>:[字段性子] <字段类型> <字段名称> [= <默认值>] [;|,]}

实例:

struct Request { 1:required binary paramJSON; 2:required string serviceName 3:optional i32 field1 = 0; 4:optional i64 field2, 5: list<map<string , string>> fields3} 构造体名称:可以按照您的业务需求,给定不同的名称(区分大小写)。
但是要把稳,一组IDL定义文件中构造体名称不能重复,且不能利用IDL已经占用的关键字(例如required 、struct 等单词)。
序号:序号非常主要。
正整数,按照顺序排列利用。
这个属性在Apache Thrift进行序列化的时候被利用。
字段性子:包括两种关键字:required 和 optional,如果您不指定,那么系统会默认为required。
required表示这个字段必须有值,并且Apache Thrift在进行序列化时,这个字段都会被序列化;optional表示这个字段不一定有值,且Apache Thrift在进行序列化时,这个字段只有有值的情形下才会被序列化。
字段类型:在struct中,字段类型可以是某一个根本类型,也可以是某一个之前定义好的struct,还可以是某种Apache Thrift支持的容器(set、map、list),还可以是定义好的列举。
字段的类型是必须指定的。
字段名称:字段名称区分大小写,不能重复,且不能利用IDL已经占用的关键字(例如required 、struct 等单词)。
默认值:您可以为某一个字段指定默认值(也可以不指定)。
结束符:在struct中,支持两种结束符,您可以利用“;”或者“,”。
当然您也可以不该用结束符(Apache Thrift代码天生程序,会自己识别到)2-2-3、containers凑集/容器

Apache Thrift支持三种类型的容器,容器在各种编程措辞中普遍存在:

list< T >:有序列表(JAVA中表现为ArrayList),T可以是某种根本类型,也可以是某一个之前定义好的struct,还可以是某种Apache Thrift支持的容器(set、map、list),还可以是定义好的列举。
有序列表中的元素许可重复。
set< T >:无序元素凑集(JAVA中表现为HashSet),T可以是某种根本类型,也可以是某一个之前定义好的struct,还可以是某种Apache Thrift支持的容器(set、map、list),还可以是定义好的列举。
无序元素凑集中的元素不许可重复,一旦重复后一个元素将覆盖前一个元素。
map2-2-4、enmu列举

enum <列举名称> { <列举字段名> = <列举值>[;|,]}123

示例如下:

enum RESCODE { _200=200; _500=500; _400=400;}123452-2-5、常量定义

Apache Thrift许可定义常量。
常量的关键字为“const”,常量的类型可以是Apache Thrift的根本类型,也可以是某一个之前定义好的struct,还可以是某种Apache Thrift支持的容器(set、map、list),还可以是定义好的列举。
示例如下:

const i32 MY_INT_CONST = 111111; const i64 MY_LONG_CONST = 11111122222222333333334444444;const RESCODE MY_RESCODE = RESCODE._200;123452-2-6、exception 非常

Apache Thrift的exception,紧张在定义做事接口时利用。
其定义办法类似于struct(您可以理解成,把struct关键字换成exception关键字即可),示例如下:

exception ServiceException { 1:required EXCCODE exceptionCode; 2:required string exceptionMess;}12342-2-7、service 做事接口

Apache Thrift中最主要的IDL定义之一。
在后续的代码天生阶段,通过IDL定义的这些做事将构成Apache Thrift客户端调用Apache Thrift做事真个基本远端过程。
service做事接口的定义形式如下所示:

service <做事名称> { <void | 返回指类型> <做事方法名>([<入参序号>:[required | optional] <参数类型> <参数名> ...]) [throws ([<非常序号>:[required | optional] <非常类型> <非常参数名>...])]}123做事名称:做事名可以按照您的业务需求自行制订,把稳做事名是区分大小写的。
IDL中做事名称只有两个限定,便是不能重复利用相同的名称,不能利用IDL已经占用的关键字(例如required 、struct 等单词)。
返回值类型:如果这个调用方法没有返回类型,那么可以关键字“void”; 可以是Apache Thrift的根本类型,也可以是某一个之前定义好的struct,还可以是某种Apache Thrift支持的容器(set、map、list),还可以是定义好的列举。
做事方法名:做事方法名可以根据您的业务需求自定制订,把稳区分大小写。
在同一个做事中,不能重复利用一个做事方法名命名多个方法(一定要把稳),不能利用IDL已经占用的关键字。
做事方法参数:<入参序号>:[required | optional] <参数类型> <参数名>。
把稳和struct中的字段定义相似,可以指定required或者optional;如果不指定则系统默认为required 。
如果一个做事方法中有多个参数名,那么这些参数名称不能重复。
做事方法非常:throws ([<非常序号>:[required | optional] <非常类型> <非常参数名>。
throws关键字是做事方法非常定义的开始点。
在throws关键字后面,可以定义1个或者多个不同的非常类型。

Apache Thrift做事定义的示例如下:

service HelloWorldService { Reponse send(1:Request request) throws (1:ServiceException e);}1232-2-8、namespace命名空间

Apache Thrift支持为不同措辞制订不同的命名空间:

namespace java testThrift.ifacenamespace php testThrift.ifacenamespace cpp testThrift.iface123452-2-9、注释

Apache Thrift 支持多种风格的注释。
这是为了适应不同措辞背景的开拓者:

/ 注释办法1:/// 注释办法2# 注释办法312345672-2-10、include关键字

如果您的全体工程中有多个IDL定义文件(IDL定义文件的文件名可以随便取)。
那么您可以利用include关键字,在IDL定义文件A中,引入一个其他的IDL文件:

include "other.thrift"1

请把稳,一定利用双引号(不要用成中文的双引号咯),并且不该用“;”或者“,”结束符。

以上便是IDL基本的语法了,由于篇幅缘故原由不可能把每种语法、每一个细节都讲到,但是以上的语法要点已经足够您编辑一个适应业务的,灵巧的IDL定义了。
如果您须要理解更详细的Thrift IDL语法,可以参考官方文档的讲述:http://thrift.apache.org/docs/idl

2-3、最大略的Thrift代码定义Thrift中业务接口HelloWorldService.Iface的实现:

package testThrift.impl;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.apache.thrift.TException;import testThrift.iface.HelloWorldService.Iface;import testThrift.iface.RESCODE;import testThrift.iface.Reponse;import testThrift.iface.Request;/ 我们定义了一个HelloWorldService.Iface接口的详细实现。
<br> 把稳,这个父级接口:HelloWorldService.Iface,是由thrift的代码天生工具天生的<br> 要运行这段代码,请导入maven-log4j的支持。
否则修正LOGGER.info方法 @author yinwenjie /public class HelloWorldServiceImpl implements Iface { / 日志 / private static final Log LOGGER = LogFactory.getLog(HelloWorldServiceImpl.class); / 在接口定义中,只有一个方法须要实现。
<br> HelloWorldServiceImpl.send(Request request) throws TException <br> 您可以理解成这个接口的方法接管客户真个一个Request工具,并且在处理完成后向客户端返回一个Reponse工具<br> Request工具和Reponse工具都是由IDL定义的构造,并通过“代码天生工具”天生相应的JAVA代码。
/ @Override public Reponse send(Request request) throws TException { / 这里便是进行详细的业务处理了。
/ String json = request.getParamJSON(); String serviceName = request.getServiceName(); HelloWorldServiceImpl.LOGGER.info("得到的json:" + json + " ;得到的serviceName: " + serviceName); // 布局返复书息 Reponse response = new Reponse(); response.setResponeCode(RESCODE._200); response.setResponseJSON("{\"user\":\"yinwenjie\"}"); return response; } }

各位可以看到,上面一段代码中详细业务和过程和普通的业务代码没有任何差异。
乃至这段代码的实现都不知道自己将被Apache Thrift框架中的客户端调用。

然后我们开始书写Apache Thrift的做事器端代码:

package testThrift.man;import java.util.concurrent.Executors;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.apache.log4j.BasicConfigurator;import org.apache.thrift.TProcessor;import org.apache.thrift.protocol.TBinaryProtocol;import org.apache.thrift.server.TThreadPoolServer;import org.apache.thrift.server.TThreadPoolServer.Args;import org.apache.thrift.transport.TServerSocket;import testThrift.iface.HelloWorldService;import testThrift.iface.HelloWorldService.Iface;import testThrift.impl.HelloWorldServiceImpl;public class HelloBoServerDemo { static { BasicConfigurator.configure(); } / 日志 / private static final Log LOGGER =LogFactory.getLog(HelloBoServerDemo.class); public static final int SERVER_PORT = 9111; public void startServer() { try { HelloBoServerDemo.LOGGER.info("看到这句就解释thrift做事端准备事情 ...."); // 做事实行掌握器(只假如调度做事的详细实现该如何运行) TProcessor tprocessor = new HelloWorldService.Processor<Iface>(new HelloWorldServiceImpl()); // 基于壅塞式同步IO模型的Thrift做事,正式生产环境不建议用这个 TServerSocket serverTransport = new TServerSocket(HelloBoServerDemo.SERVER_PORT); // 为这个做事器设置对应的IO网络模型、设置利用的格式封装、设置线程池参数 Args tArgs = new Args(serverTransport); tArgs.processor(tprocessor); tArgs.protocolFactory(new TBinaryProtocol.Factory()); tArgs.executorService(Executors.newFixedThreadPool(100)); // 启动这个thrift做事 TThreadPoolServer server = new TThreadPoolServer(tArgs); server.serve(); } catch (Exception e) { HelloBoServerDemo.LOGGER.error(e); } } / @param args / public static void main(String[] args) { HelloBoServerDemo server = new HelloBoServerDemo(); server.startServer(); }}

以上的代码有几点须要解释:

TBinaryProtocol:这个类代码Apache Thrift特有的一种二进制描述格式。
它的特点是传输单位数据量所利用的传输量更少。
Apache Thrift还支持多种数据格式,例如我们熟习的JSON格式。
后文我们将详细先容Apache Thrift中的数据格式。
tArgs.executorService():是不是以为这个executorService很熟习,是的这个便是JAVA JDK 1.5+ 后java.util.concurrent包供应的异步任务调度做事接口,Java标准线程池ThreadPoolExecutor便是它的一个实现。
server.serve(),由于是利用的同步壅塞式网络IO模型,以是这个运用程序的主线程实行到这句话往后就会保持壅塞状态了。
不过下层网络状态不涌现缺点,这个线程就会一贯停在这里。

其余,同HelloWorldServiceImpl 类中的代码,请利用Log4j。
如果您的测试工程里面没有Log4j,请改用System.out。

接下来我们进行最大略的Apache Thrift Client的代码编写:

package testThrift.client;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.apache.log4j.BasicConfigurator;import org.apache.thrift.protocol.TBinaryProtocol;import org.apache.thrift.protocol.TProtocol;import org.apache.thrift.transport.TSocket;import testThrift.iface.HelloWorldService;import testThrift.iface.Reponse;import testThrift.iface.Request;/ 同样是基于同步壅塞模型的thrift client。
@author yinwenjie /public class HelloClient { static { BasicConfigurator.configure(); } / 日志 / private static final Log LOGGER = LogFactory.getLog(HelloClient.class); public static final void main(String[] args) throws Exception { // 做事器所在的IP和端口 TSocket transport = new TSocket("127.0.0.1", 9111); TProtocol protocol = new TBinaryProtocol(transport); // 准备调用参数 Request request = new Request("{\"param\":\"field1\"}", "\\mySerivce\\queryService"); HelloWorldService.Client client = new HelloWorldService.Client(protocol); // 准备传输 transport.open(); // 正式调用接口 Reponse reponse = client.send(request); // 一定要记住关闭 transport.close(); HelloClient.LOGGER.info("response = " + reponse); }}
Thrift客户端所利用的网络IO模型,必须要与Thrift做事器端所利用的网络IO模型同等。
也便是说做事器端如果利用的是壅塞式同步IO模型,那么客户端就必须利用壅塞式同步IO模型。
Thrift客户端所利用的封装格式,必须要与Thrift做事器端所利用的封装格式一贯。
也便是说做事器端如果利用的是二进制流的格式TBinaryProtocol,那么客户端就必须同样利用二进制刘的格式TBinaryProtocol。
其它的代码要么便是由IDL定义并由Thrift的代码天生工具天生;要么就不是主要的代码,所以为了节约篇幅就没有必要再贴出来了。
以下是运行效果。
做事器端运行效果

做事器端收到客户端要求后,取出线程池中的线程进走运行

请把稳做事器端在收到客户端要求后的运行办法:取出一条线程池中的线程,并且运行这个做事接口的详细实现。
接下来我们立时先容Apache Thrift的事情细节。

(接下文)

标签:

相关文章

微信第三方登录便捷与安全的完美融合

社交平台已成为人们日常生活中不可或缺的一部分。微信作为我国最受欢迎的社交软件之一,拥有庞大的用户群体。为了方便用户在不同平台间切换...

网站建设 2025-02-18 阅读0 评论0

广东高速代码表解码高速公路管理智慧

高速公路作为国家交通动脉,连接着城市与城市,承载着巨大的物流和人流。广东作为我国经济大省,高速公路网络密布,交通流量巨大。为了更好...

网站建设 2025-02-18 阅读0 评论0

工程量代码建筑行业的数字化密码

数字化已成为各行各业转型升级的重要方向。在建筑行业,工程量代码作为一种数字化工具,正逐渐改变着传统的工程管理方式。本文将从工程量代...

网站建设 2025-02-18 阅读0 评论0