文档章节

Thrift入门及Java实例

l
 lvk618
发布于 2016/06/15 09:12
字数 1958
阅读 14
收藏 1

一、概述

Thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发。它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml 等等编程语言间无缝结合的、高效的服务。

Thrift最初由facebook开发,07年四月开放源码,08年5月进入apache孵化器。thrift允许你定义一个简单的定义文件中的数据类型和服务接口。以作为输入文件,编译器生成代码用来方便地生成RPC客户端和服务器通信的无缝跨编程语言。【来自百度百科】

官网地址:thrift.apache.org


二、下载依赖(Maven)

1、在pom.xml 中添加如下内容:

<span style="white-space:pre">		</span><dependency>
			<groupId>org.apache.thrift</groupId>
			<artifactId>libthrift</artifactId>
			<version>0.9.3</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>1.7.12</version>
		</dependency>

三、基本概念以及实现步骤

几张图片说明thrift整个流程:

架构图:


服务端


客户端


部署图


注意:图片来源互联网

1、数据传输协议

TBinaryProtocol : 二进制格式.
TCompactProtocol : 压缩格式
TJSONProtocol : JSON格式
TSimpleJSONProtocol : 提供JSON只写协议, 生成的文件很容易通过脚本语言解析

注意: 客户端和服务端的协议要一致。

2、服务端

实现服务处理接口impl
创建TProcessor
创建TServerTransport
创建TProtocol
创建TServer
启动Server

3、客户端

创建Transport
创建TProtocol
基于TTransport和TProtocol创建 Client
调用Client的相应方法


四、实例

1、thrift文件创建,并在文件中定义需要的接口方法

namespace java com.jmust.thrift.demo

service  HelloWorldService {
  string sayHello(1:string username)
}

2、执行thrift-0.9.3.exe生成代码

thrift-0.9.3.exe -r -gen java ./demoHello.thrift
3、创建一个服务maven项目(shrift-service),将生成的 HelloWorldService.java文件复制到自己的项目中,利用maven打包成为bundle作为一个服务包,里面代码具体是什么样子的,我们不需要关心,到时候需要用到的地方,只需要把这个服务包引进去即可使用,下面看看我的pom.xml文件(把该开放出去的package开放出去,该引进来的package引进来)

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.jmust.thrift</groupId>
	<artifactId>thrift-service</artifactId>
	<version>1.0.0</version>
	<packaging>jar</packaging>

	<name>thrift-service</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>

	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>3.8.1</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.apache.thrift</groupId>
			<artifactId>libthrift</artifactId>
			<version>0.9.3</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>1.7.12</version>
		</dependency>
	</dependencies>
	
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>2.3.2</version>
				<configuration>
					<source>1.7</source>
					<target>1.7</target>
					<encoding>${project.build.sourceEncoding}</encoding>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-resources-plugin</artifactId>
				<version>2.4.3</version>
				<executions>
					<execution>
						<phase>compile</phase>
					</execution>
				</executions>
				<configuration>
					<encoding>${project.build.sourceEncoding}</encoding>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-source-plugin</artifactId>
				<version>2.4</version>
				<executions>
					<execution>
						<phase>deploy</phase>
						<goals>
							<goal>jar</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-deploy-plugin</artifactId>
				<version>2.8.2</version>
				<configuration>
					<skip>false</skip>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-javadoc-plugin</artifactId>
				<version>2.10.3</version>
				<configuration>
					<aggregate>true</aggregate>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-surefire-plugin</artifactId>
				<version>2.7.2</version>
				<configuration>
					<skip>false</skip>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.codehaus.mojo</groupId>
				<artifactId>cobertura-maven-plugin</artifactId>
				<version>2.7</version>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-jar-plugin</artifactId>
				<version>2.3.1</version>
				<configuration>
					<archive>
						<manifest>
							<addClasspath>true</addClasspath>
							<classpathPrefix>lib/</classpathPrefix>
						</manifest>
						<manifestEntries>
							<Class-Path>.</Class-Path>
							<Built-By>JMUST</Built-By>
							<Bundle-ManifestVersion>2</Bundle-ManifestVersion>
							<Bundle-Name>${project.groupId}.${project.ArtifactId}</Bundle-Name>
							<Bundle-SymbolicName>${project.groupId}.${project.ArtifactId}</Bundle-SymbolicName>
							<Bundle-Version>${project.version}</Bundle-Version>
							<Bundle-Vendor>${project.groupId}</Bundle-Vendor>
							<Export-Package>com.jmust.thrift.service;version=${project.version}
							</Export-Package>
							<Import-Package>
								javax.annotation,org.slf4j,org.apache.thrift,org.apache.thrift.async,org.apache.thrift.scheme,org.apache.thrift.protocol,org.apache.thrift.server.AbstractNonblockingServer
							</Import-Package>
						</manifestEntries>
					</archive>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>


4、再创建一个实现以上服务maven项目(thrift-demo),pom.xml文件只需要引入

<span style="white-space:pre">		</span><dependency>
			<groupId>org.apache.thrift</groupId>
			<artifactId>libthrift</artifactId>
			<version>0.9.3</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>1.7.12</version>
		</dependency>
		<dependency>
			<groupId>com.jmust.thrift</groupId>
			<artifactId>thrift-service</artifactId>
			<version>1.0.0</version>
		</dependency>

4.1、实现接口Iface

package com.jmust.thrift.impl;

import org.apache.thrift.TException;

import com.jmust.thrift.service.HelloWorldService.Iface;

/**
 * 
 * @author LK
 *
 */
public class HelloWorldImpl implements Iface
{

	public HelloWorldImpl(){
		
	}
	
	public String sayHello(String username) throws TException {
		return "Hi," + username + " welcome to my blog www.jmust.com";
	}
   
}


5、根据协议去实现服务端

5.1、TSimpleServer服务端-----简单的单线程服务模型,一般用于测试

package com.jmust.thrift.demo;


import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TServer.Args;
import org.apache.thrift.server.TSimpleServer;
import org.apache.thrift.transport.TServerSocket;

import com.jmust.thrift.impl.HelloWorldImpl;
import com.jmust.thrift.service.HelloWorldService.Iface;
import com.jmust.thrift.service.HelloWorldService.Processor;

/**
 * 单线程服务模型,一般用于测试  TSimpleServer服务端
 * @author LK
 *
 */
public class HelloTSimpleServerDemo {

	public static final int SERVER_PORT = 8090;

	public void startServer() {
		try {
			System.out.println("HelloWorld TSimpleServer start ....");
 
			TProcessor tprocessor = new Processor<Iface>(
					new HelloWorldImpl());
			// 简单的单线程服务模型,一般用于测试  
			TServerSocket serverTransport = new TServerSocket(SERVER_PORT);
			Args tArgs = new Args(serverTransport);
			tArgs.processor(tprocessor);
			tArgs.protocolFactory(new TBinaryProtocol.Factory());
			TServer server = new TSimpleServer(tArgs);
			server.serve();
 
		} catch (Exception e) {
			System.out.println("Server start error!!!");
			e.printStackTrace();
		}
	}
 
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		HelloTSimpleServerDemo server = new HelloTSimpleServerDemo();
		server.startServer();
	}
}

5.2、TThreadPoolServer 服务模型 ------线程池服务模型, 使用标准的阻塞式IO,预先创建一组线程处理请求

package com.jmust.thrift.demo;


import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TThreadPoolServer;
import org.apache.thrift.server.TThreadPoolServer.Args;
import org.apache.thrift.transport.TServerSocket;

import com.jmust.thrift.impl.HelloWorldImpl;
import com.jmust.thrift.service.HelloWorldService.Iface;
import com.jmust.thrift.service.HelloWorldService.Processor;

/**
 * 线程池服务模型,使用标准的阻塞式IO,预先创建一组线程处理请求    TThreadPoolServer 服务模型
 * @author LK
 *
 */
public class HelloTThreadPoolServerDemo {

	public static final int SERVER_PORT = 8090;
	
	public void startServer() {
		try {
			System.out.println("HelloWorld TThreadPoolServer start ....");
 
			TProcessor tprocessor = new Processor<Iface>(
					new HelloWorldImpl());
			TServerSocket serverTransport = new TServerSocket(SERVER_PORT);
			//TThreadPoolServer 线程池服务模型
			Args ttpsArgs = new Args(
					 serverTransport);
			ttpsArgs.processor(tprocessor);
			ttpsArgs.protocolFactory(new TBinaryProtocol.Factory());
			//线程池服务模型,使用标准的阻塞式IO,预先创建一组线程处理请求。
			TServer server = new TThreadPoolServer(ttpsArgs);
			server.serve();
		} catch (Exception e) {
			System.out.println("Server start error!!!");
			e.printStackTrace();
		}
	}
 
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		HelloTThreadPoolServerDemo server = new HelloTThreadPoolServerDemo();
		server.startServer();
	}
}


5.3、TNonblockingServer 服务模型  -------使用 非阻塞式IO,服务端和客户端需要指定  TFramedTransport 数据传输的方式

package com.jmust.thrift.demo;


import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.server.TNonblockingServer;
import org.apache.thrift.server.TNonblockingServer.Args;
import org.apache.thrift.server.TServer;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TNonblockingServerSocket;

import com.jmust.thrift.impl.HelloWorldImpl;
import com.jmust.thrift.service.HelloWorldService.Iface;
import com.jmust.thrift.service.HelloWorldService.Processor;

/**
 * 使用非阻塞式IO,服务端和客户端需要指定 TFramedTransport 数据传输的方式    TNonblockingServer 服务模型
 * @author LK
 *
 */
public class HelloTNonblockingServerDemo {

	public static final int SERVER_PORT = 8090;
	public void startServer() {
		try {
			System.out.println("HelloWorld TNonblockingServer start ....");
 
			TProcessor tprocessor = new Processor<Iface>(
					new HelloWorldImpl());
			TNonblockingServerSocket tnbSocketTransport = new TNonblockingServerSocket(SERVER_PORT);
			Args tnbArgs = new Args(tnbSocketTransport);
			tnbArgs.processor(tprocessor);
			tnbArgs.transportFactory(new TFramedTransport.Factory());
			tnbArgs.protocolFactory(new TCompactProtocol.Factory());
			TServer server = new TNonblockingServer(tnbArgs);
			server.serve();
			
		} catch (Exception e) {
			System.out.println("Server start error!!!");
			e.printStackTrace();
		}
	}
 
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		HelloTNonblockingServerDemo server = new HelloTNonblockingServerDemo();
		server.startServer();
	}
}

5.4、THsHaServer服务模型  -------半同步半异步的服务端模型,需要指定为:  TFramedTransport 数据传输的方式

package com.jmust.thrift.demo;


import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.THsHaServer;
import org.apache.thrift.server.THsHaServer.Args;
import org.apache.thrift.server.TServer;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TNonblockingServerSocket;

import com.jmust.thrift.impl.HelloWorldImpl;
import com.jmust.thrift.service.HelloWorldService.Iface;
import com.jmust.thrift.service.HelloWorldService.Processor;

/**
 * 半同步半异步的服务端模型,需要指定为: TFramedTransport 数据传输的方式  THsHaServer服务模型
 * @author LK
 *
 */
public class HelloTHsHaServerDemo {

	public static final int SERVER_PORT = 8090;
	public void startServer() {
		try {
			System.out.println("HelloWorld THsHaServer start ....");
 
			TProcessor tprocessor = new Processor<Iface>(
					new HelloWorldImpl());
			TNonblockingServerSocket tnbSocketTransport = new TNonblockingServerSocket(SERVER_PORT);
			Args args = new Args(tnbSocketTransport);
			args.processor(tprocessor);
			args.transportFactory(new TFramedTransport.Factory());
			args.protocolFactory(new TBinaryProtocol.Factory());
			TServer server = new THsHaServer(args);
			server.serve();
			
		} catch (Exception e) {
			System.out.println("Server start error!!!");
			e.printStackTrace();
		}
	}
 
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		HelloTHsHaServerDemo server = new HelloTHsHaServerDemo();
		server.startServer();
	}
}

6、客户端实现

6.1、同步

package com.jmust.thrift.demo;

import org.apache.thrift.TException;
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;
import org.apache.thrift.transport.TTransportException;

import com.jmust.thrift.service.HelloWorldService.Client;

/**
 * 
 * @author LK
 *
 */
public class HelloClientDemo {
	public static final String SERVER_IP = "localhost";
	public static final int SERVER_PORT = 8090;
	public static final int TIMEOUT = 30000;

	/**
	 *
	 * @param userName
	 */
	public void startClient(String userName) {
		TTransport transport = null;
		try {
			//transport = new TSocket(SERVER_IP, SERVER_PORT, TIMEOUT);
			transport = new TFramedTransport(new TSocket(SERVER_IP, SERVER_PORT, TIMEOUT));
			// 协议要和服务端一致
			TProtocol protocol = new TBinaryProtocol(transport);
			//TProtocol protocol = new TCompactProtocol(transport);
			// TProtocol protocol = new TJSONProtocol(transport);
			Client client = new Client(protocol);
			transport.open();
			String result = client.sayHello(userName);
			System.out.println("Thrify client result =: " + result);
		} catch (TTransportException e) {
			e.printStackTrace();
		} catch (TException e) {
			e.printStackTrace();
		} finally {
			if (null != transport) {
				transport.close();
			}
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		HelloClientDemo client = new HelloClientDemo();
		client.startClient("lvk");

	}
}

6.2、异步

package com.jmust.thrift.demo;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import org.apache.thrift.TException;
import org.apache.thrift.async.AsyncMethodCallback;
import org.apache.thrift.async.TAsyncClientManager;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TProtocolFactory;
import org.apache.thrift.transport.TNonblockingSocket;
import org.apache.thrift.transport.TNonblockingTransport;

import com.jmust.thrift.service.HelloWorldService.AsyncClient;
import com.jmust.thrift.service.HelloWorldService.AsyncClient.sayHello_call;

/**
 * 异步客户端
 * @author LK
 *
 */
public class HelloAsynClientDemo {
	public static final String SERVER_IP = "localhost";
	public static final int SERVER_PORT = 8090;
	public static final int TIMEOUT = 30000;

	/**
	 *
	 * @param userName
	 */
	public void startClient(String userName) {
		try {
			TAsyncClientManager clientManager = new TAsyncClientManager();
			TNonblockingTransport transport = new TNonblockingSocket(SERVER_IP, SERVER_PORT, TIMEOUT);
			TProtocolFactory tprotocol = new TCompactProtocol.Factory();
			AsyncClient asyncClient = new AsyncClient(tprotocol, clientManager, transport);
			System.out.println("Client start .....");
		
			CountDownLatch latch = new CountDownLatch(1);
			AsynCallback callBack = new AsynCallback(latch);
			System.out.println("call method sayHello start ...");
			asyncClient.sayHello(userName, callBack);
			System.out.println("call method sayHello .... end");
			boolean wait = latch.await(30, TimeUnit.SECONDS);
			System.out.println("latch.await =:" + wait);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("startClient end.");
	}

	public class AsynCallback implements AsyncMethodCallback<sayHello_call>{
		private CountDownLatch latch;

		public AsynCallback(CountDownLatch latch) {
			this.latch = latch;
		}
		public void onComplete(sayHello_call response) {
			System.out.println("onComplete");
			try {
				// Thread.sleep(1000L * 1);
				System.out.println("AsynCall result =:"
						+ response.getResult().toString());
			} catch (TException e) {
				e.printStackTrace();
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				latch.countDown();
			}
		}
		public void onError(Exception exception) {
			System.out.println("onError :" + exception.getMessage());
			latch.countDown();
		}
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		HelloAsynClientDemo client = new HelloAsynClientDemo();
		client.startClient("lvk");
	}
}

7.、测试步骤

先运行服务端,让后再运行客户端,看看是否输出预计结果。


完毕!

本文转载自:http://blog.csdn.net/lk10207160511/article/details/50450541

l
粉丝 3
博文 80
码字总数 792
作品 0
广州
私信 提问
thrift rpc js使用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/byxdaz/article/details/84871376 一、thrift js使用方式 使用thrift js时,PRotocol需要使用TJSONPRotocol/T...

byxdaz
2018/12/07
0
0
Thrift入门初探--thrift安装及java入门实例

  公司的一些平台服务框架底层封装了thrift提供服务,最近项目不是很紧,于是研究了一下,刚刚入门,理解得不深,写这篇博文来整理一下思路. 什么是thrift?   简单来说,是Facebook公布的一款开...

冬至饮雪
2017/02/21
0
0
[Thrift]Apache Thrift入门Java实例

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/SunnyYoona/article/details/52606287 1. 概述 Apache Thrift 是 Facebook 实现的一种高效的、支持多种编程语...

sjf0115
2016/09/21
0
0
Apache Thrift - 可伸缩的跨语言服务开发框架

前言: 目前流行的服务调用方式有很多种,例如基于 SOAP 消息格式的 Web Service,基于 JSON 消息格式的 RESTful 服务等。其中所用到的数据传输方式包括 XML,JSON 等,然而 XML 相对体积太大...

张升强
2015/05/15
73
0
Apache Thrift - 可伸缩的跨语言服务开发框架

前言: 目前流行的服务调用方式有很多种,例如基于 SOAP 消息格式的 Web Service,基于 JSON 消息格式的 RESTful 服务等。其中所用到的数据传输方式包括 XML,JSON 等,然而 XML 相对体积太大...

IBMdW
2012/01/16
4.5K
4

没有更多内容

加载失败,请刷新页面

加载更多

领域驱动中的“贫血症和失忆症”

贫血症严重危害着人类健康,并且伴随有危险的副作用。当贫血领域对象被首次提出来时,它并不是一个博得赞美的词汇,它描述的是一个缺少内在行为领域对象。奇怪的是,人们对于贫血领域对象的态...

还仙
6分钟前
2
0
条码打印软件中标签预览正常打印无反应怎么解决

在使用条码打印软件制作标签时,有客户反馈,标签打印预览正常的,但是打印无反应,咨询是怎么回事?今天针对这个情况,可以参考以下方法进行解决。 一、预览正常情况下,打印没反应 (1)在条码...

中琅软件
16分钟前
2
0
判断字符串的时候

判断字符串的时候一定把常量房前边, //报警程度 String leve = vo.getDeviceAlertDeal().getWarnLevel(); if(("0").equals(leve)) { row.add("无报警"); }else if(("1").equals(leve)) { ro......

简小姐
16分钟前
3
0
Linux maven3.6.2 install

PS:安装 maven 之前请先安装 jdk 1.安装 wget 命令(安装过就不用了) yum -y install wget 2.寻找需要的 maven 版本 https://maven.apache.org/download.cgi 3.进入 /var/local 文件夹 cd...

东方神祇
19分钟前
2
0
Tomcat源码分析二:先看看Tomcat的整体架构

Tomcat源码分析二:先看看Tomcat的整体架构 Tomcat架构图 我们先来看一张比较经典的Tomcat架构图: 从这张图中,我们可以看出Tomcat中含有Server、Service、Connector、Container等组件,接下...

flygrk
21分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部