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. Spring Boot2.0拦截器简单实现判断是否登录

    在进行项目开发的时候使用springboot框架用到拦截器时发现2.0以后原来的抽象类WebMvcConfigurerAdapter已经过时了,去官网查文档2.x版本要实现拦截器功能改为需要继承Web ...

  2. 【vlan-给予mac地址认证】

    根据项目需求搭建好如下的路由和交换拓扑图: 1:用pc1  ping pc2 使交换机捕捉到4台pc及的 mac地址 查看交换机学习到的mac地址情况 2:配置交换机和pc机之间的接口,根pc机的ma ...

  3. MySQL innodb表使用表空间物理文件复制或迁移表

    MySQL InnoDB引擎的表通过拷贝物理文件来进行单表或指定表的复制,可以想到多种方式,今天测试其中2种: 将innodb引擎的表修改为Myisam引擎,然后拷贝物理文件 直接拷贝innodb的表 ...

  4. 服务器空间不足导致mysql服务器无法运行

    今天有朋友请我帮忙解决一个问题,他公司服务器mysql数据库一直连接失败.登录服务期之后发现服务器空间占满了,导致mysql不能启动. 下面说解决方法: 首先查看空间占用,发现空间占满了 df -h ...

  5. VSCode插件整理

    VSCode插件整理 VSCode插件整理 官网地址 vscode常用配置(User Settings文件) 基本插件 前端插件 VUE部分 python MarkDown部分 连接Linux 本地与 ...

  6. zabbix监控MySQL服务状态

    Mysql模板使用 在zabbix_agent配置文件中加入监控配置 vim etc/zabbix_agentd.conf ... UserParameter=mysql.version,mysqla ...

  7. ruby json解析&生成

    JSON 通常用于与服务端交换数据. 在接收服务器数据时一般是字符串. 我们可以使用 JSON.parse() 方法将数据转换为 ruby 对象. 一. json字符串解析 require 'json ...

  8. 快速傅里叶变换(FFT)学习笔记(未完待续)

    目录 参考资料 FFT 吹水 例题 普通做法 更高大尚的做法 定义与一部分性质 系数表达式 点值表达式 点值相乘??? 卷积 复数 单位根 DFT IDFT 蝴蝶迭代优化 单位根求法 实现.细节与小优 ...

  9. 003---设计首页index页面

    在项目的urls.py文件添加一条url from django.contrib import admin from django.urls import path, re_path from app ...

  10. Go语言中的HTTP

    Go中的http使用 package main import ( "fmt" "net/http" "io/ioutil" "st ...