This is an automated email from the ASF dual-hosted git repository.

spacewander pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git


The following commit(s) were added to refs/heads/master by this push:
     new 4570fec69 feat: support configuring the order of the upstream dns 
service discovery resolve (#7935)
4570fec69 is described below

commit 4570fec6941956e4e70886e6e78b604fe25f6c2a
Author: levy liu <[email protected]>
AuthorDate: Mon Sep 26 15:00:44 2022 +0800

    feat: support configuring the order of the upstream dns service discovery 
resolve (#7935)
---
 apisix/discovery/dns/init.lua   |   6 +-
 apisix/discovery/dns/schema.lua |   9 +++
 conf/config-default.yaml        |   6 ++
 docs/en/latest/discovery/dns.md |  17 +++++-
 docs/zh/latest/discovery/dns.md |  19 ++++++-
 t/discovery/dns/sanity.t        | 120 ++++++++++++++++++++++++++++++++++++++++
 6 files changed, 172 insertions(+), 5 deletions(-)

diff --git a/apisix/discovery/dns/init.lua b/apisix/discovery/dns/init.lua
index 335993e43..a0408a9c2 100644
--- a/apisix/discovery/dns/init.lua
+++ b/apisix/discovery/dns/init.lua
@@ -59,11 +59,15 @@ function _M.init_worker()
     local local_conf = config_local.local_conf()
     local servers = local_conf.discovery.dns.servers
 
+    local default_order = {"last", "SRV", "A", "AAAA", "CNAME"}
+    local order = core.table.try_read_attr(local_conf, "discovery", "dns", 
"order")
+    order = order or default_order
+
     local opts = {
         hosts = {},
         resolvConf = {},
         nameservers = servers,
-        order = {"last", "SRV", "A", "AAAA", "CNAME"},
+        order = order,
     }
 
     local client, err = core.dns_client.new(opts)
diff --git a/apisix/discovery/dns/schema.lua b/apisix/discovery/dns/schema.lua
index 94fc9c3cb..989938ab1 100644
--- a/apisix/discovery/dns/schema.lua
+++ b/apisix/discovery/dns/schema.lua
@@ -24,6 +24,15 @@ return {
                 type = "string",
             },
         },
+        order = {
+            type = "array",
+            minItems = 1,
+            maxItems = 5,
+            uniqueItems = true,
+            items = {
+                enum = {"last", "SRV", "A", "AAAA", "CNAME"}
+            },
+        },
     },
     required = {"servers"}
 }
diff --git a/conf/config-default.yaml b/conf/config-default.yaml
index f6b81824e..78bee8600 100755
--- a/conf/config-default.yaml
+++ b/conf/config-default.yaml
@@ -259,6 +259,12 @@ nginx_config:                     # config for render the 
template to generate n
 #  dns:
 #    servers:
 #      - "127.0.0.1:8600"         # use the real address of your dns server
+#    order:                       # order in which to try different dns record 
types when resolving
+#      - last                     # "last" will try the last previously 
successful type for a hostname.
+#      - SRV
+#      - A
+#      - AAAA
+#      - CNAME
 #  eureka:
 #    host:                        # it's possible to define multiple eureka 
hosts addresses of the same eureka cluster.
 #      - "http://127.0.0.1:8761";
diff --git a/docs/en/latest/discovery/dns.md b/docs/en/latest/discovery/dns.md
index 83d306e9f..884286e80 100644
--- a/docs/en/latest/discovery/dns.md
+++ b/docs/en/latest/discovery/dns.md
@@ -64,8 +64,23 @@ and `test.consul.service` be resolved as `1.1.1.1` and 
`1.1.1.2`, this result wi
 Note that all the IPs from `test.consul.service` share the same weight.
 
 The resolved records will be cached according to their TTL.
-For service whose record is not in the cache, we will query it in the order of 
`SRV -> A -> AAAA -> CNAME`.
+For service whose record is not in the cache, we will query it in the order of 
`SRV -> A -> AAAA -> CNAME` by default.
 When we refresh the cache record, we will try from the last previously 
successful type.
+We can also customize the order by modifying the configuration file.
+
+```yaml
+# add this to config.yaml
+discovery:
+   dns:
+     servers:
+       - "127.0.0.1:8600"          # use the real address of your dns server
+     order:                        # order in which to try different dns 
record types when resolving
+       - last                      # "last" will try the last previously 
successful type for a hostname.
+       - SRV
+       - A
+       - AAAA
+       - CNAME
+```
 
 If you want to specify the port for the upstream server, you can add it to the 
`service_name`:
 
diff --git a/docs/zh/latest/discovery/dns.md b/docs/zh/latest/discovery/dns.md
index 47debd65d..e2a56bc99 100644
--- a/docs/zh/latest/discovery/dns.md
+++ b/docs/zh/latest/discovery/dns.md
@@ -61,9 +61,22 @@ discovery:
 
 注意所有来自 `test.consul.service` 的 IP 都有相同的权重。
 
-解析的记录将根据它们的 TTL 来进行缓存。
-对于记录不在缓存中的服务,我们将按照 `SRV -> A -> AAAA -> CNAME` 的顺序进行查询。
-刷新缓存记录时,我们将从上次成功的类型开始尝试。
+解析的记录将根据它们的 TTL 来进行缓存。对于记录不在缓存中的服务,我们将默认按照 `SRV -> A -> AAAA -> CNAME` 
的顺序进行查询,刷新缓存记录时,我们将从上次成功的类型开始尝试。也可以通过修改配置文件来自定义 DNS 的解析顺序。
+
+```yaml
+# 添加到 config.yaml
+discovery:
+   dns:
+     servers:
+       - "127.0.0.1:8600"          # 使用 DNS 服务器的真实地址
+     order:                        # DNS 解析的顺序
+       - last                      # "last" 表示从上次成功的类型开始
+       - SRV
+       - A
+       - AAAA
+       - CNAME
+
+```
 
 如果你想指定 upstream 服务器的端口,可以把以下内容添加到 `service_name`:
 
diff --git a/t/discovery/dns/sanity.t b/t/discovery/dns/sanity.t
index 8c1890bef..6742223ee 100644
--- a/t/discovery/dns/sanity.t
+++ b/t/discovery/dns/sanity.t
@@ -120,6 +120,10 @@ upstreams:
       id: 1
 --- response_body
 hello world
+--- grep_error_log eval
+qr/proxy request to \S+/
+--- grep_error_log_out
+proxy request to [0:0:0:0:0:0:0:1]:1980
 
 
 
@@ -133,6 +137,10 @@ upstreams:
       id: 1
 --- response_body
 hello world
+--- grep_error_log eval
+qr/proxy request to \S+/
+--- grep_error_log_out
+proxy request to 127.0.0.1:1980
 
 
 
@@ -318,3 +326,115 @@ qr/upstream nodes: \{[^}]+\}/
 qr/upstream nodes: 
\{("127.0.0.1:1980":60,"127.0.0.2:1980":20|"127.0.0.2:1980":20,"127.0.0.1:1980":60)\}/
 --- response_body
 hello world
+
+
+
+=== TEST 16: prefer A than SRV when A is ahead of SRV in config.yaml
+--- yaml_config
+apisix:
+    node_listen: 1984
+    enable_admin: false
+deployment:
+    role: data_plane
+    role_data_plane:
+        config_provider: yaml
+discovery:
+    dns:
+        servers:
+            - "127.0.0.1:1053"
+        order:
+            - A
+            - SRV
+--- apisix_yaml
+upstreams:
+    - service_name: "srv-a.test.local"
+      discovery_type: dns
+      type: roundrobin
+      id: 1
+--- error_code: 502
+--- error_log
+proxy request to 127.0.0.1:80
+
+
+
+=== TEST 17: Invalid order type in config.yaml
+--- yaml_config
+apisix:
+    node_listen: 1984
+    enable_admin: false
+deployment:
+    role: data_plane
+    role_data_plane:
+        config_provider: yaml
+discovery:
+    dns:
+        servers:
+            - "127.0.0.1:1053"
+        order:
+            - B
+            - SRV
+--- apisix_yaml
+upstreams:
+    - service_name: "srv-a.test.local"
+      discovery_type: dns
+      type: roundrobin
+      id: 1
+--- must_die
+--- error_log
+matches none of the enum values
+
+
+
+=== TEST 18: Multiple order type in config.yaml
+--- yaml_config
+apisix:
+    node_listen: 1984
+    enable_admin: false
+deployment:
+    role: data_plane
+    role_data_plane:
+        config_provider: yaml
+discovery:
+    dns:
+        servers:
+            - "127.0.0.1:1053"
+        order:
+            - SRV
+            - SRV
+--- apisix_yaml
+upstreams:
+    - service_name: "srv-a.test.local"
+      discovery_type: dns
+      type: roundrobin
+      id: 1
+--- must_die
+--- error_log
+expected unique items but items 1 and 2 are equal
+
+
+
+=== TEST 19: invalid order type in config.yaml
+--- yaml_config
+apisix:
+    node_listen: 1984
+    enable_admin: false
+deployment:
+    role: data_plane
+    role_data_plane:
+        config_provider: yaml
+discovery:
+    dns:
+        servers:
+            - "127.0.0.1:1053"
+        order:
+            - a
+            - SRV
+--- apisix_yaml
+upstreams:
+    - service_name: "srv-a.test.local"
+      discovery_type: dns
+      type: roundrobin
+      id: 1
+--- must_die
+--- error_log
+matches none of the enum values

Reply via email to