Linux

RPC - Thrift Demo

2019-11-25  本文已影响0人  红薯爱帅

1. 前言

解决应用程序与服务器传递数据的问题,大体上分为三类:

其中 RPC 模型,又分成三类:

目前,SOA模型很少在使用,RPC常用的也只有JSON-RPC一种,还有著名的Thrift。
REST模型的资源,在大多情况情况,对应数据库的Table,通过Method很好地区分开了不同的操作。通过API的简洁设计,大大降低了项目开发过程中的沟通成本,提高了前后端开发的效率。因此,REST模型得到了广泛应用。
现在,GraphQL兴起,可以期待下。

本文重点介绍一个Thrift的Demo。

2. Thrift

The Apache Thrift software framework, for scalable cross-language services development, combines a software stack with a code generation engine to build services that work efficiently and seamlessly between C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, OCaml and Delphi and other languages.

Thrift是一个典型的CS(客户端/服务端)结构,客户端和服务端可以使用不同的语言开发。既然客户端和服务端能使用不同的语言开发,那么一定就要有一种中间语言来关联客户端和服务端的语言,没错,这种语言就是IDL(Interface Description Language)。

thrift-layers.png
类型           描述
bool          true, false 
byte          8位的有符号整数 
i16           16位的有符号整数 
i32           32位的有符号整数 
i64           64位的有符号整数 
double        64位的浮点数 
string        UTF-8编码的字符串 
binary        字符数组 
struct        结构体 
list          有序的元素列表,类似于STL的vector 
set           无序的不重复元素集,类似于STL的set 
map           key-value型的映射,类似于STL的map 
exception     是一个继承于本地语言的exception基类 
service       服务,包含多个函数接口(纯虚函数)

3. Thrift Demo

$ tree .
.
├── gen-py
│   ├── helloworld
│   │   ├── constants.py
│   │   ├── HelloWorld.py
│   │   ├── HelloWorld-remote
│   │   ├── __init__.py
│   │   └── ttypes.py
│   └── __init__.py
├── helloworld.thrift
└── my_proj
    ├── client.py
    └── server.py
service HelloWorld {
    string ping(),
    string say(1:string msg)
}
$ docker run -v "$PWD:/data" thrift thrift -o /data --gen py /data/helloworld.thrift
# server.py
import socket
import sys
sys.path.append('../gen-py') 

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

from helloworld import HelloWorld 
from helloworld.ttypes import *

class HelloWorldHandler:  
    def ping(self):   
        return "pong"   
    def say(self, msg):
        ret = "Received: " + msg
        print(ret)    
        return ret
#创建服务端
handler = HelloWorldHandler()
processor = HelloWorld.Processor(handler)
#监听端口
transport = TSocket.TServerSocket("localhost", 9090)
#选择传输层
tfactory = TTransport.TBufferedTransportFactory()
#选择传输协议
pfactory = TBinaryProtocol.TBinaryProtocolFactory()
#创建服务端 
server = TServer.TSimpleServer(processor, transport, tfactory, pfactory) 
print("Starting thrift server in python...")
server.serve()
print("done!")
# client.py
import sys
sys.path.append('../gen-py')

from helloworld import HelloWorld #引入客户端类
from thrift import Thrift 
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol

try:
    #建立socket
    transport = TSocket.TSocket('localhost', 9090)
    #选择传输层,这块要和服务端的设置一致
    transport = TTransport.TBufferedTransport(transport)
    #选择传输协议,这个也要和服务端保持一致,否则无法通信
    protocol = TBinaryProtocol.TBinaryProtocol(transport)
    #创建客户端
    client = HelloWorld.Client(protocol)
    transport.open()

    print("client - ping")
    print("server - " + client.ping())

    print("client - say") 
    msg = client.say("Hello!")
    print("server - " + msg)
    #关闭传输
    transport.close()
#捕获异常
except Thrift.TException as ex:
    print("%s" % (ex.message))

4. Demo Test

$ python3 server.py 
Starting thrift server in python...
Received: Hello!
$ python3 client.py 
client - ping
server - pong
client - say
server - Received: Hello!

5. Refers

上一篇 下一篇

猜你喜欢

热点阅读