thrift使用入门示例

原创 2015年11月17日 17:57:05

Thrift是apache的RPC框架,支持跨语言的服务。

感觉用起来和WSDL差不多,不过一个是需要写wsdl文件,一个是需要写thrift文件。

使用过程如下:

1.下载thrift,链接:

http://thrift.apache.org/download

2.编写thrift文件,明确指明提供的服务(方法)

shared.thrift

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/**
 * This Thrift file can be included by other Thrift files that want to share
 * these definitions.
 */

namespace cpp shared
namespace d share // "shared" would collide with the eponymous D keyword.
namespace dart shared
namespace java shared
namespace perl shared
namespace php shared
namespace haxe shared

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

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


tutorial.thrift

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

# Thrift Tutorial
# Mark Slee (mcslee@facebook.com)
#
# This file aims to teach you how to use Thrift, in a .thrift file. Neato. The
# first thing to notice is that .thrift files support standard shell comments.
# This lets you make your thrift file executable and include your Thrift build
# step on the top line. And you can place comments like this anywhere you like.
#
# Before running this file, you will need to have installed the thrift compiler
# into /usr/local/bin.

/**
 * 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
 *  i32         Signed 32-bit integer
 *  i64         Signed 64-bit integer
 *  double      64-bit floating point value
 *  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
 *
 * Did you also notice that Thrift supports C style comments?
 */

// Just in case you were wondering... yes. We support simple C comments too.

/**
 * Thrift files can reference other Thrift files to include common struct
 * and service definitions. These are found using the current path, or by
 * searching relative to any paths specified with the -I compiler flag.
 *
 * Included objects are accessed using the name of the .thrift file as a
 * prefix. i.e. shared.SharedObject
 */
include "shared.thrift"

/**
 * Thrift files can namespace, package, or prefix their output in various
 * target languages.
 */
namespace cpp tutorial
namespace d tutorial
namespace dart tutorial
namespace java tutorial
namespace php tutorial
namespace perl tutorial
namespace haxe tutorial

/**
 * Thrift lets you do typedefs to get pretty names for your types. Standard
 * C style here.
 */
typedef i32 MyInteger

/**
 * Thrift also lets you define constants for use across languages. Complex
 * types and structs are specified using JSON notation.
 */
const i32 INT32CONSTANT = 9853
const map<string,string> MAPCONSTANT = {'hello':'world', 'goodnight':'moon'}

/**
 * You can define enums, which are just 32 bit integers. Values are optional
 * and start at 1 if not supplied, C style again.
 */
enum Operation {
  ADD = 1,
  SUBTRACT = 2,
  MULTIPLY = 3,
  DIVIDE = 4
}

/**
 * Structs are the basic complex data structures. They are comprised of fields
 * which each have an integer identifier, a type, a symbolic name, and an
 * optional default value.
 *
 * Fields can be declared "optional", which ensures they will not be included
 * in the serialized output if they aren't set.  Note that this requires some
 * manual management in some languages.
 */
struct Work {
  1: i32 num1 = 0,
  2: i32 num2,
  3: Operation op,
  4: optional string comment,
}

/**
 * Structs can also be exceptions, if they are nasty.
 */
exception InvalidOperation {
  1: i32 whatOp,
  2: string why
}

/**
 * Ahh, now onto the cool part, defining a service. Services just need a name
 * and can optionally inherit from another service using the extends keyword.
 */
service Calculator extends shared.SharedService {

  /**
   * A method definition looks like C code. It has a return type, arguments,
   * and optionally a list of exceptions that it may throw. Note that argument
   * lists and exception lists are specified using the exact same syntax as
   * field lists in struct or exception definitions.
   */

   void ping(),

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

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

   /**
    * This method has a oneway modifier. That means the client only makes
    * a request and does not listen for any response at all. Oneway methods
    * must be void.
    */
   oneway void zip()

}

/**
 * That just about covers the basics. Take a look in the test/ folder for more
 * detailed examples. After you run this file, your generated code shows up
 * in folders with names gen-<language>. The generated code isn't too scary
 * to look at. It even has pretty indentation.
 */



可以把这两个文件和下载的thrift.exe放在同一个目录下。然后cd到这个目录下,执行:

thrift-0.9.3.exe -r --gen py tutorial.thrift

此时就会在该目录下生成gen-py目录。这也是写server和client脚本需要用到的文件目录。


3.在gen-py下新建pyServer.py,内容如下:

import sys, glob
# sys.path.append('gen-py')
# sys.path.insert(0, glob.glob('../../lib/py/build/lib.*')[0])

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.whatOp = work.op
        x.why = 'Cannot divide by 0'
        raise x
      val = work.num1 / work.num2
    else:
      x = InvalidOperation()
      x.whatOp = 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('localhost',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.'


即提供thrift服务,包含ping,add,calculate等方法。在9090端口监听。


4.编写pyClient.py,内容如下:

import sys, glob
# sys.path.append('gen-py')
# sys.path.insert(0, glob.glob('../../lib/py/build/lib.*')[0])

from tutorial import Calculator
from tutorial.ttypes import *

from thrift import Thrift
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol

try:

  # Make socket
  transport = TSocket.TSocket('localhost', 9090)

  # Buffering is critical. Raw sockets are very slow
  transport = TTransport.TBufferedTransport(transport)

  # Wrap in a protocol
  protocol = TBinaryProtocol.TBinaryProtocol(transport)

  # Create a client to use the protocol encoder
  client = Calculator.Client(protocol)

  # Connect!
  transport.open()

  client.ping()
  print 'ping()'

  sum = client.add(1,1)
  print '1+1=%d' % (sum)

  work = Work()

  work.op = Operation.DIVIDE
  work.num1 = 1
  work.num2 = 0

  try:
    quotient = client.calculate(1, work)
    print 'Whoa? You know how to divide by zero?'
  except InvalidOperation, io:
    print 'InvalidOperation: %r' % io

  work.op = Operation.SUBTRACT
  work.num1 = 15
  work.num2 = 10

  diff = client.calculate(1, work)
  print '15-10=%d' % (diff)

  log = client.getStruct(1)
  print 'Check log: %s' % (log.value)

  # Close!
  transport.close()

except Thrift.TException, tx:
  print '%s' % (tx.message)


服务端运行的效果为:


客户端运行的效果为:


版权声明:本文为博主原创文章,未经博主允许不得转载。

Thrift基础使用

1        RPC Client端通过动态代理,根据双方约定的服务接口存根,把要调用的远程接口的名称和接口参数发送到Server端,并获得返回值。其中: Ø        双方持有共同的接口存根...
  • yh880610
  • yh880610
  • 2017年09月10日 11:34
  • 248

由浅入深了解Thrift(一)——Thrift介绍与用法

一、  Thrift简单介绍 1.1、  Thrift是什么?能做什么? Thrift是Facebook于2007年开发的跨语言的rpc服框架,提供多语言的编译功能,并提供多种服务器工作模式;用户通过...
  • hjx_1000
  • hjx_1000
  • 2015年01月16日 16:27
  • 18264

Apache Thrift的简单使用

 Apache Thrift的简单使用---------------------- 1. 简单介绍Thrift是Facebook的一个开源项目,主要是一个跨语言的服务开发框架。它有一个代码生成器来对它...
  • amuseme_lu
  • amuseme_lu
  • 2011年03月20日 12:49
  • 65391

thrift使用总结

Apache Thrift软件框架用于可扩展的跨语言服务开发,简单来说就是RPC远程调用,它是一个完整的 RPC 框架体系。 Thrift支持的数据类型 1.基本类型 bool:布尔值 (tru...
  • qq_27784479
  • qq_27784479
  • 2017年06月14日 18:08
  • 1887

关于thrift的使用

最近使用thrift,遇到的问题在这里说一下.使用的版本是0.10.0 1.thrift不稳定,在客户端发消息,会概率性的抛出异常,然后thrift服务就down掉了,只能一直监听着thrift服务...
  • abc1113
  • abc1113
  • 2017年04月19日 10:38
  • 638

Thrift服务搭建和调用

有住ERP与有住业务系统、成本预算系统对接,按客户要求使用Thrift协议接口服务,简单学习了一下,搭建Thrift服务只要步骤如下: 一、准备必要的文件(jar包和生成Thrift java类的工具...
  • qq_32553271
  • qq_32553271
  • 2017年04月13日 20:03
  • 1352

Thrift使用指南

转载自董的博客,原文出处:http://dongxicheng.org/search-engine/thrift-guide/ 1. 内容概要 本文档比较全面的介绍了thrift(关于th...
  • tangyajun_168
  • tangyajun_168
  • 2011年12月26日 15:40
  • 1444

Thrift使用

Thrift是什么,有什么优势?这里就不阐述了,百度即可。本文旨在于展现Thrift服务搭建和调用的过程,让初学者少走弯路。本文提供完整代码及所需jar和thrift-0.9.3.exe。点击此处下载...
  • xhuzy
  • xhuzy
  • 2016年10月09日 16:13
  • 78

thrift远程调用示例

说明 thrift是apache hadoop的一个子项目,主要是完成跨语言,跨平台的序列化和远程调用。具体的可以参考官方文档: thrift.apache.org 安装 thrift和上次介...
  • wutbiao
  • wutbiao
  • 2015年04月13日 18:29
  • 3540

Thrift使用指南

本文转载自董的博客 1. 内容概要 本文档比较全面的介绍了thrift(关于thrift框架的介绍,参考我这篇文章:Thrift框架介绍)语法,代码生成结构和应用经验。本文主要讲述的对象是...
  • njchenyi
  • njchenyi
  • 2013年05月06日 09:40
  • 7302
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:thrift使用入门示例
举报原因:
原因补充:

(最多只允许输入30个字)