`
mj4d
  • 浏览: 301910 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

thrift:idl描述和跨语言的web服务

    博客分类:
  • rpc
阅读更多

从上文的描述我们知道需要两个步骤:

一、编写idl描述性

 

thrift 采用IDL(Interface Definition Language)来定义通用的服务接口,并通过生成不同的语言代理实现来达到跨语言、平台的功能。在thrift的IDL中,我们需要关注一下几点:

1、基本类型

与java中的char,int,long等基本类型一样,IDL中也有用来描述基本类型的定义

  • bool 表示一个布尔值,取true或false
  • byte 表示一个带符号的字节
  • i16 表示一个带符号的16位整形
  • i32 表示一个带符号的32位整形
  • i64 表示一个带符号的64位整形
  • double 表示一个带符号的64位整形
  • string 表示一个不可知编码的文本或二进制串

 

2、结构

结构定义了一个通用的对象以此来跨语言。主要采用struct来描述。如下我们定义了一个User对象:

struct User {
    1: i16 gender = 1,
    2: string username,
    3: string password,
    4:i32 id
}

上面的结构定义与C语言的结构描述很相同,每个字段都有一个唯一标识:1,2,3,4(处于版本管理的原因,推荐使用上唯一标识)。同时还可以有默认值。可以将结构的fields设置为optional,即如果在没有设置值时将不会序列化

 

 

3、容器

thrift的容器是强类型容器,能够与常用语言中的容器想对应,并可使用java泛型的方式进行标注。在thrift中提供了三种容器:

1、list<type> 一个有序元素列表。可翻译为java ArrayList或STL的vector,或者脚本语言中的原生数组,可包含重复数据

2、set<type> 一个无序不重复元素集。与STL的set,java的HashSet,Python的set,或者PHP/Ruby中的原生dictionary

3、map<type1,type2> 一个主键唯一键值映射表,翻译为STL的map,java HashMap,Python dictionary

 

4、异常

与结构的声明一致,唯一不同的是用exception关键字

exception NotFoundException{
    1:i16 errorType,
    2:string message
}

 

 

5、服务

一个服务的定义在语义上相当于面向对象编程中的一个接口。服务的定义如下:

service <name> {
  <returntype> <name> (<arguments>)[throws (<exceptions>)]
  ...
}

 在方法的声明中有一个oneway修饰符,表示客户端只会触发一个请求,而不会监听任何响应,oneway的方法必须是void:

oneway void zip()

一个例子

service UserService{
  void saveUser(1:User user),
  User get(1:i32 id) throws (1:NotFoundException nfe)
}

 同时service也可以从另外的service继承,需要使用关键字extends,这与java的继承关键字一样:

service Calculator extends shared.SharedService 

 

二、其他的说明

1、include

通过include引用其他的thrift文件,默认在当前路径下寻找,也可以在相对路径下寻找,需要通过编译参数-I来设置

 

2、namespace 与java的package作用一样:

namespace java org.java.codelib.thrift.sa
namespace python org.java.codelib.thrift.sa

 上面指定了java和python的package,在只有--gen java/python时将会生产响应的package

 

3、指定常量

const i32 INT32CONSTANT = 9853
const map<string,string> MAPCONSTANT = {'hello':'world', 'goodnight':'moon'}

或枚举:

enum Operation {
  ADD = 1,
  SUBTRACT = 2,
  MULTIPLY = 3,
  DIVIDE = 4
}

 三、一个例子

下面的例子是thrift分发包中的tutorial,这里对package做了些修改,其他保持不变。这里分别生成python和java的代码,服务端采用python客户端用java来实现跨语言的调用

1、shared.thrift

 

namespace java org.java.codelib.thrift.sa
namespace py shared

struct SharedStruct {
	1: i32 key
	2: string value
}

service SharedService {
	SharedStruct getStruct(1: i32 key)
}

 

2、tutorial.thrift

 

include "shared.thrift"

namespace java org.java.codelib.thrift.sa
namespace py tutorial

typedef i32 MyInteger

const i32 INT32CONSTANT = 9853
const map<string,string> MAPCONSTANT = {'hello':'world', 'goodnight':'moon'}

enum Operation {
	ADD = 1,
	SUBTRACT = 2,
	MULTIPLY = 3,
	DIVIDE = 4
}

struct Work {
  	1: i32 num1 = 0,
  	2: i32 num2,
  	3: Operation op,
  	4: optional string comment,
}

exception InvalidOperation {
  	1: i32 what,
  	2: string why
}

service Calculator extends shared.SharedService {

   	void ping(),

   	i32 add(1:i32 num1, 2:i32 num2),

   	i32 calculate(1:i32 logid, 2:Work w) throws (1:InvalidOperation ouch),

   	oneway void zip()
}

 

3、生成python和java的代理实现代码

thrift>thrift-0.9.0.exe --gen py shared.thrift
thrift>thrift-0.9.0.exe --gen py tutorial.thrift
thrift>thrift-0.9.0.exe --gen java shared.thrift
thrift>thrift-0.9.0.exe --gen java tutorial.thrift

4、PythonServer.py作为服务端python的实现:

import sys
sys.path.append('../gen-py')

from tutorial import Calculator
from tutorial.ttypes import *

from shared.ttypes import SharedStruct

from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.server import TServer

class CalculatorHandler:
  def __init__(self):
    self.log = {}

  def ping(self):
    print 'ping()'

  def add(self, n1, n2):
    print 'add(%d,%d)' % (n1, n2)
    return n1+n2

  def calculate(self, logid, work):
    print 'calculate(%d, %r)' % (logid, work)

    if work.op == Operation.ADD:
      val = work.num1 + work.num2
    elif work.op == Operation.SUBTRACT:
      val = work.num1 - work.num2
    elif work.op == Operation.MULTIPLY:
      val = work.num1 * work.num2
    elif work.op == Operation.DIVIDE:
      if work.num2 == 0:
        x = InvalidOperation()
        x.what = work.op
        x.why = 'Cannot divide by 0'
        raise x
      val = work.num1 / work.num2
    else:
      x = InvalidOperation()
      x.what = work.op
      x.why = 'Invalid operation'
      raise x

    log = SharedStruct()
    log.key = logid
    log.value = '%d' % (val)
    self.log[logid] = log

    return val

  def getStruct(self, key):
    print 'getStruct(%d)' % (key)
    return self.log[key]

  def zip(self):
    print 'zip()'

handler = CalculatorHandler()
processor = Calculator.Processor(handler)
transport = TSocket.TServerSocket(port=9090)
tfactory = TTransport.TBufferedTransportFactory()
pfactory = TBinaryProtocol.TBinaryProtocolFactory()

server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)

# You could do one of these for a multithreaded server
#server = TServer.TThreadedServer(processor, transport, tfactory, pfactory)
#server = TServer.TThreadPoolServer(processor, transport, tfactory, pfactory)

print 'Starting the server...'
server.serve()
print 'done.'

5、CalculatorClient作为java的客户端实现:

public class CalculatorClient {

    public static void main(String[] args) {
        TTransport transport;
        try {
            transport = new TSocket("localhost", 9090);
            TProtocol protocol = new TBinaryProtocol(transport);
            Calculator.Client client = new Calculator.Client(protocol);
            transport.open();
            System.out.println(client.add(12, 20));
            transport.close();
        } catch (TTransportException e) {
            e.printStackTrace();
        } catch (TException e) {
            e.printStackTrace();
        }
    }

}

6、更多例子见thrift分发包下的tutorial

分享到:
评论

相关推荐

    thrift总结 - 跨语言服务开发

    Thrift是一种开源的跨语言服务开发框架,由Facebook于2007年创建,后来贡献给了Apache基金会,成为Apache顶级项目。它旨在提供一个高效、轻量级的机制,允许编程语言之间进行定义良好、类型安全、高性能的RPC...

    Laravel开发-thrift-laravel

    1. **Thrift简介**:Thrift是一种“远程过程调用”(RPC)框架,它通过定义一种中间语言(IDL)来描述服务接口,然后自动生成各种编程语言的客户端和服务端代码,使得不同语言之间的服务调用变得简单。 2. **Thrift...

    Thrift 使用

    Thrift是一种开源的跨语言服务开发框架,由Facebook于2007年设计并发布,其初衷是为了在大规模分布式系统中解决高效的通信问题。Thrift允许开发者定义数据类型和服务接口,然后自动生成代码,实现这些服务在不同编程...

    gunicorn_thrift:用于gunicorn的python节俭服务器插件

    Thrift是一种跨语言的服务开发框架,它能够通过定义服务接口和数据类型来生成多语言的客户端和服务器代码,实现高效、简洁的RPC(远程过程调用)通信。 Gunicorn,全称Green Unicorn,是一款广泛使用的Python WSGI...

    GenThrift:在线编译thrift IDL文件的web应用

    Thrift是一种开源的跨语言服务开发框架,由Facebook最初开发,用于构建高效、可扩展的分布式系统。Thrift通过代码生成器将IDL文件转换为多种编程语言的客户端和服务器端代码,如Java、Python、C++等。 GenThrift的...

    thrift-0.9.2.tar.gz

    Apache Thrift 是一个开源的跨语言服务开发框架,它的核心在于提供了一种高效、灵活的序列化机制,以及一套强大的接口定义语言(IDL),用于构建可扩展的服务。Thrift 的设计目的是解决大型分布式系统中不同编程语言...

    Thrift--JSClient

    Apache Thrift是一种软件框架,用于构建跨语言的服务。它通过定义一个中间表示(IDL,接口定义语言)来构建服务,然后自动生成各种编程语言的代码,使得不同语言之间可以方便地进行通信。在这个场景中,"JSClient"指...

    thrift实现http协议案例

    Thrift是一种高效的、跨语言的服务框架,最初由Facebook开发,现在是Apache的顶级项目。它提供了强大的代码生成工具,可以从接口定义文件(IDL)生成多种编程语言的客户端和服务端代码,使得不同语言之间可以轻松地...

    flume通过thrift协议收集日志-Python

    Thrift 是一个跨语言的服务框架,它允许在不同的编程语言之间进行高效的数据序列化和通信。 首先,我们需要了解 Flume 的基本架构。Flume 由源(Source)、通道(Channel)和 sink 组成。Source 负责接收数据,...

    thrift 生成的java包 全部的

    Thrift 是一个开源的跨语言服务开发框架,由 Facebook 开发并贡献给了 Apache 基金会。它允许程序员定义一种接口定义语言(IDL),这种语言可以被编译成多种编程语言的代码,包括 Java。在给定的压缩包文件中,包含...

    一种基于Thrift的跨平台单点登录实现方法_韩冰.pdf

    Thrift通过定义接口描述语言(IDL)来规范服务的结构,然后自动生成多种编程语言的代码,使得服务提供者和服务消费者能够轻松地在不同的平台上进行交互。Thrift不仅支持远程过程调用(RPC),还处理数据序列化和反...

    Apache Thrift说明

    Thrift 使用 Interface Definition Language (IDL) 来描述数据结构和服务接口,这使得开发者可以在不关心底层通信细节的情况下专注于业务逻辑。IDL 文件被编译后,Thrift 提供的编译器会生成对应编程语言的客户端和...

    Python库 | gunicorn_thrift-0.2.13-py2-none-any.whl

    它通过定义一种中间表示(IDL,Interface Definition Language)来描述服务接口,然后自动生成不同语言(包括Python)的客户端和服务端代码。Thrift的主要优点是能够轻松实现分布式系统间的高效通信,支持多种传输...

    Thrift转SpringHttpInvoker

    它通过定义IDL(接口定义语言)文件来描述服务接口,然后自动生成各种语言的客户端和服务端代码。这种模式使得Thrift在分布式系统中能够提供低延迟、高吞吐量的通信。然而,Thrift的缺点是需要额外的服务器端处理和...

    thrift with memfunc and uid generator

    Thrift是一种开源的跨语言服务开发框架,由Facebook于2007年开发,后来捐赠给了Apache软件基金会。它的核心功能是提供了一种高效的序列化和通信协议,使得不同编程语言之间可以方便地进行数据交换和服务调用。在这个...

    ticket_web.zip

    Thrift通过定义一种中间语言(IDL)来描述服务接口,然后自动生成对应语言的客户端和服务器端代码,使得不同编程语言之间可以方便地进行通信。在ticket_web项目中,Thrift可能被用于构建服务端,提供跨语言的API,以...

    util-thrift_2.9.2-6.9.0.zip

    Thrift是一种开源框架,由Facebook开发并贡献给Apache软件基金会,主要用于构建跨语言的服务。它允许您定义数据类型和服务接口,然后自动生成在各种编程语言中使用的代码,以便于进行高效、低级别的二进制通信。 ...

    php连接hive thrift的lib依赖包

    Thrift是Facebook开源的一种高性能、可扩展性的跨语言服务开发框架,它允许定义服务接口,然后生成多种编程语言的代码,使得不同语言之间可以进行高效通信。 标题“php连接hive thrift的lib依赖包”指的是在PHP环境...

    thrift-typescript-servlet-example:Thrift、TypeScript、Servlet

    在这个名为"thrift-typescript-servlet-example"的项目中,我们将探讨如何将它们集成以实现一个高效的跨语言服务通信系统。 首先,让我们深入了解每个组件: 1. **Thrift**:Thrift是由Facebook开发的一种开源跨...

Global site tag (gtag.js) - Google Analytics