博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
thrift的lua实现
阅读量:4323 次
发布时间:2019-06-06

本文共 3924 字,大约阅读时间需要 13 分钟。

  最近要进行系统升级,后台的数据是根据城市区分的。担心新系统的稳定性及新数据的准确性,计划部分城市采用新接口。接口的入参里没有城市信息,只有经纬度坐标,需要调用一个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_Response12 {13     1:string retCode;14     2:i16 cityCode;15 }16 17 /** 接口定义 **/18 service LocationmatchService19 {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=909012   }13   local socket = TSocket:new(opt)14   local ttable = {15      trans = socket16   }17   local transport = TFramedTransport:new(ttable)18   19   20   local protocol = TCompactProtocol:new{21         trans = transport22   }23 24   client = LocationmatchServiceClient:new{25         protocol = protocol26   }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 res37 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阻塞方式客户端与服务端一致。

 

转载于:https://www.cnblogs.com/mahyblog/p/6109237.html

你可能感兴趣的文章
JQuery 前台传值到后台并调用后台方法
查看>>
Appium+Python3+ Android入门
查看>>
linux $ 类型变量 及Makefile 中 $ 类型变量的含义
查看>>
MyBatis插件及示例----打印每条SQL语句及其执行时间
查看>>
2.2
查看>>
[JS]事件捕获和冒泡
查看>>
【译】SQL Server误区30日谈-Day10-数据库镜像在故障发生后,马上就能发现
查看>>
linq之where子句
查看>>
Socket之UDP发送文件
查看>>
多语言在线代码编辑器,可运行程序
查看>>
C#:使用UPnP来穿透NAT使内网接口对外网可见
查看>>
js+css 实现遮罩居中弹出层(随浏览器窗口滚动条滚动)
查看>>
项目管理的小故事
查看>>
Visual Studio不显示智能提示代码,快捷键Alt+→也不出现
查看>>
多文件调用(函数、结构体)
查看>>
C# 获取本地电脑所有的盘符
查看>>
D3.js学习(三)
查看>>
汇编语言实验9
查看>>
window资源管理器下无法打开ftp站点
查看>>
spring特点与好处
查看>>