`
uule
  • 浏览: 6303579 次
  • 性别: Icon_minigender_1
  • 来自: 一片神奇的土地
社区版块
存档分类
最新评论

thrift总结 - 跨语言服务开发

 
阅读更多

官网

IBM-Apache Thrift - 可伸缩的跨语言服务开发框架

thrift的使用介绍

Thrift入门及Java实例演示

一步步学会Thrift服务搭建和调用

Thrift是一个RPC的框架

 

Thrift server端的几种工作模式分析

 

RPC 

 

POM:

<dependency>
  <groupId>org.apache.thrift</groupId>
  <artifactId>libthrift</artifactId>
  <version>0.9.2</version>
</dependency>

 

Thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发

thrift允许你定义一个简单的定义文件中的数据类型和服务接口。以作为输入文件,编译器生成代码用来方便地生成RPC客户端和服务器通信的无缝跨编程语言。

 

支持多种语言之间的RPC方式的通信

php语言client可以构造一个对象,调用相应的服务方法来调用java语言的服务 ,跨越语言的C/S RPC调用 。

 

thrift可以用来快速的开发基于Socket的接口工具。简单的说,就是可以让人快速的写Socket Server和Client。其实不用thrift开发socket也不难,

那么为什么要用thrift开发呢?主要有两个原因,一个是因为thrift本身帮你封装了很多基本的东西,你不需要自己去写socket里面的bind,accept之类的,以及他们的逻辑。可以很快速的开发基于进程的,线程的,SSL的socket。第二个理由是标准化,跨语言和跨平台,windows不算在其中。主要是在各种Posix兼容的操作系统中都可以不需要改造基本直接可用,支持的语言种类也很多,基本你会写的,他都支持。你不会写的,他也支持。

 

Thrift与其他传输方式的比较

    xml与JSON相比体积太大,但是xml传统,也不算复杂。

    json 体积较小,新颖,但不够完善。

    thrift 体积超小,使用起来比较麻烦,不如前两者轻便,但是对于1.高并发、2.数据传输量大、3.多语言环境, 满足其中2点使用 thrift还是值得的。

 

 

建立一个java rmi的流程  : 

  1、定义一个服务调用接口 。 

  2、server端:接口实现---impl的实例---注册该服务实现(端口)---启动服务。 

  3、client端:通过ip、端口、服务名,得到服务,通过接口来调用 。 

  4、rmi数据传输方式:java对象序列化 。 

 

 

Thrift:

thrift --gen <language> <Thrift filename>

 

To recursivly generate source code from a Thrift file and all other Thrift files included by it, run

thrift -r --gen <language> <Thrift filename>

 

     thrift-0.7.0.exe  -r -gen  java  TestThrift.thrift    生成java 代码 

     thrift-0.7.0.exe  -r -gen  php   TestThrift.thrift    生成php代码 

     thrift-0.7.0.exe  -r -gen  py    TestThrift.thrift    生成python代码 

     thrift-0.7.0.exe  -r -gen  as3   TestThrift.thrift    生成as3代码 

     thrift-0.7.0.exe  -r -gen  cpp   TestThrift.thrift    生成C++代码 

 

 

基本概念

 

1.数据类型

 

基本类型:

bool:布尔值,true 或 false,对应 Java 的 boolean

byte:8 位有符号整数,对应 Java 的 byte

i16:16 位有符号整数,对应 Java 的 short

i32:32 位有符号整数,对应 Java 的 int

i64:64 位有符号整数,对应 Java 的 long

double:64 位浮点数,对应 Java 的 double

string:utf-8编码的字符串,对应 Java 的 String

 

结构体类型:

struct:定义公共的对象,类似于 C 语言中的结构体定义,在 Java 中是一个 JavaBean

 

容器类型:

list:对应 Java 的 ArrayList

set:对应 Java 的 HashSet

map:对应 Java 的 HashMap

 

异常类型:

exception:对应 Java 的 Exception

 

服务类型:

service:对应服务的类

 

2.服务端编码基本步骤:

 

实现服务处理接口impl

创建TProcessor

创建TServerTransport(TServerSocket)

创建TProtocol

创建TServer

启动Server

 

3.客户端编码基本步骤:

 

创建Transport

创建TProtocol

基于TTransport和TProtocol创建 Client

调用Client的相应方法

 

4.数据传输协议

 

TBinaryProtocol : 二进制格式.

TCompactProtocol : 压缩格式

TJSONProtocol : JSON格式

TSimpleJSONProtocol : 提供JSON只写协议, 生成的文件很容易通过脚本语言解析

tips:客户端和服务端的协议要一致

 

 

服务端类型:

TSimpleServer

简单的单线程服务模型,一般用于测试。

 

TThreadPoolServer 

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

 

TNonblockingServer:

使用非阻塞式IO,服务端和客户端需要指定 TFramedTransport 数据传输的方式。

 

例子:

1、thrift生成代码

使用thrift需要先定义接口文件demo.thrift,在thrift里简称叫IDL,全称叫Interface Description Language,接口描述语言。接口描述语言里面需要定义接口中所使用的数据类型,方法等等。

 

使用 Thrift 工具编译 demo.thrift,就会生成相应的 HelloWorldService.java 文件该文件包含了在 demo.thrift 文件中描述的服务 HelloWorldService 的接口定义,即 HelloWorldService.Iface 接口,以及服务调用的底层通信细节,包括客户端的调用逻辑 HelloWorldService.Client 以及服务器端的处理逻辑 HelloWorldService.Processor,用于构建客户端和服务器端的功能。

 

创建一个简单的服务 HelloWordService。首先根据 Thrift 的语法规范编写脚本文件 demo.thrift:

namespace java com.service.demo  
 service HelloWorldService{ 
	  string sayHello(1:string username)
	  
	  i32 helloInt(1:i32 para) 
	  bool helloBoolean(1:bool para) 
	  void helloVoid() 
	  string helloNull() 
 }

 

thrift-0.9.2.exe 是官网提供的windows下编译工具,运用这个工具生成相关代码:

 

thrift-0.9.2.exe -r -gen java demo.thrift 

生成文件目录:\gen-java\com\service\demo\HelloWorldService.java

  

 将架包导入工程中,并将生成的HelloWordService.java拷入

 

2、 实现接口Iface

 

import org.apache.thrift.TException;

public class HelloWorldServiceImpl implements HelloWorldService.Iface{

	@Override
	public String sayHello(String username) throws TException {
		return "Hi," + username + " this is my first thrift demo.";
	}
	
	@Override
	public boolean helloBoolean(boolean para) throws TException {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public int helloInt(int para) throws TException {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public String helloNull() throws TException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void helloVoid() throws TException {
		// TODO Auto-generated method stub
		
	}
}

 

3、创建服务端实现代码:

 

package com.common.test;

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.transport.TServerSocket;

public class HelloServiceServer {
	public static final int SERVER_PORT = 8090;
	 
	public static void startServer() {
		try {
			 System.out.println("HelloWorld TThreadPoolServer start ....");
 
			 
			 TProcessor processor = new HelloWorldService.Processor(new HelloWorldServiceImpl());
 
			 TServerSocket serverTransport = new TServerSocket(SERVER_PORT);
			 //TServerTransport serverTransport = new TServerSocket( new InetSocketAddress("0.0.0.0",9813));  
			 
			 TThreadPoolServer.Args ttpsArgs = new TThreadPoolServer.Args(serverTransport);
			 ttpsArgs.processor(processor);
			 ttpsArgs.protocolFactory(new TBinaryProtocol.Factory());
 
			// 线程池服务模型,使用标准的阻塞式IO,预先创建一组线程处理请求。
			 TServer server = new TThreadPoolServer(ttpsArgs);
			 server.serve();
 			 
			/* 或者:
			Args trArgs=new Args(serverTransport);  
            trArgs.processor(processor);  
            
            //使用二进制来编码应用层的数据  
            trArgs.protocolFactory(new TBinaryProtocol.Factory(true, true));  
            //使用普通的socket来传输数据  
            //trArgs.transportFactory(new TTransportFactory());  
            
            TServer server = new TThreadPoolServer(trArgs);  */
	            
			 System.out.println("Start server on port "+SERVER_PORT+"..."); 
		} catch (Exception e) {
			System.out.println("Server start error!!!");
			e.printStackTrace();
		}
	}
 
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		startServer();
	}
}

 HelloWorld TThreadPoolServer start ....

 

4、创建客户端实现代码:

package com.common.test;

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

public class HelloServiceClient {

	public static final String SERVER_IP = "192.168.3.76";
	public static final int SERVER_PORT = 8090;
	public static final int TIMEOUT = 30000;

	/**
	 *
	 * @param userName
	 */
	public static void startClient(String userName) {
		TTransport transport = null;
		try {
			transport = new TSocket(SERVER_IP, SERVER_PORT, TIMEOUT);
			// 协议要和服务端一致
			TProtocol protocol = new TBinaryProtocol(transport);
			// TProtocol protocol = new TCompactProtocol(transport);
			// TProtocol protocol = new TJSONProtocol(transport);
			
			HelloWorldService.Client client = new HelloWorldService.Client(protocol);
			transport.open();
			
			String result = client.sayHello(userName);			
			System.out.println(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) {
		startClient("Michael");

	}
}

 Hi,Michael this is my first thrift demo.

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics