【原创】快速实践跨语言RPC框架- Apache Thrift

这题目一看就是老标题党啦。既然Thrift是一个跨语言的RPC框架,所以本文采用Go和Java来实现,场景是Echo Server,实现十分简单,尽量呈现出Thrift使用的基本流程。

本文将基于Thrift,使用GO来实现一个Echo Server,使用Java来实现一个Echo Client。文中有不对的地方还望大家指出。

1、配置Thrift compiler

本文是在Win10环境下配置的,Thrift 版本是v0.13.0。Thrift compiler 用于编译Thrift脚本文件,生成各种语言的源文件,比如 Go,C++, Java, Python等,开发者将基于编译生成的源文件进行开发。
Thrift compiler 下载

下载完成后,将thrift.exe文件放在任意文件夹就好了。

thrift01.png

可以把当前文件夹添加进path环境变量,方便使用。

path.png

2、编写Thrift文件

使用Thrift 开发RPC服务需要编写Thrift脚本文件,使用的是Thrift接口定义语言 (IDL)。可以通过IDL在文件中定义一些变量,结构体,服务等。具体的语法可以参考官方文档,这里就不展开了。

如下代码块,建立一个echo.thrift文件。

namespace go echo 是命名空间,go表示要应用于Go语言,echo表示编译后的文件会在echo包下。

service表示定义服务,编译后会生成Echo这个接口,接口中有echoHello这个方法,需要服务器端实现。

//echo.thrift
namespace go echo
namespace java echo

service Echo {
  string echoHello(1: string name)
}

3、编译生成Go、Java代码

使用调用thrift编译echo.thrift文件。

#编译命令
thrift -r --gen go  echo.thrift
thrift -r --gen java echo.thrift

编译后生成的Go源文件目录如下,需要重点关注一下echo.go 文件。

gen-go.png

编译后生成的Java源文件目录如下。

gen-java.png

4、用Go开发服务端

echo.go 文件中可以发现Echo接口和EchoHello方法,如下图所示。服务器端要实现这个接口。

server.png

echoHandler.go 中实现了Echo接口,EchoHello方法如下代码块。

//echoHandler.go
type EchoHandler struct {
}

func (echo *EchoHandler) EchoHello(ctx context.Context, name string) (r string, err error) {
   fmt.Println(name, "  access")
   return "hello," + name, nil
}

func NewEchoHandler() *EchoHandler {
   return &EchoHandler{}
}

启动服务端。

//server.go
func main() {
   transport, _ := thrift.NewTServerSocket("localhost:9090")
   handler := NewEchoHandler()
   processor := echo.NewEchoProcessor(handler)
   server := thrift.NewTSimpleServer2(processor, transport)
   _ = server.Serve()
}

5、用Java开发客户端

客户端的操作比较简单。

新建EchoClient.java,配置transport和protocol,就可以调用服务端的服务了,实现如下:

public class EchoClient {
    public static void main(String[] args) throws TException {
        TSocket transport = new TSocket("localhost", 9090);
        transport.open();
        TProtocol protocol = new TBinaryProtocol(transport);

        Echo.Client client = new Echo.Client(protocol);
        String resp = client.echoHello("fly");  //RPC调用服务端的方法

        System.out.println(resp);
        transport.close();
    }
}

运行该程序,远程调用服务器端的echoHello方法,服务器端会返回处理结果,如下图所示。

结果.png

到这里,就已经完成了一个简单的跨语言RPC调用啦。

6、原理简析

如果让你去实现一个RPC框架你会怎么去实现呢?

在没有接触Thrift之前,我有基于Zookeeper,Netty实现过一个简单的RPC调用,Zookeeper起到服务注册与服务发现的作用,Netty负责网络传输。客户端的调用会带上参数封装在自定义的协议里边,把协议通过FastJson序列化之后,通过Netty传输给服务端,服务端处理完成之后再类似地把结果传回给客户端。

其实,Thrift简单的原理也是这样的一个过程。Thrift 包含四个主要的组件:Transport,Protocol,Processor和Server。

  +-------------------------------------------+
  | Server                                    |
  | (single-threaded, event-driven etc)       |
  +-------------------------------------------+
  | Processor                                 |
  | (compiler generated)                      |
  +-------------------------------------------+
  | Protocol                                  |
  | (JSON, compact etc)                       |
  +-------------------------------------------+
  | Transport                                 |
  | (raw TCP, HTTP etc)                       |
  +-------------------------------------------+

Transport层用于服务端与客户端之间的通信。例子中用到的TSocket,TServerSocket,是阻塞型 socket。

Protocol 定义了消息的序列化方式。一般来讲,作为RPC框架,考虑到网络传输的效率,使用二进制的传输协议,这也是thrift默认的传输协议。

Processor负责从输入流中获取请求,将结果写入到输出流中。

Server负责将上述所有功能组合在一起。

7、疑问

写到这里,突然产生了一个疑问,既然有Http请求为什么还要有RPC呢,该怎么去选择使用呢?欢迎小伙伴评论喔。

参考

1、http://thrift.apache.org/tutorial/

2、使用Thrift框架实现C#调用Java服务

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270