Support IP Hash LB policy
[msb/apigateway.git] / openresty-ext / src / assembly / resources / openresty / nginx / luaext / dao / dao.lua
1 --[[\r
2 \r
3     Copyright (C) 2018 ZTE, Inc. and others. All rights reserved. (ZTE)\r
4 \r
5     Licensed under the Apache License, Version 2.0 (the "License");\r
6     you may not use this file except in compliance with the License.\r
7     You may obtain a copy of the License at\r
8 \r
9             http://www.apache.org/licenses/LICENSE-2.0\r
10 \r
11     Unless required by applicable law or agreed to in writing, software\r
12     distributed under the License is distributed on an "AS IS" BASIS,\r
13     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
14     See the License for the specific language governing permissions and\r
15     limitations under the License.\r
16 \r
17 --]]\r
18 \r
19 --This module integrates the shcache with an abstraction for various databases(redis and so on)\r
20 local _M = {}\r
21 _M._VERSION = '1.0.0'\r
22 \r
23 local shcache = require("vendor.shcache")\r
24 local cjson_safe =  require "cjson.safe"\r
25 local msbConf = require('conf.msbinit')\r
26 \r
27 local DB      = require('dao.redis_db')\r
28 local options = msbConf.redisConf\r
29 \r
30 local cacheConf = msbConf.cacheConf\r
31 local positive_ttl = cacheConf.positive_ttl or 60\r
32 local negative_ttl = cacheConf.negative_ttl or 2\r
33 local actualize_ttl = cacheConf.actualize_ttl or 120\r
34 local stats_prefix = "monitor:stats:"\r
35 \r
36 local svc_shcache = ngx.shared.svc_cache\r
37 \r
38 local function load_serviceinfo(key)\r
39 \r
40         -- closure to perform external lookup to redis\r
41         local fetch_svcinfo_from_db = function ()\r
42                 local _db = DB:new(options)\r
43                 return _db:getserviceinfo(key)\r
44         end\r
45 \r
46         local svcinfo_cache_table = shcache:new(\r
47                 svc_shcache,\r
48                 { external_lookup = fetch_svcinfo_from_db,\r
49                         --encode = cmsgpack.pack,\r
50                         --encode = cjson_safe.encode,\r
51                         --decode = cmsgpack.unpack\r
52                         --decode = cjson_safe.decode\r
53                 },\r
54                 {   positive_ttl = positive_ttl,           -- default cache good data for 60s \r
55                         negative_ttl = negative_ttl,           -- default cache failed lookup for 5s\r
56                         actualize_ttl = actualize_ttl,\r
57                         name = 'svcinfo_cache'       -- "named" cache, useful for debug / report\r
58                 }\r
59         )\r
60 \r
61         local serviceinfo, from_cache = svcinfo_cache_table:load(key)\r
62 \r
63         return serviceinfo\r
64 end\r
65 _M.load_serviceinfo = load_serviceinfo\r
66 \r
67 local function load_backservers(keypattern)\r
68 \r
69         -- closure to perform external lookup to redis\r
70         local fetch_servers_from_db = function ()\r
71                 local _db = DB:new(options)\r
72                 return _db:getbackservers(keypattern)\r
73         end\r
74 \r
75         local servers_cache_table = shcache:new(\r
76                 svc_shcache,\r
77                 { external_lookup = fetch_servers_from_db,\r
78                         --encode = cmsgpack.pack,\r
79                         encode = cjson_safe.encode,\r
80                         --decode = cmsgpack.unpack\r
81                         decode = cjson_safe.decode\r
82                 },\r
83                 {   positive_ttl = positive_ttl,           -- default cache good data for 60s \r
84                         negative_ttl = negative_ttl,           -- default cache failed lookup for 5s\r
85                         name = 'servers_cache'           -- "named" cache, useful for debug / report\r
86                 }\r
87         )\r
88 \r
89         local servers_table, from_cache = servers_cache_table:load(keypattern)\r
90 \r
91         return servers_table\r
92 end\r
93 _M.load_backservers = load_backservers\r
94 \r
95 \r
96 local function load_customsvcnames(keypattern)\r
97         -- closure to perform external lookup to redis\r
98         local fetch_svcnames_from_db = function ()\r
99                 local _db = DB:new(options)\r
100                 return _db:getcustomsvcnames(keypattern)\r
101         end\r
102 \r
103         local svcnames_cache_table = shcache:new(\r
104                 svc_shcache,\r
105                 { external_lookup = fetch_svcnames_from_db,\r
106                         --encode = cmsgpack.pack,\r
107                         encode = cjson_safe.encode,\r
108                         --decode = cmsgpack.unpack\r
109                         decode = cjson_safe.decode\r
110                 },\r
111                 {   positive_ttl = positive_ttl,           -- default cache good data for 60s \r
112                         negative_ttl = negative_ttl,           -- default cache failed lookup for 5s\r
113                         actualize_ttl = actualize_ttl,\r
114                         name = 'svcnames_cache'      -- "named" cache, useful for debug / report\r
115                 }\r
116         )\r
117 \r
118         local service_names, from_cache = svcnames_cache_table:load(keypattern)\r
119 \r
120         return service_names\r
121 end\r
122 _M.load_customsvcnames = load_customsvcnames\r
123 \r
124 \r
125 function _M.save_reqnum_stats(date,info)\r
126         local _db = DB:new(options)\r
127         local c, err = _db:connectdb()\r
128         if not c then\r
129                 return nil, err\r
130         end\r
131 \r
132         local red   = _db.redis\r
133         local resp,err =  red:rpush(stats_prefix..date,info)\r
134         _db:keepalivedb()\r
135         if not resp then\r
136                 return nil, "save_reqnum_stats failed! key:"..date.." value:"..info\r
137         else\r
138                 return resp,nil\r
139         end\r
140 end\r
141 \r
142 function _M.delete_reqnum_stats(date)\r
143         local _db = DB:new(options)\r
144         local c, err = _db:connectdb()\r
145         if not c then\r
146                 return nil, err\r
147         end\r
148         local red   = _db.redis\r
149         red:del(stats_prefix..date)\r
150         _db:keepalivedb()\r
151 end\r
152 \r
153 function _M.get_reqnum_stats(date,latest_num)\r
154         if(type(latest_num)~="number") then\r
155                 return nil,"the input num is illegal!"\r
156         end\r
157         local _db = DB:new(options)\r
158         local c, err = _db:connectdb()\r
159         if not c then\r
160                 return nil, err\r
161         end\r
162         local red   = _db.redis\r
163         local resp,err =  red:lrange(stats_prefix..date,0-latest_num,-1)\r
164         _db:keepalivedb()\r
165         return resp,nil\r
166 end\r
167 \r
168 return _M\r