thrift的lua实现

最近要进行系统升级,后台的数据是根据城市区分的。担心新系统的稳定性及新数据的准确性,计划部分城市采用新接口。接口的入参里没有城市信息,只有经纬度坐标,需要调用一个thrift接口来根据坐标获取城市信息。

  如果直接修改代码逻辑,则会造成新旧版本的耦合,不仅完全上线时要再次修改,而且还要增加一次测试流程,这样成本就有些高了。这时就想到能不能用nginx+lua对新旧版本接口做灰度发布。

  步骤:

  1、安装thrift

2、生成客户的代码

    3、编译lua调用thrift需要的库

4、实现客户端代码

5、测试

  

1、安装thrift

  thrift最初由facebook开发用做系统内各语言之间的RPC通信,其实它与webservice有很多相似的地方。

  首先有一个定义数据类型和接口的文件,xxx.thrift(在webservic里面对应的是xxx.wsdl),然后用程序去生成对应的客户端/服务器代码.

  thrift的官方网站http://thrift.apache.org/,在上面可以下载最新版本的thrift(http://thrift.apache.org/download)。

  最新版本的是thrift-0.9.3.tar.gz(截止2016/11/28)。

  安装的步骤官网上有,http://thrift.apache.org/tutorial/,基本上就是:

1 ./configure && make && make install

  安装过程可能会遇到缺依赖包,不是大问题,装一下就行了。

2、生成客户的代码

 thrift文件内容,服务端提供 location_match.thrift:

 1 /**
2 * File: location_service.thrift
3 */
4 /** 入参数据结构 **/
5 struct Location_point
6 {
7 1: double x;
8 2: double y;
9 }
10 /** 出参数据结构 **/
11 struct Citycode_Response
12 {
13 1:string retCode;
14 2:i16 cityCode;
15 }
16
17 /** 接口定义 **/
18 service LocationmatchService
19 {
20 Citycode_Response find_citycode(1:Location_point location_point)
21 }

根据此文件生成lua客户端代码:

1 thrift --gen lua location_match.thrift

会在当前目录生成一个目录:gen-lua

里面有3个文件:

location_match_constants.lua:应该是个接口文件,里面有说明,大概意思是说,不懂就不要改

location_match_LocationmatchService.lua: 接口的定义

location_match_ttypes.lua:出入参数结构定义

这个过程非常像axis根据wsdl生成webservice代码的过程。上面的3个文件不需要改的。

3、编译lua调用thrift需要的库

lua调用thrift服务需要一些库文件,一部分是c语言实现的动态链接库*.so文件,一部分是lua语言的函数库*.lua。这些库的源码文件在官网下载的包里有(thrift-0.9.3.tar.gz),解压后在lib目录下有各个语言的库。lua在lib/lua下。

这里需要注意几个问题:1、官网的包里c语言编译会报错(当然可能是个别现象),具体错误没记住,大致上是说 relink libluasocket.so 时候报错。这个错误还好说,改下Makefile.am调整顺序即可,参见http://blog.csdn.net/superye1983/article/details/51190166。 2、调用thrift服务一定要注意两个关键点传输协议和IO方式(阻塞/非阻塞),传输协议有二进制流传输、json串和压缩数据传输格式等,其实主要规定了数据在传输过程中的格式,官网的包中只有二进制传输的协议TBinaryProtocol.lua。3、官网的包中socke是根据依赖lua实现的,而现实使用openresty是基于luajit的。luajit的socket是ngx.socket.tcp(),可能会造成某些冲突。

这里采用http://www.cnblogs.com/voipman/p/5365248.html 这篇文章中提到的源码实现,没有使用thrift官网的代码。代码下载地址https://github.com/gityf/ngx_lua_thrift。上面有明确的安装说明,非常简单编译动态链接库时只需一个命令make linux。

这里采用的nginx是openresty.下载和安装参见http://openresty.org/cn/.

4、实现客户端代码

test_cln.lua:

 1 require('TSocket')
2 require('TCompactProtocol')
3 require('TTransport')
4 require('location_match_LocationmatchService')
5 require('location_match_ttypes')
6 require('TFramedTransport')
7 module("test_cln",package.seeall)
8 function demoFunc()
9 local opt = {
10 host='127.0.0.1',
11 port=9090
12 }
13 local socket = TSocket:new(opt)
14 local ttable = {
15 trans = socket
16 }
17 local transport = TFramedTransport:new(ttable)
18
19
20 local protocol = TCompactProtocol:new{
21 trans = transport
22 }
23
24 client = LocationmatchServiceClient:new{
25 protocol = protocol
26 }
27 local location_point = Location_point:new{
28 x=114.2901961,
29 y=22.76033004,
30 }
31 socket:open()
32 res = ""
33 local ret = client:find_citycode(location_point)
34 res= tostring(ret.cityCode)
35 ngx.log(ngx.ERR,res..' ~~~~~~~'..tostring(ret.cityCode))
36 return res
37 end

实现上与http://blog.csdn.net/superye1983/article/details/51190166这篇帖子里差不多。区别在于协议使用的是压缩协议TCompactProtocol,IO阻塞方式上采用的是无阻塞,所以使用了TFramedTransport,因为服务端实现的是无阻塞服务,如果协议、阻塞方式不对发起调用时就会报IO错误,TTransportException: time out/TTransportException: closed/TTransportException: connection reset by peer.

要把第二步生成的lua文件、第三步编译的动态链接库和lua文件都放到lualib目录下。test_cln.lua也要防止这个目录下。

nginx.conf:

1         location / {
2 content_by_lua_file /usr/local/nginx/nginx/conf/luascript/test.lua;
3 root html;
4 index index.html index.htm;
5 }

test.lua:

1 local cln = require "test_cln"
2 ngx.say(cln.demoFunc());

5、测试

[root@hadoop-1 sbin]# curl http://127.0.0.1/
1438

返回城市代码成功。

总结:采用openresty(nginx的一个版本,有luajit插件)实现接口的灰度发布,lua调用thrift,安装thrift,生成客户的代码,下载开源的thrift-lua依赖的库,thrift需要协议和io阻塞方式客户端与服务端一致。

thrift的lua的更多相关文章

  1. thrift的lua实现

    最近要进行系统升级,后台的数据是根据城市区分的.担心新系统的稳定性及新数据的准确性,计划部分城市采用新接口.接口的入参里没有城市信息,只有经纬度坐标,需要调用一个thrift接口来根据坐标获取城市信息 ...

  2. Thrift的TBinaryProtocol二进制协议分析

    先上张图,说明一下thrift的二进制协议是什么东东. 报文格式编码: bool类型: 一个字节的类型,两个字节的字段编号,一个字节的值(true:1,false:0). Byte类型: 一个字节的类 ...

  3. Thrift的TJsonProtocol协议分析

    Thrift协议实现目前有二进制协议(TBinaryProtocol),紧凑型二进制协议(TCompactProtocol)和Json协议(TJsonProtocol). 前面的两篇文字从编码和协议原 ...

  4. 安装thrift全过程

    为了研究基于thrift的RPC框架,其实,是想自己基于thrift写一个微服务的platform.首先就是安装Thrift,便于IDL架构生成java的接口文件.多的不说了,开始install的过程 ...

  5. ubuntu thrift 0.9.3编译安装

    Table of Contents 1. 下载thrift源代码 2. 编译并安装 3. 运行测试程序 4. 安装 1 下载thrift源代码 git clone https://git-wip-us ...

  6. Openresty使用Thrift安装步骤

    最新想用Golang与Openresty相互通讯调用,使用RPC协议来实现,后来研究最终选择了Thrift:主要还是FB实现了支持Lua和Go模块,直接编译就可以成功嵌套使用,非常方便:研究了两天最后 ...

  7. RPC服务框架探索之Thrift

    前言架构服务化后,需要实现一套方便调用各服务的框架,现在开源如日中天,优先会寻找开源实现,如果没有合适自家公司业务的,才会考虑从零开发,尤其是一切以KPI为准绳的公司,谁会跟钱过不去?N个月之前,公司 ...

  8. dotnetcore 与 hbase 之二——thrift 客户端的制作

    说明 在上一篇文章dotnetcore 与 hbase 之一--hbase 环境准备结束后,我们已经有了 hbase 数据库环境.接下来就可以利用 thrift 生成 c# hbase 客户端了.如果 ...

  9. thrift接口描述语言 (基于thrift 0.13.0版本)

    thrift接口描述语言(IDL)用来定义thrift类型. 一个Thrift IDL文件用来生成各种语言使用的结构体和服务. IDL中包含如下部分: 1. Document Document中包含0 ...

随机推荐

  1. 简单使用PuTTy登录centos虚拟机

    博主刚刚开始学习Linux,想通过写博客的方式加深对linux学习的记忆 使用虚拟机安装精简版的linux后发现窗口字体太小,于是就想着通过PuTTy登录的方式解决 简单安装linux后 将linux ...

  2. maven-聚合与继承

    1.聚合-方便快速构建项目 多个maven模块要构建需要分别执行一次maven构建命令,怎样只执行一次构建命令就构建多个maven模块呢?maven提供了聚合模块可以满足一次运行,构建多模块的要求 2 ...

  3. A*与IDA*的奇妙之旅

    因为A*卡了一天QAQ 那么,A*是什么呢? A* A*是对于bfs的优化,启发式搜索. 例如下图: 不错,在这张图上,小人去找电脑,用bfs的话: 黄色就是bfs的搜索范围...不要问我为什么选黄色 ...

  4. 【Java】关于Spring框架的总结 (三)

    前文对 Spring IoC 和 Spring AOP 的实现方法进行了整合.如果有不明白的或有质疑的地方可以评论出来,一起探讨问题,帮助别人也是帮助自己!本文探讨的中心主要放在 Spring 的注解 ...

  5. 前端面试题目汇总摘录(JS 基础篇 —— 2018.11.02更新)

    温故而知新,保持空杯心态 JS 基础 JavaScript 的 typeof 返回那些数据类型 object number function boolean undefined string type ...

  6. docker windows container的一些注意点

    1.在阿里云esc的ws2016里装docker只能使用windows container,因为官方也说了主机也是虚拟机所以不能开启Hyper-v. 2.默认使用nat模式运行network,该模式在 ...

  7. Messy Code in Windows Server 2008 R2 English Edition

          We always use Windows Server 2008 R2 English operation system. And it doesn't have any problem ...

  8. DDoS 攻击与防御:从原理到实践(下)

    欢迎访问网易云社区,了解更多网易技术产品运营经验. DDoS 攻击与防护实践 DDoS 攻击的实现方式主要有如下两种: 自建 DDoS 平台 现在有开源的 DDoS 平台源代码,只要有足够机器和带宽资 ...

  9. Chrome也疯狂之Vimium插件

    Chrome也疯狂之安装Vimium插件 由于最近换上了Mac,深感外设的累赘,脱离了外接鼠标以及键盘之后发现操作更加的流畅了(可怜我入手不到一年的机械键盘).当然脱离鼠标用触摸板来操作浏览器有时候还 ...

  10. Python-类-函数参数-takes 0 positional arguments but 1 was given

    在学习Python基础的时候,在创建某一个shownametest()函数,解析器会报错 TypeError: shownametest() takes 0 positional arguments ...