3 Copyright 2016 2015-2016 ZTE, Inc. and others. All rights reserved.
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use this file except in compliance with the License.
7 You may obtain a copy of the License at
9 http://www.apache.org/licenses/LICENSE-2.0
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
18 email: meng.zhaoxing1@zte.com.cn
21 -- put red into the connection pool of size 100,
22 -- with 10 seconds max idle time
23 local function close_redis(red)
27 --release connection to the pool
28 local pool_max_idle_time = 10000
30 local ok, err = red:set_keepalive(pool_max_idle_time, pool_size)
32 ngx.log(ngx.ERR, "set keepalive error:", err)
37 local function query_ipurl_updatecache(red,key)
38 local keyprefix = "msb:routing:custom:"..key
41 local infokey=keyprefix..":info"
42 -- first of all check whether the status is 1(enabled)
43 local status = red:hget(infokey,"status")
44 if not (status=="1") then
45 ngx.log(ngx.WARN, key.."is disabled.status=", status)
49 -- Try to get url for key
50 local url, err = red:hget(infokey,"url")
51 ngx.log(ngx.WARN, "==url:", url)
52 if not url or url == ngx.null then
56 -- Try to get ip:port for key
57 local serverkey=keyprefix..":lb:server1"
58 local server, err = red:hget(serverkey,"ip")..":"..red:hget(serverkey,"port")
59 ngx.log(ngx.WARN, "==server:", server)
60 if not server or server == ngx.null then
64 -- get the local cache
65 local cache = ngx.shared.ceryx
66 local uri = ngx.var.uri
67 -- Save found key to local cache for 5 seconds
68 cache:set("custom:key:"..uri,key,5)
69 cache:set("custom:server:"..uri,server,5)
70 cache:set("custom:url:"..uri,url,5)
73 ngx.var.server = server
78 local function query_allkeys_updatecache(red)
79 -- Try to get all keys start with "msb:routing:custom:"
80 local allkeys, err = red:keys("msb:routing:custom:*")
81 if not allkeys or allkeys == ngx.null then
87 for key, value in ipairs(allkeys) do
88 name = string.gsub(string.gsub(string.gsub(value,"msb:routing:custom:",""),":info",""),":lb:server1","")
91 --取出所有的�?放到table中准备排�?
94 for key,_ in pairs(key_set) do
95 --为了避免效率问题,暂时不用table.insert()
96 --table.insert(key_table,key)
97 key_table[index] = key
100 --对所有键进行倒序排序,用于实现最长前缀匹配
101 table.sort(key_table, function (a, b)
105 local servicenames = ""
106 local delimiter = "<>"
107 for i=1,#key_table do
108 servicenames=servicenames..key_table[i]..delimiter
111 -- get the local cache
112 local cache = ngx.shared.ceryx
113 -- Save all keys to local cache for 30 seconds(0.5 minutes)
114 cache:set("customrouter:allkeys", servicenames, 30)
118 local function query_router_info()
119 local uri = ngx.var.uri
120 ngx.log(ngx.WARN, "==uri:", uri)
122 -- Check if key exists in local cache
123 local cache = ngx.shared.ceryx
124 local key, flags = cache:get("custom:key:"..uri)
125 local server, flags = cache:get("custom:server:"..uri)
126 local url, flags = cache:get("custom:url:"..uri)
127 if key and server and url then
129 ngx.var.server = server
131 ngx.log(ngx.WARN, "==using custom cache:", key.."&&"..server.."&&"..url)
135 local redis = require "resty.redis"
136 local red = redis:new()
137 red:set_timeout(1000) -- 1000 ms
138 local redis_host = "127.0.0.1"
139 local redis_port = 6379
140 local res, err = red:connect(redis_host, redis_port)
142 -- Return if could not connect to Redis
144 ngx.log(ngx.ERR, "connect to redis error:", err)
148 -- Check if all servicenames exists in local cache
149 local servicenames, flags = cache:get("customrouter:allkeys")
151 ngx.log(ngx.WARN,"==get all keys from cache:",servicenames)
153 servicenames = query_allkeys_updatecache(red)
156 local delimiter = "<>"
158 for key in string.gmatch(servicenames,"(.-)"..delimiter) do
159 ngx.log(ngx.WARN, "==key_table key:", key)
160 local from, to, err = ngx.re.find(uri, "^"..key.."(/(.*))?$", "jo")
163 ngx.log(ngx.WARN,"Matched! start-end:",from,"-",to)
164 local result = query_ipurl_updatecache(red,key)
169 ngx.log(ngx.WARN,"not Matched")
171 ngx.log(ngx.WARN,"ngx.re.find throw error: ",err)
177 return close_redis(red)
180 local function rewrite_router_url()
181 local server=ngx.var.server
182 if server=="fallback" then
183 ngx.status = ngx.HTTP_NOT_FOUND
186 local url=ngx.var.url
187 local key=ngx.var.key
188 local rewriteduri = ngx.re.sub(ngx.var.uri, "^"..key.."(.*)", url.."$1", "o")
189 ngx.log(ngx.WARN, "==rewrited uri:", rewriteduri)
190 ngx.req.set_uri(rewriteduri)