Thrift RPC实战(一).初次体验Thrift
1.前言:
Thrift作为Facebook开源的RPC框架, 通过IDL中间语言, 并借助代码生成引擎生成各种主流语言的rpc框架服务端/客户端代码,主要特点:
开发速度快:
通过编写RPC接口IDL文件,利用编译生成器自动生成Server端骨架(Skeletons)和客户端Stubs,省去开发者自定义和维护接口编解码、消息传输、服务器多线程模型等基础工作;Server端开发者只需按照服务骨架,写好自己的业务处理程序(Handlers)即可,Client端程序只需创建IDL中定义的服务对象,然后就像调用本地对象的方法一样调用远端服务。
接口维护简单高效:
通过维护Thrift格式的IDL(Interface Description Language)文件(注意写好注释),即可作为给Clients使用的接口文档使用,也自动生成接口代码,始终保持代码和文档的一致性。且Thrift协议可灵活支持接口的可扩展性。
学习成本低:
因为其来自Google Protocol Buffers开发团队,所以其IDL文件风格类似Google Protocol Buffers,且更加易读易懂;特别是RPC服务接口的风格就像写一个一般的面向对象的Class一样简单。
初学者只需参照http://thrift.apache.org/几个小时即可理解和使用Thrift。
多语言/跨语言支持:
Thrift支持C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, OCaml and Delphi等多种语言,即可生成上述语言的服务器端和客户端程序。
对于我们经常使用的Java、PHP、Python、C++支持良好,虽然对iOS环境的Objective-C(Cocoa)支持稍逊,但也完全满足我们的使用要求。
已验证成熟稳定:
Thrift在很多开源项目中已经被验证是稳定和高效的,例如Cassandra、Evernode等;在Facebook、Baidu等后台产品中也有使用。
2.基础知识
2.1 Thrift 软件栈
Thrift对软件栈的定义非常的清晰, 使得各个组件能够松散的耦合, 针对不同的应用场景, 选择不同是方式去搭建服务.
评注:
Transport: 传输层,定义数据传输方式,可以为TCP/IP传输,内存共享或者文件共享等
protocol: 协议层, 定义数据传输格式,可以为二进制或者XML等
Processor: 处理层, 这部分由定义的idl来生成, 封装了协议输入输出流, 并委托给用户实现的handler进行处理.
Server: 服务层, 整合上述组件, 提供网络模型(单线程/多线程/事件驱动), 最终形成真正的服务.
Thrift 对语言的支持
Thrift和Google Protobuf相比, 都提供了可扩展序列化机制, 不但兼容性好而且压缩率高. 两者在这块各有长短, 性能上PB稍有优势. 但在语言的支持度上, Protobuf只支持c++/java/python这三种主流的语言, Thrift则几乎覆盖了大部分的语言, 从这点上来说, Thrift的优势非常的明显.
Thrift 支持的数据类型
基本类型:
bool: 布尔值
byte: 8位有符号整数
i16: 16位有符号整数
i32: 32位有符号整数
i64: 64位有符号整数
double: 64位浮点数
string: UTF-8编码的字符串
binary: 二进制串
结构体类型:
struct: 定义的结构体对象
容器类型:
list: 有序元素列表
set: 无序无重复元素集合
map: 有序的key/value集合
异常类型:
exception: 异常类型
服务类型:
service: 具体对应服务的类
3.小试牛刀
3.1定义thrift文件
namespace java com.yangyang.thrift.api
service HelloService {
string hello(1: string name);
}
3.2使用thrift提供的代码生成工具生成代码
thrift -gen java -out ../java/ hello.thrift
3.3新建thrift-demo工程
在pom文件中加入thrift以及log4j的jar
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>0.9.3</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.5</version>
</dependency>
编写服务端代码:
package com.yangyang.thrift.server;
import com.yangyang.thrift.api.HelloService;
import com.yangyang.thrift.com.yangyang.thrift.service.HelloServiceImpl;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TThreadPoolServer;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TTransportException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Created by chenshunyang on 2016/10/30.
*/
public class ServerDemo {
public static void main(String[] args) throws TTransportException {
Logger logger = LoggerFactory.getLogger(ServerDemo.class);
int port= 9000 ;
// *) 传输层(Transport), 设置监听端口为9000
TServerSocket serverTransport = new TServerSocket(port);
// *) 协议层
TBinaryProtocol.Factory protocolFactory = new TBinaryProtocol.Factory(true, true);
// *) 处理层(Processor)
HelloServiceImpl handler = new HelloServiceImpl();
HelloService.Processor<HelloServiceImpl> processor = new HelloService.Processor<HelloServiceImpl>(handler);
// *) 服务层(Server)
TServer server = new TThreadPoolServer(
new TThreadPoolServer.Args(serverTransport)
.protocolFactory(protocolFactory)
.processor(processor));
// *) 启动监听服务
server.serve();
logger.info("服务已经启动,端口为:"+port);
}
}
编写客户端代码:
package com.yangyang.thrift;
import com.yangyang.thrift.api.HelloService;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
/**
* Created by chenshunyang on 2016/10/30.
*/
public class ClientDemo {
public static void main(String[] args) throws TException {
// *) 传输层
TTransport transport = new TSocket("localhost", 9000);
transport.open();
// *) 协议层, 与服务端对应
TProtocol protocol = new TBinaryProtocol(transport);
// *) 创建RPC客户端
HelloService.Client client = new HelloService.Client(protocol);
// *) 调用服务
System.out.println(client.hello("chenshunyang"));
// *) 关闭句柄
transport.close();
}
}
先运行服务端,后运行客户端,观察结果,可以看到客户端输出结果:
hello chenshunyang
Thrift RPC实战(一).初次体验Thrift的更多相关文章
- Thrift RPC实战(三) thrift序列化揭秘
本文主要讲解Thrift的序列化机制, 看看thrift作为数据交换格式是如何工作的? 1.构造应用场景: 1). 首先我们先来定义下thrift的简单结构. 1 2 3 4 5 namespace ...
- Thrift 个人实战--初次体验Thrift
前言: Thrift作为Facebook开源的RPC框架, 通过IDL中间语言, 并借助代码生成引擎生成各种主流语言的rpc框架服务端/客户端代码. 不过Thrift的实现, 简单使用离实际生产环境还 ...
- Thrift 个人实战--初次体验Thrift(转)
前言: Thrift作为Facebook开源的RPC框架, 通过IDL中间语言, 并借助代码生成引擎生成各种主流语言的rpc框架服务端/客户端代码. 不过Thrift的实现, 简单使用离实际生产环境还 ...
- Thrift RPC实战(二) Thrift 网络服务模型
限于篇幅关系,在观察源码的时候,只列举了部分源代码 TServer类层次体系 TSimpleServer/TThreadPoolServer是阻塞服务模型 TNonblockingServer/THs ...
- Thrift 个人实战--Thrift 的序列化机制
前言: Thrift作为Facebook开源的RPC框架, 通过IDL中间语言, 并借助代码生成引擎生成各种主流语言的rpc框架服务端/客户端代码. 不过Thrift的实现, 简单使用离实际生产环境还 ...
- 使用Thrift RPC编写程序(服务端和客户端)
1. Thrift类介绍 Thrift代码包(位于thrift-0.6.1/lib/cpp/src)有以下几个目录: concurrency:并发和时钟管理方面的库processor:Processo ...
- 利用thrift rpc进行C++与Go的通信
一:什么是rpc rpc通俗来理解就是远程调用函数,相对于本地调用来说,只需要在主调函数中调用被掉函数即可,代码如下: void fun(int i) { cout << "fu ...
- Thrift RPC框架介绍
u 简介 Thrift是一种开源的跨语言的RPC服务框架.Thrift最初由facebook公司开发的,在2007年facebook将其提交apache基金会开源了.对于当时的facebook来说创造 ...
- RPC服务框架探索之Thrift
前言架构服务化后,需要实现一套方便调用各服务的框架,现在开源如日中天,优先会寻找开源实现,如果没有合适自家公司业务的,才会考虑从零开发,尤其是一切以KPI为准绳的公司,谁会跟钱过不去?N个月之前,公司 ...
随机推荐
- asp.net 发邮件
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...
- MEF框架在Silverlight中应用(15)
原文:MEF框架在Silverlight中应用(15) MEF框架在Silverlight中应用 代码下载 MEF框架是微软提供的一个插件框架.应用概括为一句话:输入,输出,组合.下面是具体在Silv ...
- 开源Dubbox
当当网开源Dubbox https://github.com/dangdangdotcom/dubbox https://github.com/alibaba/dubbo http://www.inf ...
- WEB安全实战(五)XSS 攻击的第二种解决方式(推荐)
序 说到 XSS 攻击,前边已经有两篇文章在讲这个事了,这次又拿出来说,主要是针对近期工作中的一些新的问题.那么之前是怎么解决问题的呢?为什么又要换解决方式?以下就具体的跟大家分享一下. 旧方案 公司 ...
- SQL Server 2012的附件失败,与硬链接的问题
1.我在系统上做了硬链接,也就是把C盘的某个目录,映射为D盘. 2.把数据库文件mdf和ldf放入D盘.结果,SQL Server的企业管理器,无法从D盘里加载mdf或ldf文件,并且在目录下无法显示 ...
- SQL点滴10—使用with语句来写一个稍微复杂sql语句,附加和子查询的性能对比
原文:SQL点滴10-使用with语句来写一个稍微复杂sql语句,附加和子查询的性能对比 今天偶尔看到sql中也有with关键字,好歹也写了几年的sql语句,居然第一次接触,无知啊.看了一位博主的文章 ...
- 记一次内存泄漏DUMP分析
自从进入一家创业公司以后,逐渐忙成狗,却无所收获,感觉自身的技术能力用武之地很少,工作生活都在业务逻辑中颠倒. 前些天线上服务内存吃紧,让运维把DUMP拿下来,分析一下聊以自慰. 先来统计一下大对象信 ...
- a:focus{outline: none;} 如何去掉点击链接时周围的虚线框outline属性
1. CSS方式 在IE下是使用html属性:hideFoucs,在HTML标签中加上hidefocus=”true”属性即可,但这个属性是IE私有的,Firefox是不认的. 加了hidefocus ...
- vs 文件头自动添加注释
原文:vs 文件头自动添加注释 vs2010 C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ItemTemplates ...
- HubbleDotNet全文搜索数据库组件(一)
HubbleDotNet 简介及安装详解 2012-11-05 12:59 来源:9SSSD.COM 作者:starts_2000 字号:T|T [摘要]HubbleDotNet 是一个基于.net ...