{"id":20802341,"url":"https://github.com/eratel/discovery-redis","last_synced_at":"2025-10-13T09:37:43.430Z","repository":{"id":228347486,"uuid":"142371189","full_name":"eratel/Discovery-redis","owner":"eratel","description":"基于https://github.com/Nepxion/Discovery.git  的灰度发布拓展,支持redis存储分发集群，服务拉起后自动同步灰度规则。使用DEV分支！！ 代码已经无偿贡献给到官方可以直接下载啦！https://github.com/Nepxion/Discovery.git","archived":false,"fork":false,"pushed_at":"2018-07-27T06:18:37.000Z","size":284,"stargazers_count":18,"open_issues_count":1,"forks_count":10,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-17T16:46:27.529Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eratel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2018-07-26T01:17:17.000Z","updated_at":"2023-10-27T08:10:39.000Z","dependencies_parsed_at":"2024-03-18T11:23:14.571Z","dependency_job_id":null,"html_url":"https://github.com/eratel/Discovery-redis","commit_stats":null,"previous_names":["eratel/discovery-redis"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/eratel/Discovery-redis","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eratel%2FDiscovery-redis","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eratel%2FDiscovery-redis/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eratel%2FDiscovery-redis/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eratel%2FDiscovery-redis/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eratel","download_url":"https://codeload.github.com/eratel/Discovery-redis/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eratel%2FDiscovery-redis/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279014547,"owners_count":26085536,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-13T02:00:06.723Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-17T18:30:33.705Z","updated_at":"2025-10-13T09:37:43.413Z","avatar_url":"https://github.com/eratel.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Nepxion Discovery\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg?label=license)](https://github.com/Nepxion/Discovery/blob/master/LICENSE)\n[![Maven Central](https://img.shields.io/maven-central/v/com.nepxion/discovery.svg?label=maven%20central)](http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.nepxion%22%20AND%20discovery)\n[![Javadocs](http://www.javadoc.io/badge/com.nepxion/discovery.svg)](http://www.javadoc.io/doc/com.nepxion/discovery)\n[![Build Status](https://travis-ci.org/Nepxion/Discovery.svg?branch=master)](https://travis-ci.org/Nepxion/Discovery)\n\nNepxion Discovery是一款对Spring Cloud的服务注册发现的增强中间件，其功能包括多版本灰度发布，黑/白名单的IP地址过滤，限制注册等，支持Eureka、Consul和Zookeeper，支持Spring Cloud Api Gateway（F版）、Zuul网关和微服务的灰度发布，支持Alibaba的Nacos为远程配置中心，支持Spring Cloud C版、D版、E版和F版。现有的Spring Cloud微服务可以方便引入该插件，代码零侵入\n\n使用者只需要做如下简单的事情：\n- 引入相关Plugin Starter依赖到pom.xml\n- 必须为微服务定义一个版本号（version），必须为微服务自定义一个便于为微服务归类的Key，例如组名（group）或者应用名（application）。两者定义在application.properties或者yaml的metadata里，便于远程配置中心推送和灰度界面分析\n- 使用者只需要关注相关规则推送。可以采用如下方式之一\n  - 通过远程配置中心推送规则\n  - 通过控制台界面推送规则\n  - 通过客户端工具（例如Postman）推送\n\n## 请联系我\n- 请加微信群或者微信\n\n![Alt text](https://github.com/Nepxion/Docs/blob/master/zxing-doc/微信群-1.jpg) ![Alt text](https://github.com/Nepxion/Docs/blob/master/zxing-doc/微信-1.jpg)\n\n## 快速开始\n- 图形化演示操作\n  - 请访问[http://www.iqiyi.com/w_19rzwzovrl.html](http://www.iqiyi.com/w_19rzwzovrl.html)，视频清晰度改成720P，然后最大化播放\n  - 请访问[https://pan.baidu.com/s/1eq_N56VbgSCaTXYQ5aKqiA](https://pan.baidu.com/s/1eq_N56VbgSCaTXYQ5aKqiA)，获取更清晰的视频，注意一定要下载下来看，不要在线看，否则也不清晰\n![Alt text](https://github.com/Nepxion/Docs/blob/master/discovery-plugin-doc/Console1.jpg)\n![Alt text](https://github.com/Nepxion/Docs/blob/master/discovery-plugin-doc/Console2.jpg)  \n- 更多教程和示例查看最下面的“示例演示”\n\n## 痛点\n现有Spring Cloud的痛点\n- 如果你是运维负责人，是否会经常发现，你掌管的测试环境中的服务注册中心，被一些不负责的开发人员把他本地开发环境注册上来，造成测试人员测试失败。你希望可以把本地开发环境注册给屏蔽掉，不让注册\n- 如果你是运维负责人，生产环境的某个微服务集群下的某个实例，暂时出了问题，但又不希望它下线。你希望可以把该实例给屏蔽掉，暂时不让它被调用\n- 如果你是业务负责人，鉴于业务服务的快速迭代性，微服务集群下的实例发布不同的版本。你希望根据版本管理策略进行路由，提供给下游微服务区别调用，达到多版本灰度访问控制\n- 如果你是测试负责人，希望对微服务做A/B测试，那么通过动态改变版本达到该目的\n\n## 简介\n- 实现对基于Spring Cloud的微服务和Spring Cloud Api Gateway（F版）和Zuul网关的支持\n  - 具有极大灵活性 - 支持在任何环节做过滤控制和版本灰度发布\n  - 具有极小限制性 - 只要开启了服务注册发现，程序入口加了@EnableDiscoveryClient\n- 实现服务注册层面的控制\n  - 基于黑/白名单的IP地址过滤机制禁止对相应的微服务进行注册\n  - 基于最大注册数的限制微服务注册。一旦微服务集群下注册的实例数目已经达到上限，将禁止后续的微服务进行注册\n- 实现服务发现层面的控制\n  - 基于黑/白名单的IP地址过滤机制禁止对相应的微服务被发现\n  - 基于版本配对，通过对消费端和提供端可访问版本对应关系的配置，在服务发现和负载均衡层面，进行多版本访问控制\n- 实现灰度发布\n  - 通过规则改变，实现灰度发布\n  - 通过版本切换，实现灰度发布\n- 实现通过XML进行上述规则的定义\n- 实现通过事件总线机制（EventBus）的功能，实现发布/订阅功能\n  - 对接远程配置中心，默认集成阿里巴巴的Nacos，异步接受远程配置中心主动推送规则信息，动态改变微服务的规则\n  - 结合Spring Boot Actuator，异步接受Rest主动推送规则信息，动态改变微服务的规则\n  - 结合Spring Boot Actuator，动态改变微服务的版本\n  - 在服务注册层面的控制中，一旦禁止注册的条件触发，主动推送异步事件，以便使用者订阅\n- 实现通过Listener机制进行扩展\n  - 使用者可以自定义更多的规则过滤条件\n  - 使用者可以对服务注册发现核心事件进行监听\n- 实现支持Spring Boot Actuator和Swagger集成\n- 实现独立控制台，支持对规则和版本集中管理，未来考虑界面实现\n- 实现支持未来扩展更多的服务注册中心\n- 实现图形化的灰度发布功能\n\n## 名词解释\n- IP地址，即根据微服务上报的它所在机器的IP地址。本系统内部强制以IP地址上报，禁止HostName上报，杜绝Spring Cloud应用在Docker或者Kubernetes部署时候出现问题\n- 本地版本，即初始化读取本地配置文件获取的版本，也可以是第一次读取远程配置中心获取的版本。本地版本和初始版本是同一个概念\n- 动态版本，即灰度发布时的版本。动态版本和灰度版本是同一个概念\n- 本地规则，即初始化读取本地配置文件获取的规则，也可以是第一次读取远程配置中心获取的规则。本地规则和初始规则是同一个概念\n- 动态规则，即灰度发布时的规则。动态规则和灰度规则是同一个概念\n- 事件总线，即基于Google Guava的EventBus构建的组件。在使用上，通过事件总线推送动态版本和动态规则的时候，前者只支持异步，后者支持异步和同步\n- 远程配置中心，即可以存储规则配置XML格式的配置中心，可以包括不限于Nacos，Apollo，DisConf，Spring Cloud Config\n- 配置（Config）和规则（Rule），在本系统中属于同一个概念，例如更新配置，即更新规则，例如远程配置中心存储的配置，即规则XML\n\n## 场景\n- 黑/白名单的IP地址注册的过滤\n  - 开发环境的本地微服务（例如IP地址为172.16.0.8）不希望被注册到测试环境的服务注册发现中心，那么可以在配置中心维护一个黑/白名单的IP地址过滤（支持全局和局部的过滤）的规则\n  - 我们可以通过提供一份黑/白名单达到该效果\n- 最大注册数的限制的过滤\n  - 当某个微服务注册数目已经达到上限（例如10个），那么后面起来的微服务，将再也不能注册上去\n- 黑/白名单的IP地址发现的过滤\n  - 开发环境的本地微服务（例如IP地址为172.16.0.8）已经注册到测试环境的服务注册发现中心，那么可以在配置中心维护一个黑/白名单的IP地址过滤（支持全局和局部的过滤）的规则，该本地微服务不会被其他测试环境的微服务所调用\n  - 我们可以通过推送一份黑/白名单达到该效果\n- 多版本灰度访问控制\n  - A服务调用B服务，而B服务有两个实例（B1、B2），虽然三者相同的服务名，但功能上有差异，需求是在某个时刻，A服务只能调用B1，禁止调用B2。在此场景下，我们在application.properties里为B1维护一个版本为1.0，为B2维护一个版本为1.1\n  - 我们可以通过推送A服务调用某个版本的B服务对应关系的配置，达到某种意义上的灰度控制，切换版本的时候，我们只需要再次推送即可\n- 动态改变微服务版本\n  - 在A/B测试中，通过动态改变版本，不重启微服务，达到访问版本的路径改变\n\n## 架构\n简单描述一下，本系统的核心模块“基于版本控制的灰度发布”，从网关（Zuul）开始的灰度发布操作过程\n- 灰度发布前\n  - 假设当前生产环境，调用路径为网关(V1.0)-\u003e服务A(V1.0)-\u003e服务B(V1.0)\n  - 运维将发布新的生产环境，部署新服务集群，服务A(V1.1)，服务B(V1.1)\n  - 由于网关(1.0)并未指向服务A(V1.1)，服务B(V1.1)，所以它们是不能被调用的  \n- 灰度发布中\n  - 新增用作灰度发布的网关(V1.1)，指向服务A(V1.1)-\u003e服务B(V1.1)\n  - 灰度网关(V1.1)发布到服务注册发现中心，但禁止被服务发现，网关外的调用进来无法负载均衡到网关(V1.1)上\n  - 在灰度网关(V1.1)-\u003e服务A(V1.1)-\u003e服务B(V1.1)这条调用路径做灰度测试\n  - 灰度测试成功后，把网关(V1.0)指向服务A(V1.1)-\u003e服务B(V1.1)\n- 灰度发布后  \n  - 下线服务A(V1.0)，服务B(V1.0)，灰度成功\n  - 灰度网关(V1.1)可以不用下线，留作下次版本上线再次灰度发布\n\n架构图\n\n![Alt text](https://github.com/Nepxion/Docs/blob/master/discovery-plugin-doc/Architecture.jpg)\n\n## 兼容\n版本兼容情况\n- Spring Cloud F版，请采用4.x.x版本，具体代码参考master分支\n- Spring Cloud C版、D版和E版，请采用3.x.x版本，具体代码参考Edgware分支\n- 4.x.x版本由于Swagger和Spring Boot 2.x.x版本的Actuator用法有冲突，故暂时不支持Endpoint功能，其他功能和3.x.x版本一致\n\n中间件兼容情况\n- Consul\n  - Consul服务器版本不限制，推荐用最新版本，从[https://releases.hashicorp.com/consul/1.2.1/](https://releases.hashicorp.com/consul/1.2.1/)获取\n- Zookeeper\n  - Spring Cloud F版，必须采用Zookeeper服务器的3.5.x服务器版本（或者更高）\n  - Spring Cloud C版、D版和E版，Zookeeper服务器版本不限制\n- Eureka\n  - 跟Spring Cloud版本保持一致\n\n## 依赖\n微服务选择相应的插件引入，最后一个如需对接Nacos远程配置中心，则引入\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.nepxion\u003c/groupId\u003e\n    \u003cartifactId\u003ediscovery-plugin-starter-eureka\u003c/artifactId\u003e\n    \u003cversion\u003e${discovery.plugin.version}\u003c/version\u003e\n\u003c/dependency\u003e\n\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.nepxion\u003c/groupId\u003e\n    \u003cartifactId\u003ediscovery-plugin-starter-consul\u003c/artifactId\u003e\n    \u003cversion\u003e${discovery.plugin.version}\u003c/version\u003e\n\u003c/dependency\u003e\n\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.nepxion\u003c/groupId\u003e\n    \u003cartifactId\u003ediscovery-plugin-starter-zookeeper\u003c/artifactId\u003e\n    \u003cversion\u003e${discovery.plugin.version}\u003c/version\u003e\n\u003c/dependency\u003e\n\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.nepxion\u003c/groupId\u003e\n    \u003cartifactId\u003ediscovery-plugin-config-center-extension-nacos\u003c/artifactId\u003e\n    \u003cversion\u003e${discovery.plugin.version}\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n独立控制台引入，最后一个如需对接Nacos远程配置中心，则引入\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.nepxion\u003c/groupId\u003e\n    \u003cartifactId\u003ediscovery-console-starter\u003c/artifactId\u003e\n    \u003cversion\u003e${discovery.plugin.version}\u003c/version\u003e\n\u003c/dependency\u003e\n\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.nepxion\u003c/groupId\u003e\n    \u003cartifactId\u003ediscovery-console-extension-nacos\u003c/artifactId\u003e\n    \u003cversion\u003e${discovery.plugin.version}\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n## 工程\n\n| 工程名 | 描述 |\n| --- | --- | \n| discovery-plugin-framework | 核心框架 |\n| discovery-plugin-framework-eureka | 核心框架的Eureka实现 |\n| discovery-plugin-framework-consul | 核心框架的Consul实现 |\n| discovery-plugin-framework-zookeeper | 核心框架的Zookeeper实现 |\n| discovery-plugin-config-center | 配置中心实现 |\n| discovery-plugin-config-center-extension-nacos | 配置中心的Nacos扩展 |\n| discovery-plugin-admin-center | 管理中心实现 |\n| discovery-plugin-starter-eureka | Eureka Starter |\n| discovery-plugin-starter-consul | Consul Starter |\n| discovery-plugin-starter-zookeeper | Zookeeper Starter |\n| discovery-console | 独立控制台，提供给UI |\n| discovery-console-extension-nacos | 独立控制台的Nacos扩展 |\n| discovery-console-starter | Console Starter |\n| discovery-console-desktop | 图形化灰度发布等桌面程序 |\n| discovery-springcloud-example-console | 独立控制台示例 |\n| discovery-springcloud-example-eureka | Eureka服务器 |\n| discovery-springcloud-gateway | 用于灰度发布的Spring Cloud Api Gateway（F版）示例 |\n| discovery-springcloud-example | 用于灰度发布的微服务和Zuul示例 |\n\n## 规则和策略\n### 规则示例\n请不要被吓到，我只是把注释写的很详细而已，里面配置没几行\n```xml\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003crule\u003e\n    \u003c!-- 如果不想开启相关功能，只需要把相关节点删除即可，例如不想要黑名单功能，把blacklist节点删除 --\u003e\n    \u003cregister\u003e\n        \u003c!-- 服务注册的黑/白名单注册过滤，只在服务启动的时候生效。白名单表示只允许指定IP地址前缀注册，黑名单表示不允许指定IP地址前缀注册。每个服务只能同时开启要么白名单，要么黑名单 --\u003e\n        \u003c!-- filter-type，可选值blacklist/whitelist，表示白名单或者黑名单 --\u003e\n        \u003c!-- service-name，表示服务名 --\u003e\n        \u003c!-- filter-value，表示黑/白名单的IP地址列表。IP地址一般用前缀来表示，如果多个用“;”分隔，不允许出现空格 --\u003e\n        \u003c!-- 表示下面所有服务，不允许10.10和11.11为前缀的IP地址注册（全局过滤） --\u003e\n        \u003cblacklist filter-value=\"10.10;11.11\"\u003e\n            \u003c!-- 表示下面服务，不允许172.16和10.10和11.11为前缀的IP地址注册 --\u003e\n            \u003cservice service-name=\"discovery-springcloud-example-a\" filter-value=\"172.16\"/\u003e\n        \u003c/blacklist\u003e\n\n        \u003c!-- \u003cwhitelist filter-value=\"\"\u003e\n            \u003cservice service-name=\"\" filter-value=\"\"/\u003e\n        \u003c/whitelist\u003e  --\u003e\n\n        \u003c!-- 服务注册的数目限制注册过滤，只在服务启动的时候生效。当某个服务的实例注册达到指定数目时候，更多的实例将无法注册 --\u003e\n        \u003c!-- service-name，表示服务名 --\u003e\n        \u003c!-- filter-value，表示最大实例注册数 --\u003e\n        \u003c!-- 表示下面所有服务，最大实例注册数为10000（全局配置） --\u003e\n        \u003ccount filter-value=\"10000\"\u003e\n            \u003c!-- 表示下面服务，最大实例注册数为5000，全局配置值10000将不起作用，以局部配置值为准 --\u003e\n            \u003cservice service-name=\"discovery-springcloud-example-a\" filter-value=\"5000\"/\u003e\n        \u003c/count\u003e\n    \u003c/register\u003e\n\n    \u003cdiscovery\u003e\n        \u003c!-- 服务发现的黑/白名单发现过滤，使用方式跟“服务注册的黑/白名单过滤”一致 --\u003e\n        \u003c!-- 表示下面所有服务，不允许10.10和11.11为前缀的IP地址被发现（全局过滤） --\u003e\n        \u003cblacklist filter-value=\"10.10;11.11\"\u003e\n            \u003c!-- 表示下面服务，不允许172.16和10.10和11.11为前缀的IP地址被发现 --\u003e\n            \u003cservice service-name=\"discovery-springcloud-example-b\" filter-value=\"172.16\"/\u003e\n        \u003c/blacklist\u003e\n\n        \u003c!-- 服务发现的多版本灰度访问控制 --\u003e\n        \u003c!-- service-name，表示服务名 --\u003e\n        \u003c!-- version-value，表示可供访问的版本，如果多个用“;”分隔，不允许出现空格 --\u003e\n        \u003cversion\u003e\n            \u003c!-- 表示消费端服务a的1.0，允许访问提供端服务b的1.0和1.1版本 --\u003e\n            \u003cservice consumer-service-name=\"discovery-springcloud-example-a\" provider-service-name=\"discovery-springcloud-example-b\" consumer-version-value=\"1.0\" provider-version-value=\"1.0;1.1\"/\u003e\n            \u003c!-- 表示消费端服务b的1.0，允许访问提供端服务c的1.0和1.1版本 --\u003e\n            \u003cservice consumer-service-name=\"discovery-springcloud-example-b\" provider-service-name=\"discovery-springcloud-example-c\" consumer-version-value=\"1.0\" provider-version-value=\"1.0;1.1\"/\u003e\n            \u003c!-- 表示消费端服务b的1.1，允许访问提供端服务c的1.2版本 --\u003e\n            \u003cservice consumer-service-name=\"discovery-springcloud-example-b\" provider-service-name=\"discovery-springcloud-example-c\" consumer-version-value=\"1.1\" provider-version-value=\"1.2\"/\u003e\n        \u003c/version\u003e\n    \u003c/discovery\u003e\n\u003c/rule\u003e\n```\n\n### 多版本灰度规则策略\n```xml\n版本策略介绍\n1. 标准配置，举例如下\n   \u003cservice consumer-service-name=\"a\" provider-service-name=\"b\" consumer-version-value=\"1.0\" provider-version-value=\"1.0,1.1\"/\u003e 表示消费端1.0版本，允许访问提供端1.0和1.1版本\n2. 版本值不配置，举例如下\n   \u003cservice consumer-service-name=\"a\" provider-service-name=\"b\" provider-version-value=\"1.0,1.1\"/\u003e 表示消费端任何版本，允许访问提供端1.0和1.1版本\n   \u003cservice consumer-service-name=\"a\" provider-service-name=\"b\" consumer-version-value=\"1.0\"/\u003e 表示消费端1.0版本，允许访问提供端任何版本\n   \u003cservice consumer-service-name=\"a\" provider-service-name=\"b\"/\u003e 表示消费端任何版本，允许访问提供端任何版本\n3. 版本值空字符串，举例如下\n   \u003cservice consumer-service-name=\"a\" provider-service-name=\"b\" consumer-version-value=\"\" provider-version-value=\"1.0,1.1\"/\u003e 表示消费端任何版本，允许访问提供端1.0和1.1版本\n   \u003cservice consumer-service-name=\"a\" provider-service-name=\"b\" consumer-version-value=\"1.0\" provider-version-value=\"\"/\u003e 表示消费端1.0版本，允许访问提供端任何版本\n   \u003cservice consumer-service-name=\"a\" provider-service-name=\"b\" consumer-version-value=\"\" provider-version-value=\"\"/\u003e 表示消费端任何版本，允许访问提供端任何版本\n4. 版本对应关系未定义，默认消费端任何版本，允许访问提供端任何版本\n\n特殊情况处理，在使用上需要极力避免该情况发生\n1. 消费端的application.properties未定义版本号，则该消费端可以访问提供端任何版本\n2. 提供端的application.properties未定义版本号，当消费端在xml里不做任何版本配置，才可以访问该提供端\n```\n\n### 动态改变规则策略\n微服务启动的时候，由于规则（例如：rule.xml）已经配置在本地，使用者希望改变一下规则，而不重启微服务，达到规则的改变 \n- 规则分为本地规则和动态规则\n- 本地规则是通过在本地规则（例如：rule.xml）文件定义的，也可以从远程配置中心获取，在微服务启动的时候读取\n- 动态规则是通过POST方式动态设置，或者由远程配置中心推送设置\n- 规则初始化的时候，如果接入了远程配置中心，先读取远程规则，如果不存在，再读取本地规则文件\n- 多规则灰度获取规则的时候，先获取动态规则，如果不存在，再获取本地规则\n- 规则可以持久化到远程配置中心，一旦微服务死掉后，再次启动，仍旧可以拿到灰度规则，所以动态改变规则策略属于永久灰度发布手段\n\n### 动态改变版本策略\n微服务启动的时候，由于版本已经写死在application.properties里，使用者希望改变一下版本，而不重启微服务，达到访问版本的路径改变 \n- 版本分为本地版本和动态版本\n- 本地版本是通过在application.properties里配置的，在微服务启动的时候读取\n- 动态版本是通过POST方式动态设置\n- 多版本灰度获取版本值的时候，先获取动态版本，如果不存在，再获取本地版本\n- 版本不会持久化到远程配置中心，一旦微服务死掉后，再次启动，拿到的还是本地版本，所以动态改变版本策略属于临时灰度发布手段\n\n### 黑/白名单的IP地址注册的过滤策略\n微服务启动的时候，禁止指定的IP地址注册到服务注册发现中心。支持黑/白名单，白名单表示只允许指定IP地址前缀注册，黑名单表示不允许指定IP地址前缀注册\n- 全局过滤，指注册到服务注册发现中心的所有微服务，只有IP地址包含在全局过滤字段的前缀中，都允许注册（对于白名单而言），或者不允许注册（对于黑名单而言）\n- 局部过滤，指专门针对某个微服务而言，那么真正的过滤条件是全局过滤+局部过滤结合在一起\n\n### 最大注册数的限制的过滤策略\n微服务启动的时候，一旦微服务集群下注册的实例数目已经达到上限（可配置），将禁止后续的微服务进行注册\n- 全局配置值，只下面配置所有的微服务集群，最多能注册多少个\n- 局部配置值，指专门针对某个微服务而言，那么该值如存在，全局配置值失效\n\n### 黑/白名单的IP地址发现的过滤策略\n微服务启动的时候，禁止指定的IP地址被服务发现。它使用的方式和“黑/白名单的IP地址注册的过滤”一致\n\n### 版本属性字段定义策略\n不同的服务注册发现组件对应的版本配置值\n```xml\n# Eureka config\neureka.instance.metadataMap.version=1.0\neureka.instance.metadataMap.group=xxx-service-group\n\n# 奇葩的Consul配置（参考https://springcloud.cc/spring-cloud-consul.html - 元数据和Consul标签）\n# Consul config（多个值用“,”分隔，例如version=1.0,value=abc）\nspring.cloud.consul.discovery.tags=version=1.0,group=xxx-service-group\n\n# Zookeeper config\nspring.cloud.zookeeper.discovery.metadata.version=1.0\nspring.cloud.zookeeper.discovery.metadata.group=xxx-service-group\n```\n\n### 功能开关策略\n```xml\n# Plugin config\n# 开启和关闭服务注册层面的控制。一旦关闭，服务注册的黑/白名单过滤功能将失效，最大注册数的限制过滤功能将失效。缺失则默认为true\nspring.application.register.control.enabled=true\n# 开启和关闭服务发现层面的控制。一旦关闭，服务多版本调用的控制功能将失效，动态屏蔽指定IP地址的服务实例被发现的功能将失效。缺失则默认为true\nspring.application.discovery.control.enabled=true\n# 开启和关闭通过Rest方式对规则配置的控制和推送。一旦关闭，只能通过远程配置中心来控制和推送。缺失则默认为true\nspring.application.config.rest.control.enabled=true\n# 本地规则文件的路径，支持两种方式：classpath:rule.xml - 规则文件放在resources目录下，便于打包进jar；file:rule.xml - 规则文件放在工程根目录下，放置在外部便于修改。缺失则默认为不装载本地规则\nspring.application.config.path=classpath:rule.xml\n# 为微服务归类的Key，一般通过group字段来归类，例如eureka.instance.metadataMap.group=xxx-group或者eureka.instance.metadataMap.application=xxx-application。缺失则默认为group\n# spring.application.group.key=group\n# spring.application.group.key=application\n```\n\n## 配置中心\n### 跟远程配置中心整合\n本系统默认跟Nacos集成，如何安装使用，请参考[https://github.com/alibaba/nacos](https://github.com/alibaba/nacos)。使用者也可以跟携程Apollo，百度DisConf等远程配置中心整合，实现规则读取和订阅\n- 拉取配置，参考discovery-plugin-config-center-extension-nacos工程\n- 推送配置，参考discovery-console-extension-nacos工程\n\n## 管理中心\n\u003e PORT端口号为server.port或者management.port都可以（management.port开放只支持3.x.x版本）\n### 配置接口\n### 版本接口\n### 路由接口\n参考Swagger界面，如下图\n\n![Alt text](https://github.com/Nepxion/Docs/blob/master/discovery-plugin-doc/Swagger1.jpg)\n\n## 独立控制台\n为UI提供相关接口，包括\n- 一系列批量功能\n- 跟Nacos集成，实现配置推送和清除\n\n\u003e PORT端口号为server.port或者management.port都可以（（注意：管理端口不支持F版）\n### 控制台接口\n参考Swagger界面，如下图\n\n![Alt text](https://github.com/Nepxion/Docs/blob/master/discovery-plugin-doc/Swagger2.jpg)\n\n## 扩展和自定义更多规则或者监听\n使用者可以继承如下类\n- AbstractRegisterListener，实现服务注册的扩展和监听，用法参考discovery-springcloud-example下MyRegisterListener\n- AbstractDiscoveryListener，实现服务发现的扩展和监听，用法参考discovery-springcloud-example下MyDiscoveryListener。注意，在Consul下，同时会触发service和management两个实例的事件，需要区别判断，如下图\n- AbstractLoadBalanceListener，实现负载均衡的扩展和监听，用法参考discovery-springcloud-example下MyLoadBalanceListener\n\n集成了健康检查的Consul控制台\n![Alt text](https://github.com/Nepxion/Docs/blob/master/discovery-plugin-doc/Consul.jpg)\n\n## 示例演示\n### 场景描述\n本例将模拟一个较为复杂的场景，如下图\n\n![Alt text](https://github.com/Nepxion/Docs/blob/master/discovery-plugin-doc/Version.jpg)\n\n- 系统部署情况：\n  - 网关Zuul集群部署了1个\n  - 微服务集群部署了3个，分别是A服务集群、B服务集群、C服务集群，分别对应的实例数为2、2、3\n- 微服务集群的调用关系为网关Zuul-\u003e服务A-\u003e服务B-\u003e服务C\n- 系统调用关系\n  - 网关Zuul的1.0版本只能调用服务A的1.0版本，网关Zuul的1.1版本只能调用服务A的1.1版本\n  - 服务A的1.0版本只能调用服务B的1.0版本，服务A的1.1版本只能调用服务B的1.1版本\n  - 服务B的1.0版本只能调用服务C的1.0和1.1版本，服务B的1.1版本只能调用服务C的1.2版本\n\n用规则来表述上述关系\n```xml\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003crule\u003e\n    \u003cdiscovery\u003e\n        \u003cversion\u003e\n            \u003c!-- 表示网关z的1.0，允许访问提供端服务a的1.0版本 --\u003e\n            \u003cservice consumer-service-name=\"discovery-springcloud-example-zuul\" provider-service-name=\"discovery-springcloud-example-a\" consumer-version-value=\"1.0\" provider-version-value=\"1.0\"/\u003e\n            \u003c!-- 表示网关z的1.1，允许访问提供端服务a的1.1版本 --\u003e\n            \u003cservice consumer-service-name=\"discovery-springcloud-example-zuul\" provider-service-name=\"discovery-springcloud-example-a\" consumer-version-value=\"1.1\" provider-version-value=\"1.1\"/\u003e\n            \u003c!-- 表示消费端服务a的1.0，允许访问提供端服务b的1.0版本 --\u003e\n            \u003cservice consumer-service-name=\"discovery-springcloud-example-a\" provider-service-name=\"discovery-springcloud-example-b\" consumer-version-value=\"1.0\" provider-version-value=\"1.0\"/\u003e\n            \u003c!-- 表示消费端服务a的1.1，允许访问提供端服务b的1.1版本 --\u003e\n            \u003cservice consumer-service-name=\"discovery-springcloud-example-a\" provider-service-name=\"discovery-springcloud-example-b\" consumer-version-value=\"1.1\" provider-version-value=\"1.1\"/\u003e\n            \u003c!-- 表示消费端服务b的1.0，允许访问提供端服务c的1.0和1.1版本 --\u003e\n            \u003cservice consumer-service-name=\"discovery-springcloud-example-b\" provider-service-name=\"discovery-springcloud-example-c\" consumer-version-value=\"1.0\" provider-version-value=\"1.0;1.1\"/\u003e\n            \u003c!-- 表示消费端服务b的1.1，允许访问提供端服务c的1.2版本 --\u003e\n            \u003cservice consumer-service-name=\"discovery-springcloud-example-b\" provider-service-name=\"discovery-springcloud-example-c\" consumer-version-value=\"1.1\" provider-version-value=\"1.2\"/\u003e\n        \u003c/version\u003e\n    \u003c/discovery\u003e\n\u003c/rule\u003e\n```\n\n上述微服务分别见discovery-springcloud-example字样的8个DiscoveryApplication，分别对应各自的application.properties。这8个应用，对应的版本和端口号如下表（Gateway指Spring Cloud Api Gateway，只支持F版）\n\n| 微服务 | 服务端口 | 管理端口 | 版本 |\n| --- | --- | --- | --- |\n| A1 | 1100 | 5100 | 1.0 |\n| A2 | 1101 | 5101 | 1.1 |\n| B1 | 1200 | 5200 | 1.0 |\n| B2 | 1201 | 5201 | 1.1 |\n| C1 | 1300 | 5300 | 1.0 |\n| C2 | 1301 | 5301 | 1.1 |\n| C3 | 1302 | 5302 | 1.2 |\n| Zuul | 1400 | 5400 | 1.0 |\n| Gateway | 1500 | 5500 | 1.0 |\n\n独立控制台见discovery-springcloud-example-console，对应的版本和端口号如下表\n\n| 服务端口 | 管理端口 |\n| --- | --- |\n| 2222 | 3333 |\n\n### 开始演示\n- 启动服务注册发现中心，默认是Eureka。可供选择的有Eureka，Zuul，Zookeeper。Eureka，请启动discovery-springcloud-example-eureka下的应用，后两者自行安装服务器\n- 根据上面选择的服务注册发现中心，对示例下的discovery-springcloud-example/pom.xml进行组件切换\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.nepxion\u003c/groupId\u003e\n    \u003cartifactId\u003ediscovery-plugin-starter-eureka\u003c/artifactId\u003e\n    \u003c!-- \u003cartifactId\u003ediscovery-plugin-starter-consul\u003c/artifactId\u003e --\u003e\n    \u003c!-- \u003cartifactId\u003ediscovery-plugin-starter-zookeeper\u003c/artifactId\u003e --\u003e\n    \u003cversion\u003e${discovery.plugin.version}\u003c/version\u003e\n\u003c/dependency\u003e\n```\n- 根据上面选择的服务注册发现中心，对控制台下的discovery-springcloud-example-console/pom.xml进行组件切换切换\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.springframework.cloud\u003c/groupId\u003e\n    \u003cartifactId\u003espring-cloud-starter-netflix-eureka-client\u003c/artifactId\u003e\n    \u003c!-- \u003cartifactId\u003espring-cloud-starter-consul-discovery\u003c/artifactId\u003e --\u003e\n    \u003c!-- \u003cartifactId\u003espring-cloud-starter-zookeeper-discovery\u003c/artifactId\u003e --\u003e\n\u003c/dependency\u003e\n```\n\n### 服务注册过滤的操作演示\n黑/白名单的IP地址注册的过滤\n- 在rule.xml把本地IP地址写入到相应地方\n- 启动DiscoveryApplicationA1.java\n- 抛出禁止注册的异常，即本地服务受限于黑名单的IP地址列表，不会注册到服务注册发现中心；白名单操作也是如此，不过逻辑刚好相反\n\n最大注册数的限制的过滤\n- 在rule.xml修改最大注册数为0\n- 启动DiscoveryApplicationA1.java\n- 抛出禁止注册的异常，即本地服务受限于最大注册数，不会注册到服务注册发现中心\n\n黑/白名单的IP地址发现的过滤\n- 在rule.xml把本地IP地址写入到相应地方\n- 启动DiscoveryApplicationA1.java和DiscoveryApplicationB1.java、DiscoveryApplicationB2.java\n- 你会发现A服务无法获取B服务的任何实例，即B服务受限于黑名单的IP地址列表，不会被A服务的发现；白名单操作也是如此，不过逻辑刚好相反\n\n### 服务发现和负载均衡控制的操作演示\n#### 基于图形化方式的多版本灰度访问控制\n- 请访问[http://www.iqiyi.com/w_19s07thtsh.html](http://www.iqiyi.com/w_19s07thtsh.html)，视频清晰度改成720P，然后最大化播放\n- 请访问[https://pan.baidu.com/s/1eq_N56VbgSCaTXYQ5aKqiA](https://pan.baidu.com/s/1eq_N56VbgSCaTXYQ5aKqiA)，获取更清晰的视频，注意一定要下载下来看，不要在线看，否则也不清晰\n\n#### 基于Rest方式的多版本灰度访问控制\n基于服务的操作过程和效果\n- 启动discovery-springcloud-example下7个DiscoveryApplication（除去Zuul），无先后顺序，等待全部启动完毕\n- 下面URL的端口号，可以是服务端口号，也可以是管理端口号（注意：管理端口不支持F版）\n- 通过版本切换，达到灰度访问控制，针对A服务\n  - 1.1 通过Postman或者浏览器，执行POST [http://localhost:1100/routes](http://localhost:1100/routes)，填入discovery-springcloud-example-b;discovery-springcloud-example-c，查看路由路径，如图1，可以看到符合预期的调用路径\n  - 1.2 通过Postman或者浏览器，执行POST [http://localhost:1100/version/update](http://localhost:1100/version/update)，填入1.1，动态把服务A的版本从1.0切换到1.1\n  - 1.3 通过Postman或者浏览器，再执行第一步操作，如图2，可以看到符合预期的调用路径，通过版本切换，灰度访问控制成功\n- 通过规则改变，达到灰度访问控制，针对B服务\n  - 2.1 通过Postman或者浏览器，执行POST [http://localhost:1200/config/update-sync](http://localhost:1200/config/update-sync)，发送新的规则XML（内容见下面）\n  - 2.2 通过Postman或者浏览器，执行POST [http://localhost:1201/config/update-sync](http://localhost:1201/config/update-sync)，发送新的规则XML（内容见下面）\n  - 2.3 上述操作也可以通过独立控制台，进行批量更新，见图5。操作的逻辑：B服务的所有版本都只能访问C服务3.0版本，而本例中C服务3.0版本是不存在的，意味着这么做B服务不能访问C服务\n  - 2.4 重复1.1步骤，发现调用路径只有A服务-\u003eB服务，如图3，通过规则改变，灰度访问控制成功\n- 负载均衡的灰度测试\n  - 3.1 通过Postman或者浏览器，执行POST [http://localhost:1100/invoke](http://localhost:1100/invoke)，这是example内置的访问路径示例（通过Feign实现）\n  - 3.2 重复“通过版本切换，达到灰度访问控制”或者“通过规则改变，达到灰度访问控制”操作，查看Ribbon负载均衡的灰度结果，如图4\n- 上述操作，都是单次操作，如需要批量操作，可通过“独立控制台”接口，它集成批量操作和推送到远程配置中心的功能，可以取代上面的某些调用方式\n- 其它更多操作，请参考“配置中心”、“管理中心”和“独立控制台”\n\n新XML规则\n```xml\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003crule\u003e\n    \u003cdiscovery\u003e\n        \u003cversion\u003e\n            \u003cservice consumer-service-name=\"discovery-springcloud-example-b\" provider-service-name=\"discovery-springcloud-example-c\" consumer-version-value=\"\" provider-version-value=\"3.0\"/\u003e\n        \u003c/version\u003e\n    \u003c/discovery\u003e\n\u003c/rule\u003e\n```\n\n图1\n\n![Alt text](https://github.com/Nepxion/Docs/blob/master/discovery-plugin-doc/Result1.jpg)\n\n图2\n\n![Alt text](https://github.com/Nepxion/Docs/blob/master/discovery-plugin-doc/Result2.jpg)\n\n图3\n\n![Alt text](https://github.com/Nepxion/Docs/blob/master/discovery-plugin-doc/Result3.jpg)\n\n图4\n\n![Alt text](https://github.com/Nepxion/Docs/blob/master/discovery-plugin-doc/Result4.jpg)\n\n图5\n\n![Alt text](https://github.com/Nepxion/Docs/blob/master/discovery-plugin-doc/Result5.jpg)\n\n基于网关的操作过程和效果\n- 在上面基础上，启动discovery-springcloud-example下DiscoveryApplicationZuul\n- 因为Zuul是一种特殊的微服务，所有操作过程跟上面完全一致\n\n图6\n\n![Alt text](https://github.com/Nepxion/Docs/blob/master/discovery-plugin-doc/Result6.jpg)\n\n图7\n\n![Alt text](https://github.com/Nepxion/Docs/blob/master/discovery-plugin-doc/Result7.jpg)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feratel%2Fdiscovery-redis","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feratel%2Fdiscovery-redis","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feratel%2Fdiscovery-redis/lists"}