基于Apache Thrift的公路涵洞数据交互实现原理
基于Apache Thrift的公路涵洞数据交互实现原理
Apache Thrift简介
Apache Thrift(以下简称为“Thrift”) 是 Facebook 实现的一种高效的、支持多种编程语言的远程服务调用的框架。
目前流行的服务调用方式有很多种,例如基于 SOAP 消息格式的 Web Service,基于 JSON 消息格式的 RESTful 服务等。其中所用到的数据传输方式包括 XML,JSON 等,然而 XML 相对体积太大,传输效率低,JSON 体积较小,新颖,但还不够完善。本文将介绍由 Facebook 开发的远程服务调用框架 Apache Thrift,它采用接口描述语言定义并创建服务,支持可扩展的跨语言服务开发,所包含的代码生成引擎可以在多种语言中,如 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk 等创建高效的、无缝的服务,其传输数据采用二进制格式,相对 XML 和 JSON 体积更小,对于高并发、大数据量和多语言的环境更有优势。
Thrift 架构
Thrift 包含一个完整的堆栈结构用于构建客户端和服务器端。下图描绘了 Thrift 的整体架构。
图 1. 架构图
如图所示,图中黄色部分是用户实现的业务逻辑,褐色部分是根据 Thrift 定义的服务接口描述文件生成的客户端和服务器端代码框架,红色部分是根据 Thrift 文件生成代码实现数据的读写操作。红色部分以下是 Thrift 的传输体系、协议以及底层 I/O 通信,使用 Thrift 可以很方便的定义一个服务并且选择不同的传输协议和传输层而不用重新生成代码。
Thrift 服务器包含用于绑定协议和传输层的基础架构,它提供阻塞、非阻塞、单线程和多线程的模式运行在服务器上,可以配合服务器 / 容器一起运行。
服务端和客户端具体的调用流程如下:
图 2. Server 端启动、服务时序图
该图所示是 HelloServiceServer 启动的过程以及服务被客户端调用时,服务器的响应过程。从图中我们可以看到,程序调用了 TThreadPoolServer 的 serve 方法后,server 进入阻塞监听状态,其阻塞在 TServerSocket 的 accept 方法上。当接收到来自客户端的消息后,服务器发起一个新线程处理这个消息请求,原线程再次进入阻塞状态。在新线程中,服务器通过 TBinaryProtocol 协议读取消息内容,调用 HelloServiceImpl 的 helloVoid 方法,并将结果写入 helloVoid_result 中传回客户端。
图 3. Client 端调用服务时序图
该图所示是 HelloServiceClient 调用服务的过程以及接收到服务器端的返回值后处理结果的过程。从图中我们可以看到,程序调用了 Hello.Client 的 helloVoid 方法,在 helloVoid 方法中,通过 send_helloVoid 方法发送对服务的调用请求,通过 recv_helloVoid 方法接收服务处理请求后返回的结果。
Thrift环境准备
1下载Thrift
当前版本为Thrift-0.10.0。
2. 编译或下载Thrift编译器
windows下可以直接下载已经编译好的编译器Thrift-0.10.0.exe。
涵洞数据交互实例:
1. 定义Thrift文件
exception GenericError {
}
enum SlabCulvertType {
}
struct CommonResult{
}
struct SlabCulvert {
}
service EngineerService {
CommonResult slabCulvert_add(1: Context context,2: SlabCulvertType slabCulvertType,3: SlabCulvert slabCulvert) throws (1:GenericError e)
CommonResult slabCulvert_modify(1: Context context,2: SlabCulvertCondition slabCulvertCondition,3: SlabCulvertType slabCulvertType,4: SlabCulvert slabCulvert) throws (1:GenericError e)
CommonResult slabCulvert_remove(1: Context context,2: SlabCulvertCondition slabCulvertCondition) throws (1:GenericError e)
SlabCulvertResult slabCulvert_query(1: Context context,2: SlabCulvertCondition slabCulvertCondition) throws (1:GenericError e)
}
2. 使用Thrift编译器编译Thrift文件
thrift --gen <language> <Thrift filename>
3. 编写服务端代码
#!/usr/bin/env python
# -*- coding:utf-8 -*- import glob
import sys
sys.path.append('gen-py')
sys.path.insert(0, glob.glob('../../lib/py/build/lib*')[0]) from tutorial import EngineerService from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.server import TServer class EngineerServiceHandler:
def __init__(self):
self.log = {} def slabCulvert_add(self, context, slabCulvertType, slabCulvert):
pass def slabCulvert_modify(self, context, slabCulvertCondition, slabCulvertType, slabCulvert):
pass def slabCulvert_remove(self, context, slabCulvertCondition):
pass def slabCulvert_query(self, context, slabCulvertCondition):
pass if __name__ == '__main__':
handler = EngineerServiceHandler()
processor = EngineerService.Processor(handler)
transport = TSocket.TServerSocket(port=9090)
tfactory = TTransport.TBufferedTransportFactory()
pfactory = TBinaryProtocol.TBinaryProtocolFactory() server = TServer.TSimpleServer(processor, transport, tfactory, pfactory) print('Starting the server...')
server.serve()
print('done.')
4. 客户端使用框架代码调用远程服务
#!/usr/bin/env python
# -*- coding:utf-8 -*- import sys
import glob
sys.path.append('gen-py')
sys.path.insert(0, glob.glob('../../lib/py/build/lib*')[0]) from tutorial import EngineerService
from tutorial.ttypes import InvalidOperation, slabCulvertType from thrift import Thrift
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol def main():
# Make socket
transport = TSocket.TSocket('localhost', 9090) # Buffering is critical. Raw sockets are very slow
transport = TTransport.TBufferedTransport(transport) # Wrap in a protocol
protocol = TBinaryProtocol.TBinaryProtocol(transport) # Create a client to use the protocol encoder
client = EngineerService.Client(protocol) # Connect!
transport.open() try:
context = ...
slab_culvert_type = ...
slab_culvert = slabCulvert(...)
res = client.slabCulvert_add(context, slab_culvert_type, slab_culvert)
print(res)
except InvalidOperation as e:
print('InvalidOperation: %r' % e) # Close!
transport.close() if __name__ == '__main__':
try:
main()
except Thrift.TException as tx:
print('%s' % tx.message)
参考资料:
基于Apache Thrift的公路涵洞数据交互实现原理的更多相关文章
- Apache Thrift学习之二(基础及原理)
Apache Thrift 是 Facebook 实现的一种高效的.支持多种编程语言的远程服务调用的框架.本文将从 Java 开发人员角度详细介绍 Apache Thrift 的架构.开发和部署,并且 ...
- 基于Apache POI 从xlsx读出数据
[0]写在前面 0.1) these codes are from 基于Apache POI 的从xlsx读出数据 0.2) this idea is from http://cwind.iteye. ...
- 基于Apache POI 向xlsx写入数据
[0]写在前面 0.1) these codes are from 基于Apache POI 的向xlsx写入数据 0.2) this idea is from http://cwind.iteye. ...
- 基于Apache Hudi构建分析型数据湖
为了有机地发展业务,每个组织都在迅速采用分析. 在分析过程的帮助下,产品团队正在接收来自用户的反馈,并能够以更快的速度交付新功能. 通过分析提供的对用户的更深入了解,营销团队能够调整他们的活动以针对特 ...
- 基于ssh框架的highcharts前后台数据交互实例
Highcharts 是一个用纯JavaScript编写的一个图表库, 能够很简单便捷的在web网站或是web应用程序添加有交互性的图表,并且免费提供给个人学习.个人网站和非商业用途使用.HighCh ...
- 基于Xen实现一种domain0和domainU的应用层数据交互高效机制 - 2
继续昨天的思路,今天先google了类似的实现domain0和domainU之间数据传输的方案 [Xen-devel] XenStore as a data transfer path? 这篇帖子讨 ...
- Apache Thrift 跨语言服务开发框架
Apache Thrift 是一种支持多种编程语言的远程服务调用框架,由 Facebook 于 2007 年开发,并于 2008 年进入 Apache 开源项目管理.Apache Thrift 通过 ...
- Apache Thrift - 可伸缩的跨语言服务开发框架
To put it simply, Apache Thrift is a binary communication protocol 原文地址:http://www.ibm.com/developer ...
- 【转】Apache Thrift - 可伸缩的跨语言服务开发框架
Apache Thrift - 可伸缩的跨语言服务开发框架 Apache Thrift 是 Facebook 实现的一种高效的.支持多种编程语言的远程服务调用的框架.本文将从 Java 开发人员角度详 ...
随机推荐
- sqlserver查询分析器在本地服务器查看其它SqlServer服务器内容
exec sp_addlinkedserver 服务器自命名,'',sqloledb,要查询服务器的IP地址 exec sp_addlinkedsrvlogin 服务器自命名,false,null,账 ...
- 三维重建:SLAM的粒度和工程化问题
百度百科的定义.此文引用了其他博客的一些图像,如有侵权,邮件联系删除. 申明一下,SLAM不是一个算法,而是一个工程. 在计算机视觉中, 三维重建是指根据单视图或者多视图的图像重建三维信息的过程. 由 ...
- POJ_2594_最小路径覆盖
Treasure Exploration Time Limit: 6000MS Memory Limit: 65536K Total Submissions: 8085 Accepted: 3 ...
- xml方式实现aop编程
第一:引入jai文件 第二:引入aop名称空间 第三:配置aop
- [POI2005]SKA-Piggy Banks tarjan 水题
Code: #include<bits/stdc++.h> #define maxn 1000002 using namespace std; void setIO(string s) { ...
- jupyter notebook主目录修改
转自http://blog.csdn.net/c437yuyang/article/details/54836303 1.打开 cmd 输入命令 jupyter notebook --generate ...
- [USACO15FEB]Censoring (Silver)
WA了一万次.... 然后发现多输出了一个空格 我#$%^& 启示我们输出字符的时候应该输出ASCII码看一下.... 然后本题可以用烤馍片算法,每次匹配完以后看看当前最后一位的nxt数组的值 ...
- nexus3修改admin密码
Nexus是通过内置的orientdb数据库管理,是以需要进入到库里面修改密码. 不能像这篇博客(https://blog.csdn.net/tianya6607/article/details/53 ...
- Linux基础知识和命令
1,用户登录: root(管理员),权限最大.安全生产必要时再使用. 普通用户:权限有限.2, 终端终端设备终端:输入和输出设备,如:键盘鼠标显示器; 图形终端:虚拟机进入窗 ...
- ldap 禁止匿名登录(5)
[root@zabbix1 ~]# cat disable_anon.ldif dn: cn=config changetype: modify add: olcDisallows olcDisall ...