首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 开源软件 >

Thrift初记

2013-03-25 
Thrift小记Thrit用的不多,也不够深入,这里小记一笔。关于Thrift环境如何安装,可以参考官网。?Thrit跟Java有

Thrift小记

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

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

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 */

?我就不罗嗦了了,能看到这里的都能自动理解。Thrift初记

?

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

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

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

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

namespace java org.zlex.support.thriftstruct 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) */@Overridepublic 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) */@Overridepublic 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) */@Overridepublic 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 中的 NIOarg.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;@Beforepublic void init() {server = new Server(PORT);}@Testpublic 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;@Testpublic 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。

?

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

Nginx扩展(一):nginx_tcp_proxy_module

?

小记完毕,Go Home!

?

?

?

热点排行