一.thrift可以做什么

thrift是一个跨语言通信的工具,支持的语言多,而且还提供服务器端的众多网络模型,使服务端的开发可以只专于服务本身的逻辑。

二.thrift重要概念

1.processor

实际服务器端业务逻辑处理的实现类。

2.transport

TTransport主要处理服务器端和客户端的网络读写。主要的接口

  • open
  • close
  • read
  • write
  • flush

例如常用的客户端是TSocket就是TTransport的一个实现

在服务器端当有请求来的时候,通过TServerTransport可以创建TTransport对象,然后通过TTransport发送数据给客户端,主要的接口

  • open
  • listen
  • accept
  • close

例如TNonblockingTransport,TSocket等。ServerTransport可以理解为主要实现了accept以后要做的事情,到底是采用何种方式(同步异步,阻塞非阻塞)把请求交给processor处理。

3.protocol

传输协议,thrift客户端和服务器端远程调用时候传输数据时候采取的数据格式,例如

TBinaryProtocol 二进制格式

TCompactProtocol  高效和压缩的二进制格式

TDenseProtocoal  与TCompactProtocol相比,meta信息略有不同

TJSONProtocoal  JSON

TDebugProtocoal  text 格式 方便调试

4.server

服务器的作用就是把前面的processor,transport,protocol组合到一起,协同他们的工作,例如:

TSimplerServer 接受一个连接,处理连接请求,直到客户端关闭了连接,它才回去接受一个新的连接。

TNonblockingServer 使用非阻塞的I/O解决了TSimpleServer一个客户端阻塞其他所有客户端的问题。

THsHaServer(半同步/半异步的server)它使用一个单独的线程来处理网络I/O,一个独立的worker线程池来处理消息。这样,只要有空闲的worker线程,消息就会被立即处理,因此多条消息能被并行处理。

TThreadPoolServer 有一个专用的线程用来接受连接。一旦接受了一个连接,它就会被放入ThreadPoolExecutor中的一个worker线程里处理。

注意:使用何种server和需要使用某种server transport,transport可能是有要求的。

例如:TNonblockingServer.Args的构造方法中

public Args(org.apache.thrift.transport.TNonblockingServerTransport transport)

可以看出使用TNonblockingServer需要使用TNonblockingServerTransport才行。

例如:使用THsHaServer时候server和client都需要设置transport为TFramedTransport

三.demo 编写一个ID生成器

下面编写的全局ID生成器是https://github.com/twitter/snowflake的简单版本,删减了通过zookeeper保证workerid的不重复。基本原理相似,22位时间戳+10位workerid+12位毫秒级的计数器。

还一些其他的ID生成方案,例如UUID,通过MYSQL的REPLACE INTO等,可用于分库以后做主键。

step 1.编写thrift interface definition language文件

idserver.thrift

namespace java demo
service IDService {
i64 getId()
}

step 2.通过thrift工具生成server端和client端的代码

thrift -r --gen java idserver.thrift

step 3.编写业务逻辑实现类

idworker.java

import org.apache.thrift.TException;

public class IDWorker implements IDService.Iface {

    private long lastTimestamp;

    private long timeabs = 1288834974657L;
//12 bits
private long sequence = 0l;
//10 bits
private long workerId; public IDWorker(long workerId) {
this.workerId = workerId;
} @Override
public long getId() throws TException {
long timestamp = System.currentTimeMillis();
if (timestamp < this.lastTimestamp) {
return -1;
} else if (timestamp == this.lastTimestamp) {
if (this.sequence < 2048) {
this.sequence = ++this.sequence;
System.out.println(this.sequence);
} else {
while (timestamp <= this.lastTimestamp) {
timestamp = System.currentTimeMillis();
}
}
} else {
this.sequence = 0;
}
this.lastTimestamp = timestamp;
return ((timestamp-timeabs) << 22) | this.workerId << 12 | this.sequence;
}
}

step 3.编写thrift服务器端主程序IDServer.java

import org.apache.thrift.TProcessor;
import org.apache.thrift.TProcessorFactory;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.THsHaServer;
import org.apache.thrift.server.TServer;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TNonblockingServerSocket;
import org.apache.thrift.transport.TTransportException;
public class IDServer { /**
* 半同步/半异步的server。它使用一个单独的线程来处理网络I/O,一个独立的worker线程池来处理消息。
*/
public void startTHsHaServer() {
try {
TProcessor processor = new IDService.Processor<IDService.Iface>(new IDWorker(1l));
TNonblockingServerSocket serverTransport = new TNonblockingServerSocket(8080);
THsHaServer.Args args = new THsHaServer.Args(serverTransport);
args.processorFactory(new TProcessorFactory(processor));
args.protocolFactory(new TBinaryProtocol.Factory());
args.transportFactory(new TFramedTransport.Factory());
args.workerThreads(2);
TServer server = new THsHaServer(args);
server.serve();
} catch (TTransportException e) {
e.printStackTrace();
}
} public static void main(String args[]) {
new IDServer().startTHsHaServer();
}
}

step 4.编写thrift客户端调用代码

ClientDemo.java

import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport; public class ClientDemo extends Thread { @Override
public void run() {
super.run();
this.startClient();
} public void startClient() {
TTransport transport = null;
try {
transport = new TFramedTransport(new TSocket("localhost", 8080, 30000));
TProtocol protocol = new TBinaryProtocol(transport);
IDService.Client client = new IDService.Client(protocol);
transport.open();
System.out.println("service result:"+client.getId());
} catch (Exception e) {
e.printStackTrace();
} finally {
if (transport != null) {
transport.close();
}
}
} public static void main(String args[]) {
for (int i=0; i<1000; i++) {
new ClientDemo().start();
}
} }

参考资料

http://thrift.apache.org/docs/concepts/

http://www.codelast.com/?p=4824#more-4824

thrift基本概念和实例的更多相关文章

  1. Thrift入门及Java实例演示<转载备用>

    Thrift入门及Java实例演示 作者: Michael 日期: 年 月 日 •概述 •下载配置 •基本概念 .数据类型 .服务端编码基本步骤 .客户端编码基本步骤 .数据传输协议 •实例演示(ja ...

  2. Javascript单例模式概念与实例

    前言 和其他编程语言一样,Javascript同样拥有着很多种设计模式,比如单例模式.代理模式.观察者模式等,熟练运用Javascript的设计模式可以使我们的代码逻辑更加清晰,并且更加易于维护和重构 ...

  3. C#反射概念以及实例详解【转】

    2009-08-28 13:12 佚名 互联网 我要评论(1) 字号:T | T C#反射概念以及实例向你介绍了C#反射的基本内容以及C#反射实例的简单应用,希望对你了解和学习C#反射以及C#反射实例 ...

  4. Thrift入门及Java实例演示

    目录: 概述 下载配置 基本概念 数据类型 服务端编码基本步骤 客户端编码基本步骤 数据传输协议 实例演示(java) thrift生成代码 实现接口Iface TSimpleServer服务模型 T ...

  5. Apache Thrift with Java Quickstart(thrift入门及Java实例)

    thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发.它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Python, PHP, Ruby, Erlang, Perl ...

  6. Thrift 原理与使用实例

    一.Thrift 框架介绍 1.前言 Thrift是一个跨语言的服务部署框架,最初由Facebook于2007年开发,2008年进入Apache开源项目.Thrift通过一个中间语言(IDL, 接口定 ...

  7. Thrift入门及Java实例演示【转】

    概述 Thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发.它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++.Java.Python.PHP.Ruby.Erlang.Perl.Ha ...

  8. (转)sqlserver游标概念与实例全面解说

    首先声明:该文章转自http://www.cnblogs.com/wudiwushen/archive/2010/03/30/1700925.html  的博客 引言  我们先不讲游标的什么概念,步骤 ...

  9. 使用C#和Thrift来访问Hbase实例

    今天试着用C#和Thrift来访问Hbase,主要参考了博客园上的这篇文章.查了Thrift,Hbase的资料,结合博客园的这篇文章,终于搞好了.期间经历了不少弯路,下面我尽量详细的记录下来,免得大家 ...

随机推荐

  1. vim(一) vim与markdown

    vim markdown 配置 vim高亮显示Markdown语法 在.vimrc添加 Plugin 'godlygeek/tabular' Plugin 'plasticboy/vim-markdo ...

  2. Java 不可变对象

    不可变对象(immutable objects):一旦对象被创建,它们的状态就不能被改变(包括基本数据类型的值不能改变,引用类型的变量不能指向其他的对象,引用类型指向的对象的状态也不能改变),每次对他 ...

  3. PIE SDK介绍

    1. 产品概述 PIE-SDK是航天宏图自主研发的PIE二次开发组件包,集成了专业的遥感影像处理.辅助解译.信息提取.专题图表生成.二三维可视化等功能.底层采用微内核式架构,由跨平台的标准C++编写, ...

  4. git push的一些坑

    在安装git的时候我们一般会自己设置一个用户名和邮箱,这个一般设置为全局的用户名,如下所示 git config --global user.name "xxx" git conf ...

  5. docker 解决容器时间与主机时间不一致的问题

    环境: 1.阿里云ecs服务器 2.docker 3.docker镜像 centos7.4.1708 方法一: 查看主机时间: [root@iZbp1625jeg61bc2zzfcotZ docker ...

  6. keepalived heartbeat lvs haproxy

    一, keeplived @ 01,keeplived 是什么? Keepalived起初是为LVS设计的,专门用来监控集群系统中各个服务节点的状态,它根据TCP/IP参考模型的第三.第四层.第五层交 ...

  7. oracle 笔记---(七)__角色

    一,角色介绍 角色就是相关权限的命令集合,使用角色的主要目的就是为了简化权限的管理,假定有用户a,b,c为了让他们都拥有权限:连接数据库和在scott.emp表上select,insert,updat ...

  8. Object 公共方法详解

    在C#中,所有类型最终都从System.Object派生,所以每个类型的每个对象都保证了一组最基本的方法.具体地说,System.Object提供了一组公共实例方法. 一.Equals 如果两个对象具 ...

  9. DistinctBy

    如何很好的使用Linq的Distinct方法[全屏看文] Person1: Id=1, Name="Test1" Person2: Id=1, Name="Test1&q ...

  10. 项目视图 Project Browser

    项目视图 在这个视图,你可以访问.管理你当前项目资源. 项目视图左侧面板显示项目的文件夹结构的分层列表,当从列表中单击一个文件夹,其内容会显示在面板的右边.你可以点击小三角展开或折叠文件夹,显示他包含 ...