This is an automated email from the ASF dual-hosted git repository.
sixh pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/shenyu-nginx.git
The following commit(s) were added to refs/heads/main by this push:
new fd9cf40 add consul sync (#8)
fd9cf40 is described below
commit fd9cf403bf8983a5bfc9a34aa2e22c6d3cb1a7e6
Author: Sinsy <[email protected]>
AuthorDate: Sat Oct 29 17:40:17 2022 +0800
add consul sync (#8)
* add consul
* add watch function
* fix citation error
* support balance
* add watch
* fix error var
* add docs
---
README.md | 62 +++++++++----
example/{etcd => consul}/nginx.conf | 32 ++++---
example/etcd/nginx.conf | 6 +-
lib/shenyu/register/consul.lua | 159 +++++++++++++++++++++++++++++++++
rockspec/shenyu-nginx-1.0.0-1.rockspec | 1 +
5 files changed, 229 insertions(+), 31 deletions(-)
diff --git a/README.md b/README.md
index 17b143f..ef96a97 100644
--- a/README.md
+++ b/README.md
@@ -5,12 +5,22 @@ This module provided SDK to watch available ShenYu instance
list as upstream nod
1. [ETCD](#greeting-etcd) (Supported)
2. [Nacos](#greeting-nacos) (Supported)
3. [Zookeeper](#greeting-zookeeper) (Supported)
-4. Consul (TODO)
+4. [Consul](#greeting-consul) (Supported)
In the cluster mode, Apache ShenYu supports the deployment of multiple ShenYu
instances, which may have new instances joining or leaving at any time.
Hence, Apache ShenYu introduces Service Discovery modules to help client to
detect the available instances.
Currently, Apache ShenYu Bootstrap already supports Apache Zookeeper, Nacos,
Etcd, and consul. Client or LoadBalancer can get the available ShenYu instances
by those Service register center.
+Here provides a completed
[examples](https://github.com/apache/shenyu-nginx/tree/main/example).
+=======
+Here is a completed
[example](https://github.com/apache/shenyu-nginx/blob/main/example/etcd/nginx.conf)
working with ETCD.
+
+Here is a completed
[example](https://github.com/apache/shenyu-nginx/blob/main/example/nacos/nginx.conf)
working with Nacos.
+
+Here is a completed
[example](https://github.com/apache/shenyu-nginx/blob/main/example/consul/nginx.conf)
working with Consul.
+
+Here is a completed
[example](https://github.com/apache/shenyu-nginx/blob/main/example/zookeeper/nginx.conf)
working with Zookeeper.
+
## Getting Started
- Prerequisite:
@@ -62,14 +72,6 @@ upstream shenyu {
}
```
-Finally, restart OpenResty.
-```shell
-openresty -s reload
-```
-
-Here provides a completed
[examples](https://github.com/apache/shenyu-nginx/tree/main/example).
-=======
-Here is a completed
[example](https://github.com/apache/shenyu-nginx/blob/main/example/etcd/nginx.conf)
working with ETCD.
### Greeting Nacos
@@ -104,13 +106,6 @@ upstream shenyu {
}
```
-Finally, restart OpenResty.
-```shell
-openresty -s reload
-```
-
-Here is a completed
[example](https://github.com/apache/shenyu-nginx/blob/main/example/nacos/nginx.conf)
working with Nacos.
-
## Greeting Zookeeper
Modify the Nginx configure, create and initialize the ShenYu register to
connect to target register center.
Listen for changes to the node via the zookeeper watch event. Here is an
example of the zookeeper configuration.
@@ -136,11 +131,44 @@ Modify the upstream to enable to update upstream servers
dynamically. This case
}
}
```
+
+### Greeting Consul
+
+Modify the Nginx configure, create and initialize the ShenYu register to
connect to target register center.
+Listen for changes to the node via the consul watch event. Here is an example
of the consul configuration.
+```shell
+init_worker_by_lua_block {
+ local register = require "shenyu.register.consul";
+ register.init({
+ uri = "http://192.168.152.128:8500",
+ path = "/v1/catalog/service/demo",
+ shenyu_storage = ngx.shared.shenyu_storage,
+ balancer_type = "chash",
+ })
+}
+```
+1. ``balancer_type`` specify the balancer. It has supported `chash` and `round
robin`.
+2. `uri` consul server address.
+3. `path` path of service.
+
+Modify the upstream to enable to update upstream servers dynamically. This
case will synchronize the ShenYu instance list with register center. And then
pick one up for handling the request.
+
+```shell
+ upstream shenyu {
+ server 0.0.0.1;
+ balancer_by_lua_block {
+ require("shenyu.register.consul").pick_and_set_peer()
+ }
+ }
+```
+
+## Finally
+
Finally, restart OpenResty.
```shell
openresty -s reload
```
-Here is a completed
[example](https://github.com/apache/shenyu-nginx/blob/main/example/zookeeper/nginx.conf)
working with Zookeeper.
+
## Contributor and Support
diff --git a/example/etcd/nginx.conf b/example/consul/nginx.conf
similarity index 62%
copy from example/etcd/nginx.conf
copy to example/consul/nginx.conf
index 41b7a18..df93391 100644
--- a/example/etcd/nginx.conf
+++ b/example/consul/nginx.conf
@@ -15,37 +15,45 @@
# specific language governing permissions and limitations
# under the License.
-worker_processes 4;
-daemon off;
+worker_processes 2;
error_log /dev/stdout debug;
-
events {
- worker_connections 1024;
+ worker_connections 1024;
}
http {
- lua_shared_dict shenyu_storage 1m;
+ default_type application/octet-stream;
+ access_log logs/access.log;
+ lua_shared_dict shenyu_storage 10m;
init_worker_by_lua_block {
- local register = require("shenyu.register.etcd")
+ local register = require "shenyu.register.consul";
register.init({
+ uri = "http://192.168.152.128:8500",
+ path = "/v1/catalog/service/demo",
shenyu_storage = ngx.shared.shenyu_storage,
balancer_type = "chash",
- etcd_base_url = "http://127.0.0.01:2379",
})
}
upstream shenyu {
- server 0.0.0.1;
- balancer_by_lua_block {
- require("shenyu.register.etcd").pick_and_set_peer()
+ server 0.0.0.1 down;
+ balancer_by_lua_block {
+ local consul = require "shenyu.register.consul";
+ consul.pick_and_set_peer();
}
}
-
server {
- listen 8080;
+ listen 80;
+ server_name localhost;
+ default_type text/html;
+ location = /favicon.ico {
+ log_not_found off;
+ access_log off;
+ }
location ~ /* {
proxy_pass http://shenyu;
+
}
}
}
diff --git a/example/etcd/nginx.conf b/example/etcd/nginx.conf
index 41b7a18..94f495d 100644
--- a/example/etcd/nginx.conf
+++ b/example/etcd/nginx.conf
@@ -23,14 +23,14 @@ events {
worker_connections 1024;
}
http {
- lua_shared_dict shenyu_storage 1m;
+ lua_shared_dict shenyu_storage 10m;
init_worker_by_lua_block {
local register = require("shenyu.register.etcd")
register.init({
shenyu_storage = ngx.shared.shenyu_storage,
balancer_type = "chash",
- etcd_base_url = "http://127.0.0.01:2379",
+ etcd_base_url = "http://192.168.0.106:2379",
})
}
@@ -49,3 +49,5 @@ http {
}
}
}
+
+
diff --git a/lib/shenyu/register/consul.lua b/lib/shenyu/register/consul.lua
new file mode 100644
index 0000000..7282742
--- /dev/null
+++ b/lib/shenyu/register/consul.lua
@@ -0,0 +1,159 @@
+--
+-- Licensed to the Apache Software Foundation (ASF) under one or more
+-- contributor license agreements. See the NOTICE file distributed with
+-- this work for additional information regarding copyright ownership.
+-- The ASF licenses this file to You under the Apache License, Version 2.0
+-- (the "License"); you may not use this file except in compliance with
+-- the License. You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+local http = require("resty.http")
+local json = require("cjson")
+local ngx_balancer = require("ngx.balancer")
+
+local balancer = require("shenyu.register.balancer")
+
+local ngx_timer_at = ngx.timer.at
+local ngx_worker_exiting = ngx.worker.exiting
+
+local log = ngx.log
+local ERR = ngx.ERR
+
+local _M = {}
+
+_M._VERSION="0.1"
+
+local function get_server_list()
+ local httpc = http.new()
+
+ local res, err = httpc:request_uri(_M.uri, {
+ method = "GET",
+ path = _M.path,
+
+ })
+
+ if not res then
+ log(ERR, "failed to request.")
+ return nil, err
+ end
+
+ if res.status == 200 then
+ local upstreams = {}
+ local kvs = json.decode(res.body)
+
+ for _, v in ipairs(kvs) do
+ local instanceId = ""
+ instanceId = instanceId .. v.ServiceAddress .. ":" .. v.ServicePort
+ upstreams[instanceId] = 1
+ end
+
+ return upstreams, err
+ end
+
+ return nil, err
+end
+
+local function sync(premature)
+
+ if premature or ngx_worker_exiting() then
+ return
+ end
+
+ local storage = _M.storage
+
+ local server_list = storage:get("server_list")
+ local servers = json.decode(server_list)
+
+ _M.balancer:reinit(servers)
+
+ local ok, err = ngx_timer_at(2, sync)
+
+ if not ok then
+ log(ERR, "failed to start sync ", err)
+ end
+
+end
+
+local function subscribe(premature, initialized)
+ if premature or ngx_worker_exiting() then
+ return
+ end
+
+ if not initialized then
+
+ local server_list, err = get_server_list()
+
+ if not server_list then
+ log(ERR, "", err)
+ goto continue
+ end
+
+ _M.balancer:init(server_list)
+
+ local server_list_in_json = json.encode(server_list)
+ _M.storage:set("server_list", server_list_in_json)
+
+ initialized = true
+ else
+ local server_list, err = get_server_list()
+
+ if not server_list then
+ log(ERR, "", err)
+ goto continue
+ end
+
+ _M.balancer:reinit(server_list)
+
+ local server_list_in_json = json.encode(server_list)
+ _M.storage:set("server_list", server_list_in_json)
+ end
+
+
+ :: continue ::
+ local ok, err = ngx_timer_at(2, subscribe, initialized)
+ if not ok then
+ log(ERR, "failed to subscribe: ", err)
+ end
+
+ return
+
+
+end
+
+
+function _M:pick_and_set_peer(key)
+ local server = _M.balancer:find(key)
+ ngx_balancer.set_current_peer(server)
+end
+
+
+function _M.init(conf)
+
+ _M.uri = conf.uri
+ _M.path = conf.path
+ _M.storage = conf.shenyu_storage
+ _M.balancer = balancer.new(conf.balancer_type)
+ if 0 == ngx.worker.id() then
+ local ok, err = ngx_timer_at(0, subscribe)
+ if not ok then
+ log(ERR, "failed to start watch: ", err)
+ return
+ end
+ end
+
+ local ok, err = ngx_timer_at(2, sync)
+ if not ok then
+ log(ERR, "failed to start sync ", err)
+ end
+
+end
+
+return _M
\ No newline at end of file
diff --git a/rockspec/shenyu-nginx-1.0.0-1.rockspec
b/rockspec/shenyu-nginx-1.0.0-1.rockspec
index 37d3a4c..e2cdcdd 100644
--- a/rockspec/shenyu-nginx-1.0.0-1.rockspec
+++ b/rockspec/shenyu-nginx-1.0.0-1.rockspec
@@ -41,6 +41,7 @@ build = {
["shenyu.register.etcd"] = "lib/shenyu/register/etcd.lua",
["shenyu.register.nacos"] = "lib/shenyu/register/nacos.lua",
["shenyu.register.balancer"] = "lib/shenyu/register/balancer.lua",
+ ["shenyu.register.consul"] = "lib/shenyu/register/consul.lua",
["shenyu.register.zookeeper"] = "lib/shenyu/register/zookeeper.lua",
["shenyu.register.zookeeper.connection"] =
"lib/shenyu/register/zookeeper/connection.lua",
["shenyu.register.zookeeper.zk_client"] =
"lib/shenyu/register/zookeeper/zk_client.lua",