Thrift 的若干问题记录
Thrift 官网
配置安装前的环境
http://thrift.apache.org/docs/install/
注意事项 1
对于 automake 的安装,一般使用 $ sudo apt-get install automake 或 $ sudo yum install automake 后,会自动安装一系列工具,比如:aclocal, autoscan, autoconf, autoheader, automake, 这些工具一般都是匹配或者版本兼容的。
我为了使用最新版本的 automake,采用源码安装后,只会使上述 automake 和 aclocal 升级到最新版,所以出现了版本不兼容问题。
$ which automake /usr/local/bin/automake $ which aclocal /usr/local/bin/aclocal $ which autoscan /usr/bin/autoscan $ which autoconf /usr/bin/autoconf $ which autoheader /usr/bin/autoheader
导致在编译 Thrift 时,configure 出现错误信息:
./configure: line 18645: syntax error near unexpected token `QT5,'
./configure: line 18645: ` PKG_CHECK_MODULES(QT5, Qt5Core >= 5.0, Qt5Network >= 5.0,'
解决方法是,卸载编译安装的 automake 及附属工具,采用包管理器默认的组合。
注意事项 2
执行 bootstrap.sh 可能会有如下 warning,
$ ./bootstrap.sh make distclean... ok Unescaped left brace in regex is deprecated, passed through in regex; marked by <-- HERE in m/\${ <-- HERE [^\}]*}/ at /usr/bin/autoscan line 361. $ autoscan --version Unescaped left brace in regex is deprecated, passed through in regex; marked by <-- HERE in m/\${ <-- HERE [^\}]*}/ at /usr/bin/autoscan line 361. autoscan (GNU Autoconf) 2.69 Copyright (C) 2012 Free Software Foundation, Inc.
...
$ perl --version This is perl 5, version 22, subversion 1 (v5.22.1) built for x86_64-linux-gnu-thread-multi (with 73 registered patches, see perl -V for more detail) Copyright 1987-2015, Larry Wall ...
对这个 warning 的解释如下图,详见 https://unix.stackexchange.com/questions/238539/automake-error-unescaped-left-brace-in-regex-is-deprecated
解压缩源码包,编译安装
$ ./bootstrap.sh # 查看可配置的选项(optional) $ ./configure --help # 因为一般 Linux 默认的 Python 为 Python2,所以对使用 Python3,如果配置保留默认的 --with-py3 并设置 --with-python=no,经测试, 并不会有 Python3 的编译。所以这里采用迂回的方法,在 config 前,首先将 /usr/bin/python 链接到 /usr/bin/python3.6,这样 Thrift 就能自动识别 Python 为 Python3。编译安装完成后,再将链接改回默认的 /usr/bin/python2.7
$ sudo ln -fs /usr/bin/python3.5 /usr/bin/python
# 取消不需要支持的语言(因为我只使用 C, C++, Python3,所以这里仅保留默认的 --with-c_glib, --with-cpp, --with-python),如果编译器较旧,可能需要加配置选项 CXXFLAGS='-std=c++11' $ ./configure --with-as3=no --with-qt5=no --with-csharp=no --with-java=no --with-erlang=no --with-nodejs=no --with-nodets=no --with-lua=no --with-perl=no --with-php=no --with-php_extension=no --with-py3=no --with-dart=no --with-ruby=no --with-haskell=no --with-go=no --with-swift=no --with-rs=no --with-cl=no --with-haxe=no --with-dotnetcore=no --with-d=no $ make $ sudo make install
# 恢复系统 Python 环境
$ sudo ln -fs /usr/bin/python2.7 /usr/bin/python
遇到问题
编译安装后,发现对于 Python3,没有把必要的 Python 库文件写入到 /usr/local/lib64/python3.6/site-packages/thrift
所以,对于 Python3,需要手动安装 thrift 库,
$ sudo pip3 install thrift
然后在写 Python Server 和/或 Client 脚本时,直接从 import thrift.xxx 即可,不用再像示例脚本 thrift-0.13.0/tutorial/py/ 中的 Server 或 Client 脚本一样,还需要这样…… sys.path.insert(0, glob.glob('../../lib/py/build/lib*')[0])
基本用法
1. 使用 Sever 端语言(比如这里用 Cpp),编写包含具体功能的函数,把它们集成到比如 CppServer.cpp
2. 使用 Client 端语言 (比如这里用 Python3),编写业务逻辑,调用 Sever 端编写的函数(这就是远程过程调用 RPC 的意义)
要使上述 RPC 能正常 work,需要编写联系 Server 和 Client 的接口 .thrift 文件(编写方法可以参考 thrift-0.13.0/tutorial/tutorial.thrift 和 thrift-0.13.0/test/xxx.thrift)
编写完成后例如 demo.thrift ,分别对 Server 和 Client 使用的语言编译中间库,例如
# 如果 .thrift 文件有嵌套,可能需要 -r 选项去生成包含文件的中间库 $ thrift -r --gen cpp demo.thrift $ thrift -r --gen py demo.thrift
分别生成 gen-cpp 和 gen-py,在上述 1. 和 2. 步骤,需要用到这些中间库文件。
3. 编译 Server 端,生成例如 CppServer 的可执行文件,运行,
$ ./CppServer
Starting the server...
4. 编辑 Client 端,生成例如 Python3Client.py 的脚本文件,运行,
$ python3 Python3Client.py ping() 1+1=2 InvalidOperation: InvalidOperation(whatOp=4, why='Cannot divide by 0') 15-10=5 Check log: 5
完。