热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Thrift教程初级篇——RPC框架Thrift的安装环境变量配置与第一个实例

本文介绍了RPC框架Thrift的安装环境变量配置与第一个实例,讲解了RPC的概念以及如何解决跨语言、c++客户端、web服务端、远程调用等需求。Thrift开发方便上手快,性能和稳定性也不错,适合初学者学习和使用。

前言:                    

因为项目需要跨语言,c++客户端,web服务端,远程调用等需求,所以用到了RPC框架Thrift,刚开始有点虚,第一次接触RPC框架,后来没想到Thrift开发方便上手快,而且性能和稳定性也不错,项目也顺利完成。所以给各位小白们,“科普”一下如何使用Thrift完成自己的远程调用。

1.什么是RPC:                     

 

平时开发的服务,大多都是本地调用,如果说需要依赖他人服务了,而且他人的服务在远端,那怎么调用呢?

 

RPC能够游刃有余的解决这样的问题。首先来研究一下什么RPC

 

RPC(remote produce call),远程过程调用协议。它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。

 

看下面这张图:

一次远程的调用经历了一下10个步骤:

1.调用客户端以本地方式调用远程服务

2.client stub将请求(方法和参数)组装成网络消息

3.client stub找得到服务器地址,将消息传送到远程主机

4.server stub得到传送过来的请求,进行解码

5.server stub 调用本地服务,处理请求

6.本地服务处理请求,并将处理结果返回给server stub

7.server stub将请求处理结果组装成网络消息

8.server stub找到客户端地址,将请求处理结果传送给客户端

9.client stub 接收到请求处理结果,进行解码

10.客户端最终接收到请求处理结果

 

RPC框架的目的就是将2-9步骤封装起来,对使用者透明,客户端只需要执行第一步调用接口,然后就能够得到结果。这样是不是很方便,而且省去了很多麻烦。

 

通过对RPC的初步了解,那接下来就开始不如Thrift的大门吧

 

2.What is Thrift?                                                

ThriftFacebook公司开发的一款开源的RPC框架,对于一般的RPC框架来说,通过IDL语言定义接口(Interface description language),Thrift也采用了这样的做法,并通过一个编译器生成不同语言的代码(目前支持C++,Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, SmalltalkOCaml,并由生成的代码负责RPC协议层和传输层的实现。

Thrift协议栈:

第一部分(Your Code):

简单总结:开发者的业务逻辑代码

 

第二部分(ServiceClient

Thrift自动生成的代码,包含ProcessorTserverServiceClient

TServer负责接收Client的请求,并将请求转发到Processor进行处理。TServer主要任务就是高效的接受Client的请求,特别是在高并发请求的情况下快速完成请求。

Processor(或者TProcessor)负责对Client的请求做出相应,包括RPC请求转发,调用参数解析和用户逻辑调用,返回值写回等处理步骤。Processor是服务器端从Thrift框架转入用户逻辑的关键流程。Processor同时也负责向Message结构中写入数据或者读出数据。

ServiceClient就是客户端,包含可以调用的请求方法和发送客户端请求

 

第三部分:

TProtocol主要负责结构化数据组装成Message,或者从Message结构中读出结构化数据。TProtocol将一个有类型的数据转化为字节流以交给TTransport进行传输,或者从TTransport中读取一定长度的字节数据转化为特定类型的数据。如int32会被TBinaryProtocol Encode为一个四字节的字节数据,或者TBinaryProtocolTTransport中取出四个字节的数据Decodeint32

 

第四部门:

TTransport负责以字节流方式发送和接收Message,是底层IO模块在Thrift框架中的实现,每一个底层IO模块都会有一个对应TTransport来负责Thrift的字节流(Byte Stream)数据在该IO模块上的传输。例如TSocket对应Socket传输,TFileTransport对应文件传输。

 

第五部分:

底层IO模块,负责实际的数据传输,包括Socket,文件,或者压缩数据流等。

 

通过这个协议栈,可以得出结论,使用Thrift只需要做三件事:

1.通过IDL定义数据结构和服务

2.利用代码生成工具生成代码

3.编写你的业务逻辑

 

接下来我们就按照这个三步走开发一个简单的HelloWorld级别的客户端与服务端

 

3.How to use Thrift?                                                

首先要做的就是下载并配置Thrift,附上链接:http://thrift.apache.org/download

现在版本都是0.10.0,

下载好之后将名字改成“thrift.exe”

我的电脑操作系统是Windows,属于在Windows情况下配置。

thrift.exe放在Thrift文件夹下:

配置环境变量:

 

配置完成之后,打开dos窗口,输入”thrifx -version”:

接下来执行三步走策略:

 

第一步:通过IDL定义数据结构和服务                

从最简单的HelloWorld开始,编写HelloWorld.thrift,内容如下:

namespace java service.server
service HelloWorld{
string sendString(1:string para)
}

随便放在一个文件夹下,我这里放在E:\software\Thrift,

 第二步:利用代码生成工具生成代码                                   

进入HelloWorld.thrift所在目录,执行

执行完成,你会发现没有任何提示,记得有位大神说过,没有任何提示就是好事。

这时候发现在当前目录下多了一个gen-java的目录,里面有Thrift生成的HelloWorld.java

OK,前两步已经完成,还是很简单的吧。

第三步:编写你的业务逻辑                       

创建一个Gradle管理的Java项目,bulid.gradle中添加相关的依赖,将gen-java中的HelloWorld.java拷贝到IDE的java项目中(注意包名,地址对应)。

(喜欢用Maven的朋友可以用Maven构建)

dependencies {
compile "org.apache.thrift:libthrift:0.9.2"
compile "org.slf4j:slf4j-log4j12:1.7.5"
}

 

 创建HelloWorldServiceImpl实现HelloWorld.Iface接口,这个就是主要的业务逻辑。

package service.impl;

import org.apache.thrift.TException;
import service.server.HelloWorld;

/**
* 服务端实现
*
* @author tang
*/
public class HelloWorldServiceImpl implements HelloWorld.Iface {

@Override
public String sendString(String para) throws TException {
System.out.println("接收到服务端传来的参数: " + para);
String result = "服务端成功收到消息";
return result;
}

}

 接着,创建服务端实现代码,命名为HelloWorldServiceServer,把HelloWoeldServiceImpl作为一个具体的处理器传递给Thrift服务器:

 

package service.server;

import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TSimpleServer;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TTransportException;
/**
* 服务端
*
* @author tang
*/
import service.impl.HelloWorldServiceImpl;

public class HelloWorldServiceServer {

public static void main(String[] args) throws TTransportException {
System.out.println("服务端开启");

// 关联处理器
TProcessor tProcessor = new HelloWorld.Processor(new HelloWorldServiceImpl());

// 设置服务端口为 8080
TServerSocket serverSocket = new TServerSocket(8080);

// 简单的单线程服务模型
TServer.Args tArgs = new TServer.Args(serverSocket);
tArgs.processor(tProcessor);
// 设置协议工厂为 TBinaryProtocol.Factory
tArgs.protocolFactory(new TBinaryProtocol.Factory());
TServer server = new TSimpleServer(tArgs);
// 启动服务
server.serve();
}

}

 最后,再写一个客户端HelloWorldClient.java:

package client;

import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import service.server.HelloWorld;

/**
* 客户端
*
* @author tang
*/
public class HelloWorldClient {

public static void main(String[] args) {
System.out.println("客户端启动....");
TTransport transport = null;
try {
// 设置调用的服务地址为本地,端口为8080,超时设置为30秒
transport = new TSocket("localhost", 8080, 30000);
// 协议要和服务端一致
TProtocol protocol = new TBinaryProtocol(transport);
HelloWorld.Client client = new HelloWorld.Client(protocol);
transport.open();
// 调用接口方法
String result = client.sendString("Hello World!");
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != transport) {
transport.close();
}
}
}

}

 这个是project结构图:

这里有一些Thrift自带的警告,不用去管他(有点违背Effective java中的原则)。。。。。

最后的最后:测试                                                                                            

启动服务端,然后再启动客户端,这是服务端会收到来自客户端的消息:“HelloWorld”

客户端收到服务端的反馈:

好了,到这里,Thrift的第一个实例就结束了,总的来说Thrift还是很好用的,有些的不好的地方欢迎批评斧正!

参考文章:

 http://www.blogjava.net/ldwblog/archive/2014/12/03/421011.html


推荐阅读
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 在哈佛大学商学院举行的Cyberposium大会上,专家们深入探讨了开源软件的崛起及其对企业市场的影响。会议指出,开源软件不仅为企业提供了新的增长机会,还促进了软件质量的提升和创新。 ... [详细]
  • 阿里云ecs怎么配置php环境,阿里云ecs配置选择 ... [详细]
  • 在编译BSP包过程中,遇到了一个与 'gets' 函数相关的编译错误。该问题通常发生在较新的编译环境中,由于 'gets' 函数已被弃用并视为安全漏洞。本文将详细介绍如何通过修改源代码和配置文件来解决这一问题。 ... [详细]
  • 远程过程调用(RPC)是一种允许客户端通过网络请求服务器执行特定功能的技术。它简化了分布式系统的交互,使开发者可以像调用本地函数一样调用远程服务,并获得返回结果。本文将深入探讨RPC的工作原理、发展历程及其在现代技术中的应用。 ... [详细]
  • 使用WinForms 实现 RabbitMQ RPC 示例
    本文通过两个WinForms应用程序演示了如何使用RabbitMQ实现远程过程调用(RPC)。一个应用作为客户端发送请求,另一个应用作为服务端处理请求并返回响应。 ... [详细]
  • 本文深入探讨了JavaScript中实现继承的四种常见方法,包括原型链继承、构造函数继承、组合继承和寄生组合继承。对于正在学习或从事Web前端开发的技术人员来说,理解这些继承模式对于提高代码质量和维护性至关重要。 ... [详细]
  • 近期,谷歌公司的一名安全工程师Eduardo Vela在jQuery Mobile框架中发现了一项可能引发跨站脚本攻击(XSS)的安全漏洞。此漏洞使得使用jQuery Mobile的所有网站面临潜在的安全威胁。 ... [详细]
  • 转自:http:www.yybug.comread-htm-tid-15324.html为什么使用Twisted? 如果你并不准备使用Twisted,你可能有很多异议。为什么使用T ... [详细]
  • FreeBSD作为Berkeley Software Distribution (BSD)的一个关键分支,其发展历程深刻影响了现代操作系统的设计。本文将探讨FreeBSD从早期版本到最新版本的技术进步及其对计算行业的贡献。 ... [详细]
  • 2023 ARM嵌入式系统全国技术巡讲旨在分享ARM公司在半导体知识产权(IP)领域的最新进展。作为全球领先的IP提供商,ARM在嵌入式处理器市场占据主导地位,其产品广泛应用于90%以上的嵌入式设备中。此次巡讲将邀请来自ARM、飞思卡尔以及华清远见教育集团的行业专家,共同探讨当前嵌入式系统的前沿技术和应用。 ... [详细]
  • 本文详细介绍了 Dockerfile 的编写方法及其在网络配置中的应用,涵盖基础指令、镜像构建与发布流程,并深入探讨了 Docker 的默认网络、容器互联及自定义网络的实现。 ... [详细]
  • 在前两篇文章中,我们探讨了 ControllerDescriptor 和 ActionDescriptor 这两个描述对象,分别对应控制器和操作方法。本文将基于 MVC3 源码进一步分析 ParameterDescriptor,即用于描述 Action 方法参数的对象,并详细介绍其工作原理。 ... [详细]
  • 在Linux系统中配置并启动ActiveMQ
    本文详细介绍了如何在Linux环境中安装和配置ActiveMQ,包括端口开放及防火墙设置。通过本文,您可以掌握完整的ActiveMQ部署流程,确保其在网络环境中正常运行。 ... [详细]
  • a16z 宣布成立全新的加密研究实验室,旨在推动加密技术和 Web3 领域的科学发展。 ... [详细]
author-avatar
dongquchunlaizv_123
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有