`

Thrift小记

阅读更多

Thrit用的不多,也不够深入,这里小记一笔。

关于Thrift环境如何安装,可以参考官网。 

或者直接下载windows版本的thrift-0.9.2.exe

Thrit跟Java有数据类型的映射关系:

/**
 * The first thing to know about are types. The available types in Thrift are:
 *
 *  bool        Boolean, one byte
 *  byte        Signed byte
 *  i16         Signed 16-bit integer - short
 *  i32         Signed 32-bit integer - int
 *  i64         Signed 64-bit integer - long
 *  double      64-bit floating point value - double
 *  string      String
 *  binary      Blob (byte array)
 *  map<t1,t2>  Map from one type to another
 *  list<t1>    Ordered list of one type
 *  set<t1>     Set of unique elements of one type
 */

 我就不罗嗦了了,能看到这里的都能自动理解。蠢话

 

RPC的核心就是传参调用,参数抛不开基本数据类型、集合,更常用的是自定义对象。

在Thrift中,需要将自定义对象预先定义,类似于C语言编译要求。或者可以include其他thrift文件。

这里用Profile作为对象载体,这里Java的class对应Thrit中的struct,interface对应service。

做一个操作Profile的接口实现,代码如下:

namespace java org.zlex.support.thrift

struct Profile {
	1: string name,
	2: i32 score,
	3: bool enable
}
 
service ProfileService {
    string updateName(1:Profile profile, 2:string name)
    i32 updateScore(1:Profile profile, 2:i32 score)
    map<string,string> toMap(1:Profile profile)
}

保存为Profile.thrift

 

执行命令,生成Java代码:

thrift -r -gen java Profile.thrift

生成的代码详见附件。自动生成的代码中,冗余还是不少。修改代码的冲动闪过,保持原生态。

 

针对接口做个实现类:

/**
 * Mar 14, 2013
 */
package org.zlex.support.thrift.impl;

import java.util.HashMap;
import java.util.Map;

import org.apache.thrift.TException;
import org.zlex.support.thrift.Profile;
import org.zlex.support.thrift.ProfileService.Iface;

/**
 * 
 * @author snowolf
 * @version 1.0
 * @since 1.0
 */
public class ProfileServiceImpl implements Iface {

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.zlex.support.thrift.ProfileService.Iface#updateName(org.zlex.support
	 * .thrift.Profile, java.lang.String)
	 */
	@Override
	public String updateName(Profile profile, String name) throws TException {
		profile.setName(name);
		return profile.getName();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.zlex.support.thrift.ProfileService.Iface#updateScore(org.zlex.support
	 * .thrift.Profile, int)
	 */
	@Override
	public int updateScore(Profile profile, int score) throws TException {
		profile.setScore(profile.getScore() + score);
		return profile.getScore();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.zlex.support.thrift.ProfileService.Iface#toMap(org.zlex.support.thrift
	 * .Profile)
	 */
	@Override
	public Map<String, String> toMap(Profile profile) throws TException {
		Map<String, String> map = new HashMap<String, String>();
		map.put("name", profile.getName());
		map.put("score", "" + profile.getScore());
		map.put("isEnable", "" + profile.isEnable());
		return map;
	}

}

 

做一个Server实现,“非阻塞&高效二进制编码”:

/**
 * Mar 14, 2013
 */
package org.zlex.support.thrift;

import org.apache.log4j.Logger;

import org.apache.thrift.TProcessorFactory;
import org.apache.thrift.protocol.TCompactProtocol;
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;
import org.zlex.support.thrift.impl.ProfileServiceImpl;

/**
 * 
 * @author snowolf
 * @version 1.0
 * @since 1.0
 */
public class Server {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger.getLogger(Server.class);

	/**
	 * 
	 */
	private int port;

	/**
	 * @param port
	 */
	public Server(int port) {
		this.port = port;
	}

	/**
	 * 
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public void start() {
		try {
			TNonblockingServerSocket socket = new TNonblockingServerSocket(port);
			final ProfileService.Processor processor = new ProfileService.Processor(
					new ProfileServiceImpl());
			THsHaServer.Args arg = new THsHaServer.Args(socket);
			// 高效率的、密集的二进制编码格式进行数据传输
			// 使用非阻塞方式,按块的大小进行传输,类似于 Java 中的 NIO
			arg.protocolFactory(new TCompactProtocol.Factory());
			arg.transportFactory(new TFramedTransport.Factory());
			arg.processorFactory(new TProcessorFactory(processor));
			TServer server = new THsHaServer(arg);
			logger.info("服务启动-使用:非阻塞&高效二进制编码");
			server.serve();
		} catch (TTransportException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

 

服务器测试用例:

/**
 * Mar 14, 2013
 */
package org.zlex.support.thrift;

import org.junit.Before;
import org.junit.Test;

/**
 * 
 * @author snowolf
 * @version 1.0
 * @since 1.0
 */
public class ServerTest {
	public final static int PORT = 9999;

	private Server server;

	@Before
	public void init() {
		server = new Server(PORT);
	}

	@Test
	public void test() {
		server.start();
	}
}

 

客户端测试用例:

/**
 * Mar 14, 2013
 */
package org.zlex.support.thrift;

import static org.junit.Assert.*;

import java.util.Map;

import org.apache.thrift.TApplicationException;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TCompactProtocol;
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 org.junit.Test;

/**
 * 
 * @author snowolf
 * @version 1.0
 * @since 1.0
 */
public class ClientTest {
	public final static int PORT = 9999;
	public static final String address = "localhost";
	public static final int clientTimeout = 30000;

	@Test
	public void test() {
		TTransport transport = new TFramedTransport(new TSocket(address, PORT,
				clientTimeout));
		TProtocol protocol = new TCompactProtocol(transport);
		ProfileService.Client client = new ProfileService.Client(protocol);

		try {
			transport.open();
			Profile profile = new Profile();
			profile.setName("Snowolf");
			Map<String, String> map = client.toMap(profile);
			assertEquals(map.get("name"),"Snowolf");

		} catch (TApplicationException e) {
			System.out.println(e.getMessage() + " " + e.getType());
		} catch (TTransportException e) {
			e.printStackTrace();
		} catch (TException e) {
			e.printStackTrace();
		}
		transport.close();
	}
}

 

Client调用Server接口,将Profile对象交由Server处理,转换为Map。

 

如果需要Thirft承载高并发的负载,可以通过nginx来完成负载均衡的实现,详见

Nginx扩展(一):nginx_tcp_proxy_module

 

小记完毕,Go Home!

 

 

 

3
0
分享到:
评论

相关推荐

    the programmer's guide to apache thrift

    Apache Thrift is an open source cross language serialization and RPC framework. With support for over 15 programming languages, Apache Thrift can play an important role in a range of distributed ...

    thrift源码

    thrift源码thrift源码thrift源码thrift源码thrift源码thrift源码thrift源码thrift源码thrift源码thrift源码thrift源码thrift源码thrift源码thrift源码thrift源码thrift源码thrift源码thrift源码thrift源码thrift源码...

    Windows下QT使用Thrift的样例

    网上一直搜不到Windows下QT使用thrift的例子,自己整了个 QT版本 5.8.0 Boost版本 boost_1_61_0 Thrift版本 thrift-0.10.0

    thrift安装

    thrift 安装包。

    使用wireshark抓取thrift协议接口调用

    使用wireshark抓取thrift协议接口调用

    thrift-0.9.2.tar.gz

    thrift,Apache Thrift 0.9.2 版本,解压后直接直接安装,可伸缩的跨语言服务开发框架,命令: 解压命令:tar -zxf thrift-0.9.2.tar.gz 安装命令:./configure --with-lua=no && make && make install 查看版本:...

    Thrift之C++初体验

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

    thrift官方代码+与dubbo集成支持原生thrift协议

    thrift官方代码+与dubbo集成支持原生thrift协议

    Learning.Apache.Thrift.178588274

    Make applications cross-communicate using Apache Thrift! About This Book Leverage Apache Thrift to enable applications written in different programming languages (Java, C++, Python, PHP, Ruby, and so...

    thrift-编译工具

    thrift-编译工具

    java代码使用thrift2操作hbase示例

    java代码使用thrift2操作hbase示例,thrift2连接hbase添加数据,单条查找,删除数据,根据扫描器查找,修改数据等测试实例

    thrift-0.9.3.exe

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

    thrift-0.9.1.exe和thrift-0.9.2.exe

    thrift文件生成工具thrift-0.9.1.exe和thrift-0.9.2.exe压缩包

    thrift-Demo

    thrift一个实例

    unity3d thrift twisted

    unity3d-thrift-twistedunity3d-thrift-twistedunity3d-thrift-twisted

    使用thrift、websocket在javascript和cpp之间建立rpc调用

    使用thrift、websocket在javascript和c++之间建立rpc调用机制。 如果要使用js+html来写界面,cpp来写底层业务逻辑,这就非常有用了。 当然,如果底层不用cpp来写,也可以参考本代码的js对thrift的rpc包装。

    Thrift入门简介

    通俗简单的介绍了什么是thrift,适用于thrift或RPC扫盲。

    用C#和C++写的Apache Thrift的小范例

    本例改编自Apache Thrift教程: http://mikecvet.wordpress.com/2010/05/13/apache-thrift-tutorial-the-sequel/ http://chanian.com/2010/05/13/thrift-tutorial-a-php-client/ 原教程使用的是c++ server和...

    thrift初步了解

    不要认为thrift能在*.thrift文件中定义调度之类的工作 thrift通过IDL(接口描述语言)来生成各种语言需要的接口代码。 执行thrift文件命令: java:thrift-0.9.1.exe --gen java test.thrift java:thrift-0.9.1.exe ...

Global site tag (gtag.js) - Google Analytics