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语言社区

linux 内核同步机制使用

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

49050
来自专栏Java修行之道

SpringMVC中controller接收Json数据

29810
来自专栏Ryan Miao

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

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

504100
来自专栏老码农专栏

Actframework中如何灵活控制JSON响应

9430
来自专栏JavaEE

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

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

15020
来自专栏Golang语言社区

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

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

39780
来自专栏xingoo, 一个梦想做发明家的程序员

Elasticsearch安装

在启动或者安装ES之前,需要先下载JDK 1.7以上的版本,对于2.0来说,要求JDK1.8以上。 检查JDK的版本 使用命令: java -versio...

26060
来自专栏WindCoder

Spring Boot REST API错误处理指南

本来是5号来的文章,无奈最近准备换工作,一直拖着没写,今天搜索偶然看见有人已经翻译完了,由于时间原因这次就直接转载下吧,现附上英文原文及相关信息,最后再附上译文...

26620
来自专栏我是攻城师

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

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

39430
来自专栏玩转JavaEE

SpringMVC常用配置

按:最近公众号文章主要是整理一些老文章,主要是个人CSDN上的博客,也会穿插一些新的技术点。 ---- 关于Spring、SpringMVC我们前面几篇博客都介...

30260

扫码关注云+社区

领取腾讯云代金券