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、测试

[[email protected]1 sbin]# curl http://127.0.0.1/
1438

返回城市代码成功。

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

时间: 2024-10-05 10:08:11

thrift的lua实现的相关文章

thrift for lua 使用记录

本人精心总结,欢迎转载,转载请注明出处:http://blog.csdn.net/einsteinlike/article/details/43700985 thrift是一个十分节省的数据传输协议,我们尝试将其移植到quick-cocos2dx上面: lua的使用:首先编译lua5.2 make install进系统.然后编译thrift 0.9.2 ,配置的时候选择 ./configure -with-lua -with-c++等 然后make的时候各种有错,没关系,只要到make lua结

Openresty使用Thrift安装步骤

最新想用Golang与Openresty相互通讯调用,使用RPC协议来实现,后来研究最终选择了Thrift:主要还是FB实现了支持Lua和Go模块,直接编译就可以成功嵌套使用,非常方便:研究了两天最后编译成功,于是便把使用步骤做下记录. 1.Mac安装Thrift brew install thrift 2.Apache官网地址Thrift0.10下载地址 或者 git clone https://git-wip-us.apache.org/repos/asf/thrift.git thrift

ubuntu thrift 0.9.3编译安装

Table of Contents 1. 下载thrift源代码 2. 编译并安装 3. 运行测试程序 4. 安装 1 下载thrift源代码 git clone https://git-wip-us.apache.org/repos/asf/thrift.git thrift git checkout 0.9.3 2 编译并安装 安装依赖 apt-get install automake apt-get install libssl-dev apt-get install byacc apt-

Thrift的TJsonProtocol协议分析

Thrift协议实现目前有二进制协议(TBinaryProtocol),紧凑型二进制协议(TCompactProtocol)和Json协议(TJsonProtocol). 前面的两篇文字从编码和协议原理方面分析了TBinaryProtocol和TCompactProtocol协议,下面对TJsonProtocol协议做一下分析. TJsonProtocol协议相对比较简单,在网络中以文本方式传输,易于抓包分析和理解. 1. 数据类型表示方式和简写 数据类型 数据类型 Json协议节点简写 C++

RPC服务框架探索之Thrift

前言架构服务化后,需要实现一套方便调用各服务的框架,现在开源如日中天,优先会寻找开源实现,如果没有合适自家公司业务的,才会考虑从零开发,尤其是一切以KPI为准绳的公司,谁会跟钱过不去?N个月之前,公司大神就开始调研了,最后选中了Thrift这个RPC服务框架.使用不熟悉的技术,我会感到很恐惧,它就相当于一个黑盒,我对它一无所知,它是如何运转的?出了问题该如何解决?带着一丝不安,查阅了相关技术文档. RPC很早之前听说过soap,restful api,rpc之类的服务协议,一直都没有机会深入实践

cocos2dx lua中异步加载网络图片,可用于显示微信头像

最近在做一个棋牌项目,脚本语言用的lua,登录需要使用微信登录,用户头像用微信账户的头像,微信接口返回的头像是一个url,那么遇到的一个问题就是如何在lua中异步加载这个头像,先在引擎源码里找了下可能会提供这个功能的地方,发现好像没有提供类似功能,那么只能自己动手写.所以我在ImageView这个类里面添加了一个成员方法,其实可以不写在ImageView里,而且我觉得非必需情况下还是不要修改引擎源码的好,因为如果源码改动比较多的话,将来引擎版本升级会比较麻烦.我写在ImageView里纯粹是想偷

Lua 第一天

今天开始学习Lua语言,感觉Lua非常便捷.我用的编译器是SciTE,很不错. 举例一:无需引用,内置输出语句   print() print(6)   --> 6 print(type(6))  -->   number 举例二:对数字字符串进行数字化处理 print("2"+3 )  -->5 举例三:..连接俩个字符串,#返回字符串长度 举例四:print()输出函数,可以有多个输出值 a = 1,b =2,c = a+b    print(a,b,c,a,b,

lua协程一则报错解决“attempt to yield across metamethod/C-call boundary”

问题 attempt to yield across metamethod/C-call boundary 需求跟如下帖子中描述一致: http://bbs.chinaunix.net/forum.php?mod=viewthread&action=printable&tid=4065715 模拟一个场景,在C中创建出coroutine来执行Lua脚本,并且提供C API给Lua使用,当某些操作可能会阻塞时(如网络I/O),C函数中执行yield将协程切换出去,然后未来的某个时刻,如果条件

lua闭合函数

function count( ... ) local i = 0 return function( ... ) i = i+ 1 return i end end local func = count(...) print(func()) print(func()) print(func()) 结果如下: 1 2 3 [Finished in 0.1s] lua 闭合函数:一个函数加上该函数所需访问的所有“非局部变量”. 如上所示:count()函数返回了另一个函数,而这个函数使用了count