歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux綜合 >> 學習Linux >> thrift的lua實現,thriftlua實現

thrift的lua實現,thriftlua實現

日期:2017/3/3 18:05:22   编辑:學習Linux

thrift的lua實現,thriftlua實現

thrift的lua實現,thriftlua實現


  最近要進行系統升級,後台的數據是根據城市區分的。擔心新系統的穩定性及新數據的准確性,計劃部分城市采用新接口。接口的入參裡沒有城市信息,只有經緯度坐標,需要調用一個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阻塞方式客戶端與服務端一致。

http://xxxxxx/Linuxjc/1175549.html TechArticle

Copyright © Linux教程網 All Rights Reserved