Thrift入门实践

简介

Thrift是由facebook研发,用于各服务之间RPC的一个跨语言通信框架。C/S架构

Thrift IDL

为了能够把不同的语言连接在一起,就必须要有一种“中间语言”,来关联客户端和服务端的两种不同语言。

这种规范语言就是IDL(Interface Description Language),接口定义语言。

具体的语法、定义参考下文,基本是C风格

生成代码

在编写好IDL之后,使用thrift的命令就可以生成对应语言的框架。

e.g IDL文件:HelloWorld.thrift

namespace py thrift_test.hello

enum RequestType {
   SAY_HELLO,   //问好
   QUERY_TIME,  //询问时间
}

struct Request {
   1: required RequestType type;  // 请求的类型,必选
   2: required string name;       // 发起请求的人的名字,必选
   3: optional i32 age;           // 发起请求的人的年龄,可选
}

exception RequestException {
   1: required i32 code;
   2: optional string reason;
}

// 服务名
service HelloWordService {
   string doAction(1: Request request) throws (1:RequestException qe); // 可能抛出异常。
}

执行命令生成对应的代码框架。执行成功后将在同级目录下产生一个文件夹,内部构如下:

gen-py
├── __init__.py
└── thrift_test
    ├── __init__.py
    └── hello
        ├── HelloWordService-remote
        ├── HelloWordService.py
        ├── __init__.py
        ├── constants.py
        └── ttypes.py

其中里包含了在IDL里定义好的各种数据类型对应封装的Python类,包含了所有定义的常量,则定义对应Service的完整描述,包括接口定义(),Client的调用桩等。

编写实现

对应语言的框架生成好之后,需要做的就是编写具体的实现了,以python为例,就是要实现对应里的方法,作为handler和其他各种组件组合,从而生成服务端代码。

以下是具体的例子

编写

# -*- coding: utf-8 -*-

import datetime

from thrift_test.hello import ttypes
from thrift_test.hello import HelloWordService
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.server import TServer

__HOST = 'localhost'
__PORT = 9577


class HelloWordHandler(object):
    def doAction(self, request):
        ret_msg = ''
        if request.type == ttypes.RequestType.SAY_HELLO:
            ret_msg = 'Hello %s, we received your msg' % request.name
        elif request.type == ttypes.RequestType.QUERY_TIME:
            ret_msg = "current_time: " + str(datetime.datetime.now())
        print 'get request: %s' % request
        return ret_msg


handler = HelloWordHandler()
processor = HelloWordService.Processor(handler)
transport = TSocket.TServerSocket(__HOST, __PORT)
tfactory = TTransport.TBufferedTransportFactory()
pfactory = TBinaryProtocol.TBinaryProtocolFactory()

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

print "starting server..."

server.serve()

print "done"

编写

# -*- coding: utf-8 -*-

import datetime

from thrift_test.hello import ttypes
from thrift_test.hello import HelloWordService
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.server import TServer

__HOST = 'localhost'
__PORT = 9577


class HelloWordHandler(object):
    def doAction(self, request):
        ret_msg = ''
        if request.type == ttypes.RequestType.SAY_HELLO:
            ret_msg = 'Hello %s, we received your msg' % request.name
        elif request.type == ttypes.RequestType.QUERY_TIME:
            print "type query"
            ret_msg = "current_time: " + str(datetime.datetime.now())
        print 'get request: %s' % request
        return ret_msg


handler = HelloWordHandler()
processor = HelloWordService.Processor(handler)
transport = TSocket.TServerSocket(__HOST, __PORT)
tfactory = TTransport.TBufferedTransportFactory()
pfactory = TBinaryProtocol.TBinaryProtocolFactory()

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

print "starting server..."

server.serve()

print "done"

liuminghao@n8-160-227:~/repos/thrift_test/demo$ cat client.py 
# -*- coding:utf-8
from thrift_test.hello import HelloWordService
from thrift_test.hello.ttypes import Request,RequestType
from thrift import Thrift
from thrift.transport import TSocket, TTransport
from thrift.protocol import TBinaryProtocol

try:
    transport = TSocket.TSocket('localhost',9577)
    transport = TTransport.TBufferedTransport(transport)
    protocol = TBinaryProtocol.TBinaryProtocol(transport)
    client = HelloWordService.Client(protocol)
    transport.open()

    req = Request(RequestType.SAY_HELLO,"mark",12)

    print "request 1"

    msg = client.doAction(req)

    print "server msg 1: " + msg 

    req = Request(RequestType.QUERY_TIME,"marky")

    print "request 2"

    msg = client.doAction(req)

    print "server msg 2: " + msg 

    transport.close()

except Thrift.TException as e:
    print "exception: " + e.message 

先运行再执行,结果如下:

request 1
server msg 1: Hello mark, we received your msg
request 2
server msg 2: current_time: 2018-01-15 15:14:40.800472

如上即为一个ThriftRPC的基本使用示范。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Golang语言社区

Golang同步:锁的使用案例详解

互斥锁 互斥锁是传统的并发程序对共享资源进行访问控制的主要手段。它由标准库代码包sync中的Mutex结构体类型代表。只有两个公开方法 Lock Unlock ...

3828
来自专栏小勇DW3

Spring的原理性总结

Bean的生命过程可以借鉴Servlet的生命过程,了解其生命过程对于不管是思想还是以后的使用都很有帮助;

1.5K5
来自专栏我是攻城师

Java并发之高级自旋锁CLH锁和MCS锁

自旋锁(spin lock)是一个典型的对临界资源的互斥手段,自旋锁是基于CAS原语的,所以它是轻量级的同步操作,它的名称来源于它的特性。自旋锁是指当一个线程尝...

2123
来自专栏Java修行之道

SpringMVC中controller接收Json数据

1501
来自专栏SDNLAB

OpenDaylight Carbon二次开发实用指南

通过本文你将知道: Maven Archetype的基本原理以及如何使用Maven Archetype生成适用于不同版本的ODL子项目。 本文将着重讲解cli命...

43215
来自专栏Golang语言社区

linux 内核同步机制使用

Linux 内核中的同步机制:原子操作、信号量、读写信号量、自旋锁的API、大内核锁、读写锁、大读者锁、RCU和顺序锁。 1、介绍 在现代操作系统里,同一时间...

3335
来自专栏Kirito的技术分享

使用spring validation完成数据后端校验

前言 数据的校验是交互式网站一个不可或缺的功能,前端的js校验可以涵盖大部分的校验职责,如用户名唯一性,生日格式,邮箱格式校验等等常用的校验。但是为了避免用户...

95112
来自专栏Ryan Miao

springmvc学习笔记--json--返回json的日期格式问题

(一)输出json数据 springmvc中使用jackson-mapper-asl即可进行json输出,在配置上有几点: 1.使用mvc:annotation...

44010
来自专栏JavaEE

Thymeleaf的使用前言:一、thymeleaf简介:二、thymeleaf标准方言:三、thymeleaf与springboot集成案例:总结:

最近听说thymeleaf好像也挺流行的,还说是spring官方推荐使用,那thymeleaf究竟是什么呢?spring为什么推荐用它呢?怎么用呢?本文将为你揭...

1312
来自专栏向治洪

Myexclipse创建Junit测试

. 下载JUnit的jar文件,下载地址在这里 2. 在MyEclipse中新建一个要测试的项目HelloJUnit 3. 添加一个要测试的类HelloJ...

1879

扫码关注云+社区