使用openresty做api网关

背景

之前文章 自动登陆并获取订单信息, 通过python脚本已经实现了定时从某企业官网爬取用户数据。接着我们需要做如下几个工作:

  • 将数据写入自己的mysql

  • 通过web客户端查看mysql中的数据

技术选型

  • 用什么语言做http服务器 ? c++、 go、c#、java 都可以,

  • 或者用开源组件来做http服务器 ?

我的选择是使用openrestry,通过lua语言来实现mysql数据的增、删、改查。

优点:

  • 跨平台

  • 开发成本低。搭建好框架后,lua代码只要关心sql语句的实现就可以了。

  • 易维护、易升级、易调试

技术要点

lua 语言学习还是比较快的,因为我只是使用mysql的功能,所以只要熟悉基本的函数、字符串、json对象的使用就可以了。

  • nginx.conf 上配置 lua

    1
    2
    3
    4
    5
    6
    7
    location /hzjzkj
    {

    default_type text/html;

    content_by_lua_file hzjzkj_mysql.lua;
    }
  • hzjzkj_mysql.lua 实现基本功能(见末尾)

  • web的报表界面使用adminLTE的jsgrid 实现

最终效果

upload successful

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165

local cjson = require "cjson"
local mysql = require("resty.mysql")

local db_config = {
host = '127.0.0.1',
port = 3306,
database = 'test',
user = 'test',
password = 'test',
orderlist = 'orderlist',
orderdetail = 'orderdetail',
tblhetong = 'hetong',
tbluser='user'
}

local args = ngx.req.get_uri_args()
local action = args['action']

local db,err

function dbinit()
db, err = mysql:new()
if not db then
ngx.say("failed to instantiate mysql: ", err)
return
end

db:set_timeout(5000) -- 5 sec

local ok, err, errcode, sqlstate = db:connect({
host = db_config.host,
port = db_config.port,
database = db_config.database,
user = db_config.user,
password = db_config.password})

if not ok then
ngx.log(ngx.ERR, "failed to connect: ", err, ": ", errcode, " ", sqlstate)
return
end
end

function dbinsert()
local res, err, errcode, sqlstate =
db:query("insert into cats (name) values (\'Tom\')")
if not res then
ngx.say("bad result: ", err, ": ", errcode, ": ", sqlstate, ".")
return
end

ngx.say(res.affected_rows, " rows inserted into table cats ",
"(last insert id: ", res.insert_id, ")")
end

function dbquery()
local res, err, errcode, sqlstate =
db:query("select * from cats order by id asc", 10)
if not res then
ngx.say("bad result: ", err, ": ", errcode, ": ", sqlstate, ".")
return
end

-- ngx.say("result: ", cjson.encode(res))
local index = 1
while res[index] do
ngx.say(res[index].id)
ngx.say(res[index].name)
index = index+1
end
end

function dbclose()
-- or just close the connection right away:
local ok, err = db:close()
if not ok then
ngx.say("failed to close: ", err)
return
end
end

function getdatafromsql(sql)
local res, err, errno, sqlstate = db:query(sql)

if not res then
ngx.say(cjson.encode({code=200, message=err, data=nil}))
else
ngx.say(cjson.encode({code=200, message="", data=res}))
end
return res
end

function insertdatafromsql(sql)
local res, err, errno, sqlstate = db:query(sql)

if not res then
ngx.say("bad result: ",sql,":", err, ": ", errcode, ": ", sqlstate, ".")
end

end

-- 获取所有物品,用于分析价格走势
function GetDetails()
ngx.req.read_body()

local args, err = ngx.req.get_post_args()
if not args then
ngx.say("failed to get post args: ", err)
return
end

-- 返回所有数据
local sql = 'SELECT d.*, t.FStatus AS HTStatus ,t.FDate FROM orderdetail d ,orderlist t WHERE d.FBillNo_BillNo = t.FBillNo_BillNo '

getdatafromsql(sql)
end


-- 根据最近时间查询orderlist信息
if action == 'GetOrderList' then
dbinit()
GetOrderList()
dbclose()
-- 插入orderlist 数据
elseif action == 'InsertOrderList' then
dbinit()
InsertOrderList()
dbclose()
-- 删除OrderList数据
elseif action == 'DeleteOrderList' then
dbinit()
DeleteOrderList()
dbclose()

-- 根据合同号orderdetail信息
elseif action == 'GetOrderDetail' then
dbinit()
GetOrderDetail()
dbclose()
-- 获取detail 信息
elseif action == 'GetDetails' then
dbinit()
GetDetails()
dbclose()
-- 插入orderdetail 数据
elseif action == 'InsertOrderDetail' then
dbinit()
InsertOrderDetail()
dbclose()
-- 获取指定销售员合同数据&商品信息
elseif action == 'GetHetongDetail' then
dbinit()
GetHetongDetail()
dbclose()
-- 获取指定销售员合同数据
elseif action == 'GetHetong' then
dbinit()
GetHetong()
dbclose()
-- 导入合同数据
elseif action =='InsertHetong' then
dbinit()
InsertHetong()
dbclose()
end