close
The Wayback Machine - https://web.archive.org/web/20200816060810/https://github.com/Nepxion/Discovery
Skip to content

🐳 Nepxion Discovery is an enhancement for Spring Cloud Discovery with gray release, router, weight, limitation, circuit breaker, degrade, isolation, monitor, tracing 灰度发布、路由、权重、限流、熔断、降级、隔离、监控、追踪

master
Go to file
Code

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
Aug 19, 2018
Aug 14, 2020
Jul 6, 2020

README.md

Image

Discovery【探索】架构篇

Total lines License Maven Central Javadocs Build Status Codacy Badge

Image Discovery【探索】指南篇,务必先阅读,请�?��?

  • 对于入门级玩�?�,参考指南示例极�?�版获取,分支为simple。涉及到指南篇里的灰度发布和路由的基本功能
  • 对于熟练级玩�?�,参考指南示例精进版获取,分支为master。除上述《极�?�版》功能外,涉及到指南篇里的绝大多数高级功能
  • 对于骨灰级玩�?�,参考指南示例高级版获取,分支为premium。除上述《精进版》功能外,涉及到指南篇里的ActiveMQ、MongoDB、RabbitMQ、Redis、RocketMQ、MySQL等高级调用链和灰度调用链的整合

Image 如果本文档由于Github网速原因无法�?�整阅读,请�?��?

Image 如果本代码由于Github网速原因无法快速阅读,请�?��?

Discovery【探索】框架架构,基于Spring Cloud Discovery服务注册发现、Ribbon负载均衡、Feign和RestTemplate调用等组件全方位增强的企业级�?服务开源解决方案,更贴近企业级需求,更具有企业级的插件引入、开�?�即用特征

  • 支持阿里巴巴Nacos、Eureka、Consul和Zookeeper四个服务注册发现中心
  • 支持阿里巴巴Nacos、携程Apollo和Redis三个远程配�?中心
  • 支持阿里巴巴Sentinel和Hystrix两个熔断隔离限流降级中间件
  • 支持Uber Jaeger、Apache Skywalking等符合OpenTracing调用链中间件
  • 支持Java Agent解决异步跨线程ThreadLocal上下文传递
  • 支持Prometheus、Grafana和Spring Boot Admin监控中间件
  • 支持Spring Cloud Gateway、Zuul网关和�?服务三大模块的灰度发布和路由等一系列功能
  • 支持和兼�?�Spring Cloud Edgware版、Finchley版、Greenwich版和Hoxton版

其功能包括

  • 灰度发布。基于规则�?�阅的全链路灰度发布,包括切换发布(版本匹配发布、区域匹配发布)和平滑发布(版本权重发布、区域权重发布)
  • 灰度路由。基于Header传递的全链路灰度路由,包括切换路由(版本匹配路由、区域匹配路由、机器IP和端口匹配路由)和平滑路由(版本权重路由、区域权重路由)。可以在网关过滤器、前端界面、负载均衡策略类三个地方�?�现路由功能
  • 组合式灰度发布和路由,灰度发布和灰度路由的多种组合式规则和策略,前端灰度&网关灰度路由组合式策略
  • 服务监控。包括调用链监控(Tracing)、日志监控(Logging)、指标监控(Metrics),CNCF技术委员会通过OpenTelemetry规范整合基于Tracing的OpenTracing规范(�?�方推荐Jaeger做Backend)和基于Metrics的OpenSensus规范(�?�方推荐Prometheus做Backend)。框架支持OpenTracing、Uber Jaeger、Apache Skywalking
    • 调用链监控(Tracing)包括Header方式、调用链方式、日志方式等单个或者组合式的全链路灰度调用链,支持对Sentinel自动埋点。调用链方式不支持Edgware版(Spring Boot 1.x.x)
    • 指标监控(Metrics)包括Prometheus、Grafana、Spring Boot Admin
  • 服务隔离。基于组和黑/白名单的全链路服务隔离,包括注册准入隔离(基于黑/白名单,包括组和IP地址的准入、最大注册数限制的准入)、消费端隔离(基于组的负载均衡的隔离、基于黑/白名单的IP地址的隔离)和提供端隔离(基于组的Header传值策略的隔离)
  • 环境隔离和路由。基于服务�?�例的元数�?Metadata的env参数和全链路传递的环境Header值进行比对�?�现隔离,当从网关传递来的环境Header(n-d-env)值和提供端�?�例的元数�?Metadata环境配�?值相等才能调用。环境隔离下,调用端�?�例找不到符合条件的提供端�?�例,把流量路由到一个通用或者备份环境
  • 服务限流熔断降级权限。集成阿里巴巴Sentinel,有机整合灰度路由,扩展LimitApp的机制,通过动态的Http Header方式�?�现组合式防护机制,包括基于服务名、基于灰度组、基于灰度版本、基于灰度区域、基于机器地址和端口等防护机制,支持自�?�义任意的业务参数组合�?�现该功能。支持原生的流控规则、降级规则、授权规则、系统规则、热点参数流控规则
  • 数�?库灰度发布。基于多数�?源的数�?库灰度发布
  • 同城双活多机房切换。基于区域匹配发布或者路由的同城双活多机房切换
  • 灰度路由和发布的自动化测试。基于Spring Boot/Spring Cloud自动化测试,包括�?通调用测试、灰度调用测试和扩展调用测试(可扩展出阿里巴巴Sentinel、FF4j功能开关等自动化测试)
  • 支持自�?�义和编程�?�现扩展
    • 支持用户自�?�义和编程禁止注册、禁止被发现、禁止被负载均衡的策略
    • 支持用户自�?�义和编程灰度路由策略
    • 支持用户自�?�义和编程负载均衡策略类
    • 支持运维调度灰度发布和路由的元数�?
    • 支持参数化灰度发布
  • Docker�?�器化和Kubernetes平台的无缝支持部署

[Nacos] 阿里巴巴中间件部门开发的新一代集服务注册发现中心和配�?中心为一体的中间件。�?�是构建以“服务”为中心的现代应用架构 (例如�?服务范式、云原生范式) 的服务基础�?�施,支持几乎所有主流类型的“服务”的发现、配�?和�?�理,更敏捷和�?�易地构建、交付和�?�理�?服务平台

[Sentinel] 阿里巴巴中间件部门开发的新一代以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳�?�性的分布式系统的流量防卫兵。�?�承接了阿里巴巴近10年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统�?�量可以承受的范围)、消息削峰填谷、集群流量控制、�?�时熔断下游不可用应用等

[Spring Cloud Alibaba] 阿里巴巴中间件部门开发的Spring Cloud增强套件,致力于提供�?服务开发的一站式解决方案。此项�?包含开发分布式应用�?服务的必需组件,方便开发者通过Spring Cloud编程模型轻松使用这些组件来开发分布式应用服务。依托Spring Cloud Alibaba,只需要添加一些注解和少量配�?,就可以将Spring Cloud应用接入阿里�?服务解决方案,通过阿里中间件来迅速搭建分布式应用系统

[OpenTracing] OpenTracing已进入CNCF,正在为全球的分布式追踪系统提供统一的概念、规范、架构和数�?标准。�?�通过提供平台无关、厂商无关的API,使得开发人员能够方便的添加(或更换)追踪系统的�?�现。对于存在多样化的技术栈共存的调用链中,OpenTracing适配Java、C、Go和.Net等技术栈,�?�现全链路分布式追踪功能。迄今为止,Uber Jaeger、Twitter Zipkin和Apache Skywalking已经适配了OpenTracing规范

本框架成为阿里巴巴中间件Nacos和Spring Cloud Alibaba项�?的相关开源

NacosSpring Cloud Alibaba

现有的Spring Cloud�?服务很方便引入该中间件,代码零侵入。鉴于Spring Cloud�?�方对Eureka和Hystrix不再做新功能的迭代,推荐用Nacos和Sentinel,�?�们对Spring Cloud灰度发布和路由更具出色的兼�?�性和友好性

Image 鸣谢

  • 感谢阿里巴巴中间件Nacos和Sentinel团队,尤其是Nacos负责人@彦林、@于怀,Sentinel负责人@�?�何、@子衿,Spring Cloud Alibaba负责人@小马哥、@洛夜、@亦盏的技术支持
  • 感谢携程Apollo团队,尤其是@�?�顺,特意开发OpenApi包和技术支持
  • 感谢代码贡�?者,包括@zifeihan,@Ax1an,@WeihuaWang,@张顺,@Esun,@liumapp,@terranhu,@JikaiSun,@HaoHuang,@FanYang,@Ankeway,@liquanjin等
  • 感谢为本框架进行测试验证和�?题分析�?�位的同学,包括@张龙,@CongweiXu,@fan,@阿神,@慕紫,@郝俊仁,@Windon,@杨成,@李鹏,@任学会,@郭小伟等
  • 感谢为本框架提出�?�贵意见和建�??的同学
  • 感谢使用本框架的公司和企业。不�?�全统�?�,�?前社区开源项�?已经被如下公司使用或者调研:
Image Image Image Image Image
Image Image Image Image Image
Image Image Image Image Image
Image Image Image Image Image
Image Image Image Image Image
Image Image Image Image Image
Image Image Image Image Image
Image Image Image Image Image
Image Image Image Image Image
Image Image Image Image Image
Image Image Image Image Image
Image Image Image Image Image

为提供更好的专业级服务,请更多已经使用本框架的公司和企业联系我

Image 特性

一、兼�?�性强。支持如下版本:

框架版本 框架分支 框架状态 Spring Cloud版本 Spring Boot版本 Spring Cloud Alibaba版本
6.0.7 master Image Hoxton
Greenwich
Finchley
2.2.x.RELEASE
2.1.x.RELEASE
2.0.x.RELEASE
2.2.x.RELEASE
2.1.x.RELEASE
2.0.x.RELEASE
5.6.0 5.x.x Image Greenwich 2.1.x.RELEASE 2.1.x.RELEASE
4.15.0 4.x.x Image Finchley 2.0.x.RELEASE 2.0.x.RELEASE
3.16.7 3.x.x Image Edgware 1.5.x.RELEASE 1.5.x.RELEASE
2.0.x 2.x.x Image Dalston 1.x.x.RELEASE 1.5.x.RELEASE
1.0.x 1.x.x Image Camden 1.x.x.RELEASE 1.5.x.RELEASE

Image 表示维护中 | Image 表示不维护,但可用,强烈建�??升级 | Image 表示不维护,不可用,已废弃

Image 注意:

  • 6.x.x版本(同时适用于Finchley、Greenwich和Hoxton以及未来的更高版本),将继续维护
  • 5.x.x版本(适用于Greenwich)已废弃
  • 4.x.x版本(适用于Finchley)已废弃
  • 3.x.x版本(适用于Edgware)不维护,但可用,强烈建�??升级
  • 2.x.x版本(适用于Dalston)已废弃
  • 1.x.x版本(适用于Camden)已废弃

二、使用方便。只需如下步骤:

�?录

请联系我

�?信、公众号和文档

Alt textAlt textAlt text

相关链接

源码主页

源码主页

指南主页

指南主页

文档主页

文档主页

界面展示

图形化灰度发布桌面程序 Alt text Alt text 图形化灰度发布Web平台 Alt text 集成规则配�?的Apollo配�?中心 Alt text 集成规则配�?的Nacos配�?中心 Alt text Nacos服务注册发现中心 Alt text 集成Sentinel熔断隔离限流降级平台 Alt text Alt text 集成Opentracing + Uber Jaeger调用链平台 Alt text Alt text Alt text Alt text Alt text 集成Sentinel + 灰度全链路监控 Alt text 集成主流中间件 + 灰度全链路监控 代码请从指南示例高级版获取,分支为premium。运行出下图强大效果的前提,需要事先搭建Nacos、Jaeger、ActiveMQ、MongoDB、RabbitMQ、Redis、RocketMQ以及MySQL数�?库等环境 使用者如果不想搭建环境,想直接观看效果,可以直接把离线数�?导入到Jaeger界面(JSON File栏,拖进去即可),观看到下图效果 Alt text Alt text Alt text 集成Prometheus + Grafana监控平台 Alt text Alt text Spring Boot Admin监控平台 Alt text

现有痛点

现有的Spring Cloud�?服务架构的痛点

  • 如果你是运维负责人,是否会经常发现,你掌�?�的测试环境中的服务注册中心,被一些不负责的开发人员把他本地开发环境注册上来,造成测试人员测试失败。你希望可以把本地开发环境注册给屏蔽掉,不�?�注册
  • 如果你是运维负责人,生产环境的某个�?服务集群下的某个�?�例,暂时出了�?题,但又不希望�?�下线。你希望可以把该�?�例给屏蔽掉,暂时不�?��?�被调用
  • 如果你是业务负责人,鉴于业务服务的快速迭代性,�?服务集群下的�?�例发布不同的版本。你希望根�?版本�?�理策略进行路由,提供给下游�?服务区别调用,例如�?��?控制快速基于版本的不同而切换,例如在不同的版本之间进行流量调拨
  • 如果你是业务负责人,希望灰度发布功能可以基于业务场景特色�?�制,例如根�?用户手机号进行不同服务器的路由
  • 如果你是DBA负责人,希望灰度发布功能可以基于数�?库切换上
  • 如果你是测试负责人,希望对�?服务做A/B测试

应用场景

  • 黑/白名单的IP地址注册的过滤
    • 开发环境的本地�?服务(例如IP地址为172.16.0.8)不希望被注册到测试环境的服务注册发现中心,那么可以在配�?中心维护一个黑/白名单的IP地址过滤(支持全局和局部的过滤)的规则
    • 我们可以通过提供一份黑/白名单达到该效果
  • 最大注册数的限制的过滤
    • 当某个�?服务注册数�?已经达到上限(例如2000个),那么后面起来的�?服务,将再也不能注册上去
  • 黑/白名单的IP地址发现的过滤
    • 开发环境的本地�?服务(例如IP地址为172.16.0.8)已经注册到测试环境的服务注册发现中心,那么可以在配�?中心维护一个黑/白名单的IP地址过滤(支持全局和局部的过滤)的规则,该本地�?服务不会被其他测试环境的�?服务所调用
    • 我们可以通过推送一份黑/白名单达到该效果
  • 多版本匹配的灰度控制
    • A服务调用B服务,而B服务有两个�?�例(B1、B2),虽然三者相同的服务名,但功能上有�?异,需求是在某个时刻,A服务只能调用B1,禁止调用B2。在此场景下,我们在application.properties里为B1维护一个版本为1.0,为B2维护一个版本为1.1
    • 我们可以通过推送A服务调用某个版本的B服务对应关系的配�?,达到某种意义上的灰度控制,改变版本的时候,我们只需要再次推送即可
  • 多版本权重的灰度控制
    • 上述场景中,我们也可以通过配给不同版本的权重(流量比例),根�?需求,A�?��?B的流量在B1和B2进行调拨
  • 多区域匹配的灰度控制
    • 上述场景中,我们也可以通过配给不同区域的进行配对,根�?需求,A�?��?B的流量在B1和B2(B1和B2所属不同区域)进行调拨
  • 多区域权重的灰度控制
    • 上述场景中,我们也可以通过配给不同区域的权重(流量比例),根�?需求,A�?��?B的流量在B1和B2(B1和B2所属不同区域)进行调拨
  • 多数�?源的数�?库灰度控制
    • 我们事先为�?服务配�?多套数�?源,通过灰度发布�?�时切换数�?源
  • 动态改变�?服务版本
    • 在A/B测试中,通过动态改变版本,不重启�?服务,达到�?��?版本的路径改变
  • 路由策略的灰度控制
    • 在业务REST调用上,在Header上传入服务名和版本对应关系的Json字符串,后端若干个服务会把请求路由到指�?�版本的服务器上
    • 在业务REST调用上,在Header上传入区域(region)名,后端若干个服务会把请求路由到指�?�区域(region)名的服务器上
    • 在业务REST调用上,在Header上传入Token,根�?不同的Token查询到不同的用户,后端若干个服务会把请求路由到指�?�的服务器上
    • 在业务RPC调用上,根�?不同的业务参数,例如手机号或者身份证号,后端若干个服务会把请求路由到指�?�的服务器上

功能�?�介

  • 基于Spring Cloud的�?服务和Spring Cloud Gateway和Zuul网关�?�现下述功能,�?�具有几个特性
    • 具有极大的易用性:支持在任何环节(�?服务和两个网关),多种方式(REST和RPC)做灰度发布和路由;移除相关依赖包后,即恢复成原生的Spring Cloud体系;引入相关依赖包后,通过配�?文件打开或者开关,该功能将自然启动,也可以通过规则文件配�?来�?�成
    • 具有极小的限制性:原生的Spring Cloud体系只需开启服务注册发现和Ribbon负载均衡;程序入口只需加上@EnableDiscoveryClient注解;零额外代码量,除非业务需要使用非常复杂的功能,需要特色化�?�制
    • 具有极强的健�?性:当远程配�?中心全部挂了,可以通过Rest方式进行灰度发布;当远程规则配�?错误或者不规范,马上切换到本地规则来代替;当一个模块出现�?题,不影响其�?�模块的运行
  • �?�现服务注册层面的控制
    • 基于黑/白名单的IP地址过滤机制禁止对相应的�?服务进行注册
    • 基于最大注册数的限制�?服务注册。一旦�?服务集群下注册的�?�例数�?已经达到上限,将禁止后续的�?服务进行注册
  • �?�现服务发现层面的控制
    • 基于黑/白名单的IP地址过滤机制禁止对相应的�?服务被发现
    • 基于版本号配对,通过对消费端和提供端可�?��?版本对应关系的配�?,在服务发现和负载均衡层面,进行多版本�?��?控制
    • 基于版本权重配对,通过对消费端和提供端版本权重(流量)对应关系的配�?,在服务发现和负载均衡层面,进行多版本流量调拨�?��?控制
    • 基于区域权重配对,通过对消费端和提供端所属区域的权重(流量)对应关系的配�?,在服务发现和负载均衡层面,进行多区域流量调拨�?��?控制
  • �?�现用户业务层面的控制
    • 使用者可以通过�?�阅业务参数的变化,�?�现特色化的灰度发布,例如,多数�?源的数�?库切换的灰度发布
  • �?�现灰度发布
    • 通过版本的动态改变,�?�现切换灰度发布
    • 通过版本匹配规则的改变,�?�现切换灰度发布
    • 通过版本权重规则的改变,�?�现平滑灰度发布
    • 通过区域匹配规则的改变,�?�现切换灰度发布
    • 通过区域权重规则的改变,�?�现平滑灰度发布
  • �?�现通过XML或者Json进行上述规则的�?�义
  • �?�现通过事件总线机制(EventBus)的功能,�?�现发布/�?�阅功能
    • 对接远程配�?中心,集成Nacos和Redis,异步接受远程配�?中心主动推送规则信息,动态改变�?服务的规则
    • 异步接受Rest主动推送规则信息,动态改变�?服务的规则,支持同步和异步推送两种方式
    • 动态改变�?服务的版本,支持同步和异步推送两种方式
    • 在服务注册层面的控制中,一旦禁止注册的条件触发,主动推送异步事件,以便使用者�?�阅
  • �?�现通过Listener机制进行扩展
    • 使用者可以对服务注册发现核心事件进行监听
  • �?�现通过策略扩展,�?�现灰度控制
    • 使用者可以�?�现跟业务有关的路由策略,根�?业务参数的不同,负载均衡到不同的服务器
    • 使用者可以根�?内�?的版本路由策略+区域路由策略+IP和端口路由策略+自�?�义策略,随心所欲的达到需要的路由功能
  • �?�现支持wagger集成
  • �?�现支持Spring Boot Admin的集成
  • �?�现支持Sentinel熔断隔离限流降级的集成
  • �?�现支持未来扩展更多的服务注册中心
  • �?�现控制平台�?服务,支持对规则和版本集中�?�理、推送、更改和删除
  • �?�现基于控制平台�?服务的图形化的灰度发布功能

名词解释

  • E版和F版,即Spring Cloud的Edgware和Finchley的首字母,以此类推
  • 切换灰度发布(也叫刚性灰度发布)和平滑灰度发布(也叫柔性灰度发布),切换灰度发布即在灰度发布的时候,没有过渡过程,流量直接从旧版本切换到新版本;平滑灰度发布即在灰度发布的时候,有个过渡过程,可以根�?�?�际情况,先给新版本分配低额流量,给旧版本分配高额流量,对新版本进行监测,如果没有�?题,就继续把旧版的流量切换到新版本上
  • IP地址,即根�?�?服务上报的�?�所在机器的IP地址。本系统内部强制以IP地址上报,禁止HostName上报,杜绝Spring Cloud应用在Docker或者Kubernetes部署时候出现�?题
  • 规则�?�义和策略�?�义,规则�?�义即通过XML或者Json�?�义既有格式的规则;策略�?�义即通过Http Header的策略方式传递路由信息
  • 本地版本,即初始化读取本地配�?文件获取的版本,也可以是第一次读取远程配�?中心获取的版本。本地版本和初始版本是同一个概念
  • 动态版本,即灰度发布时的版本。动态版本和灰度版本是同一个概念
  • 本地规则,即初始化读取本地配�?文件获取的规则,也可以是第一次读取远程配�?中心获取的规则。本地规则和初始规则是同一个概念
  • 动态规则,即灰度发布时的规则。动态规则和灰度规则是同一个概念
  • 事件总线,即基于Google Guava的EventBus构建的组件。通过事件总线可以推送动态版本和动态规则的更新和删除
  • 远程配�?中心,即可以存储规则配�?XML格式的配�?中心,可以包括不限于Nacos,Redis,Apollo,DisConf,Spring Cloud Config
  • 配�?(Config)和规则(Rule),在本系统中属于同一个概念,例如更新配�?,即更新规则;例如远程配�?中心存储的配�?,即规则XML
  • 服务端口和�?�理端口,即服务端口指在配�?文件的server.port值,�?�理端口指management.port(E版)值或者management.server.port(F版或以上)值

架构工程

架构

服务治理架构图

Alt text

全局架构图

Alt text

模块结构图

Alt text

工程

工程名 描述
discovery-common 通用模块
discovery-common-apollo 封装Apollo通用操作逻辑
discovery-common-nacos 封装Nacos通用操作逻辑
discovery-common-redis 封装Redis通用操作逻辑
discovery-plugin-framework 核心框架
discovery-plugin-framework-eureka 核心框架服务注册发现的Eureka�?�现
discovery-plugin-framework-consul 核心框架服务注册发现的Consul�?�现
discovery-plugin-framework-zookeeper 核心框架服务注册发现的Zookeeper�?�现
discovery-plugin-framework-nacos 核心框架服务注册发现的Nacos�?�现
discovery-plugin-config-center 配�?中心
discovery-plugin-config-center-starter-apollo 配�?中心的Apollo Starter
discovery-plugin-config-center-starter-nacos 配�?中心的Nacos Starter
discovery-plugin-config-center-starter-redis 配�?中心的Redis Starter
discovery-plugin-admin-center �?�理中心
discovery-plugin-starter-eureka 核心框架的Eureka Starter
discovery-plugin-starter-consul 核心框架的Consul Starter
discovery-plugin-starter-zookeeper 核心框架的Zookeeper Starter
discovery-plugin-starter-nacos 核心框架的Nacos Starter
discovery-plugin-strategy 路由策略
discovery-plugin-strategy-sentinel 路由策略的Sentinel
discovery-plugin-strategy-sentinel-monitor 路由策略的Sentinel监控
discovery-plugin-strategy-sentinel-starter-local 路由策略的Sentinel Local Starter
discovery-plugin-strategy-sentinel-starter-apollo 路由策略的Sentinel Apollo Starter
discovery-plugin-strategy-sentinel-starter-nacos 路由策略的Sentinel Nacos Starter
discovery-plugin-strategy-sentinel-starter-opentracing 路由策略的Sentinel OpenTracing Starter
discovery-plugin-strategy-sentinel-starter-skywalking 路由策略的Sentinel Skywalking Starter
discovery-plugin-strategy-starter-service 路由策略的Service Starter
discovery-plugin-strategy-starter-service-sentinel 路由策略的Service Sentinel Starter
discovery-plugin-strategy-starter-zuul 路由策略的Zuul Starter
discovery-plugin-strategy-starter-gateway 路由策略的Spring Cloud Gateway Starter
discovery-plugin-strategy-starter-hystrix 路由策略下,Hystrix做线程模式的服务隔离必须引入的插件 Starter
discovery-plugin-strategy-starter-opentracing 路由策略的OpenTracing Starter
discovery-plugin-strategy-starter-skywalking 路由策略的Skywalking Starter
discovery-plugin-strategy-starter-agent 路由策略的异步跨线程Agent Starter
discovery-plugin-strategy-starter-agent-plugin 路由策略的异步跨线程Agent Plugin Starter
discovery-plugin-test-starter 自动化测试 Starter
discovery-console 控制平台,集成接口给UI
discovery-console-starter-apollo 控制平台的Apollo Starter
discovery-console-starter-nacos 控制平台的Nacos Starter
discovery-console-starter-redis 控制平台的Redis Starter
discovery-console-desktop 图形化灰度发布等桌面程序
discovery-springcloud-example-admin Spring Boot Admin服务台示例
discovery-springcloud-example-console 控制平台示例
discovery-springcloud-example-eureka Eureka服务器示例
discovery-springcloud-example-service 用于灰度发布的�?服务示例
discovery-springcloud-example-zuul 用于灰度发布的Zuul示例
discovery-springcloud-example-gateway 用于灰度发布的Spring Cloud Gateway示例

依赖兼�?�

依赖

下面标注[必须引入]是一�?�要引入的包,标注[选择引入]是可以选择一个引入,或者不引入

核心插件引入,支持�?服务端、网关Zuul端和网关Spring Cloud Gateway端,包括核心灰度发布功能,�?�理中心,配�?中心等

[必须引入] 四个服务注册发现的中间件的增强插件,请任选一个引入
<dependency>
    <groupId>com.nepxion</groupId>
    <artifactId>discovery-plugin-starter-eureka</artifactId>
    <artifactId>discovery-plugin-starter-consul</artifactId>
    <artifactId>discovery-plugin-starter-zookeeper</artifactId>
    <artifactId>discovery-plugin-starter-nacos</artifactId>
    <version>${discovery.version}</version>
</dependency>

[选择引入] 三个远程配�?中心的中间件的扩展插件,如需要,请任选一个引入,或者也可以引入您自己的扩展
<dependency>
    <groupId>com.nepxion</groupId>
    <artifactId>discovery-plugin-config-center-starter-apollo</artifactId>
    <artifactId>discovery-plugin-config-center-starter-nacos</artifactId>
    <artifactId>discovery-plugin-config-center-starter-redis</artifactId>
    <version>${discovery.version}</version>
</dependency>

策略功能引入,支持�?服务端、网关Zuul端和网关Spring Cloud Gateway端,包括内�?版本路由、区域路由、自�?�义和编程灰度路由

�?服务端引入
[选择引入] 路由策略,如需要,请引入
<dependency>
    <groupId>com.nepxion</groupId>
    <artifactId>discovery-plugin-strategy-starter-service</artifactId>
    <version>${discovery.version}</version>
</dependency>

网关Zuul端引入
[选择引入] 路由策略,如需要,请引入
<dependency>
    <groupId>com.nepxion</groupId>
    <artifactId>discovery-plugin-strategy-starter-zuul</artifactId>
    <version>${discovery.version}</version>
</dependency>

网关Spring Cloud Gateway端引入
[选择引入] 路由策略,如需要,请引入
<dependency>
    <groupId>com.nepxion</groupId>
    <artifactId>discovery-plugin-strategy-starter-gateway</artifactId>
    <version>${discovery.version}</version>
</dependency>

[选择引入] 路由策略时候,Hystrix线程池隔离模式下必须引入该插件。灰度路由Header和调用链Span在Hystrix线程池隔离模式(信号量模式不需要引入)下传递时,通过线程上下文切换会存在丢失Header的�?题,通过该插件解决,支持�?服务端、网关Zuul端和网关Spring Cloud Gateway端

<dependency>
    <groupId>com.nepxion</groupId>
    <artifactId>discovery-plugin-strategy-starter-hystrix</artifactId>
    <version>${discovery.version}</version>
</dependency>

控制平台引入

[选择引入] 三个远程配�?中心的中间件的扩展插件,如需要,请任选一个引入,或者也可以引入您自己的扩展
<dependency>
    <groupId>com.nepxion</groupId>
    <artifactId>discovery-console-starter-apollo</artifactId>
    <artifactId>discovery-console-starter-nacos</artifactId>
    <artifactId>discovery-console-starter-redis</artifactId>
    <version>${discovery.version}</version>
</dependency>

Image 注意:中间件的引入一�?�要在所有层面保持一致,绝不允�?�出现类似如下情况,这也是常识

  • 例如,网关用Eureka做服务注册发现,�?服务用Consul做服务注册发现
  • 例如,控制平台用Nacos做远程配�?中心,�?服务用Redis做远程配�?中心

如果只想要灰度路由策略功能,而不想要灰度发布功能

  • 灰度路由策略是可以不需要接入远程配�?中心的,所以建�??去除远程配�?中心包的引入
<dependency>
    <groupId>com.nepxion</groupId>
    <artifactId>discovery-plugin-config-center-starter-xxx</artifactId>
    <version>${discovery.version}</version>
</dependency>
  • 灰度路由策略是不会对服务注册发现等逻辑产生影响,所以建�??下面两项配�?改为false
# 开启和关闭服务注册层面的控制。一旦关闭,服务注册的黑/白名单过滤功能将失效,最大注册数的限制过滤功能将失效。缺失则默�?�为true
spring.application.register.control.enabled=false
# 开启和关闭服务发现层面的控制。一旦关闭,服务多版本调用的控制功能将失效,动态屏蔽指�?�IP地址的服务�?�例被发现的功能将失效。缺失则默�?�为true
spring.application.discovery.control.enabled=false

服务端Sentinel防护插件的引入

<dependency>
    <groupId>com.nepxion</groupId>
    <artifactId>discovery-plugin-strategy-starter-service-sentinel</artifactId>
    <version>${discovery.version}</version>
</dependency>

[选择引入] Sentinel数�?源,如需要,请任选一个引入,或者也可以引入您自己的扩展
<dependency>
    <groupId>com.nepxion</groupId>
    <artifactId>discovery-plugin-strategy-sentinel-starter-nacos</artifactId>
    <artifactId>discovery-plugin-strategy-sentinel-starter-apollo</artifactId>
    <artifactId>discovery-plugin-strategy-sentinel-starter-local</artifactId>
    <version>${discovery.version}</version>
</dependency>

调用链功能引入,包含三大调用链,支持�?服务端、网关Zuul端和网关Spring Cloud Gateway端

Image 注意:该模块支持F版或更高版本,且不能同时引入

�?服务端引入
<dependency>
    <groupId>com.nepxion</groupId>
    <artifactId>discovery-plugin-strategy-sentinel-starter-opentracing</artifactId>
    <artifactId>discovery-plugin-strategy-sentinel-starter-skywalking</artifactId>
    <version>${discovery.version}</version>
</dependency>

异步跨线程Agent的引入,灰度路由Header和调用链Span在Hystrix线程池隔离模式下或者线程、线程池、@Async注解等异步调用Feign或者RestTemplate时,通过线程上下文切换会存在丢失Header的�?题,通过该插件解决,支持�?服务端、网关Zuul端和网关Spring Cloud Gateway端

<dependency>
    <groupId>com.nepxion</groupId>
    <artifactId>discovery-plugin-strategy-starter-agent</artifactId>
    <version>${discovery.version}</version>
</dependency>

<dependency>
    <groupId>com.nepxion</groupId>
    <artifactId>discovery-plugin-strategy-starter-agent-plugin</artifactId>
    <version>${discovery.version}</version>
</dependency>

自动化测试插件的引入

<dependency>
    <groupId>com.nepxion</groupId>
    <artifactId>discovery-plugin-test-starter</artifactId>
    <version>${discovery.version}</version>
</dependency>

兼�?�

版本兼�?�情况

  • 3.x.x版本不支持Spring Cloud Gateway和调用链,其�?�版本都支持

中间件兼�?�情况

规则�?�义

规则是基于XML或者Json为配�?方式,存储于本地文件或者远程配�?中心,可以通过远程配�?中心�?改的方式达到规则动态化。其核心代码参考discovery-plugin-framework以及�?�的扩展、discovery-plugin-config-center以及�?�的扩展和discovery-plugin-admin-center等

规则示例

XML示例(Json示例见discovery-springcloud-example-service下的rule.json)

Image 注意:服务名大小写规则

  • 在配�?文件(application.properties、application.yaml等)里,�?�义服务名(spring.application.name)不区分大小写
  • 在规则文件(XML、Json)里,引用的服务名必须小写
  • 在Nacos、Apollo、Redis等远程配�?中心的Key,包含的服务名必须小写
<?xml version="1.0" encoding="UTF-8"?>
<rule>
    <!-- 如果不想开启相关功能,只需要把相关节点删除即可,例如不想要黑名单功能,把blacklist节点删除 -->
    <register>
        <!-- 服务注册的黑/白名单注册过滤,只在服务启动的时候生效。白名单表示只允�?�指�?�IP地址前缀注册,黑名单表示不允�?�指�?�IP地址前缀注册。每个服务只能同时开启要么白名单,要么黑名单 -->
        <!-- filter-type,可选值blacklist/whitelist,表示白名单或者黑名单 -->
        <!-- service-name,表示服务名 -->
        <!-- filter-value,表示黑/白名单的IP地址列表。IP地址一般用前缀来表示,如果多个用“;”分隔,不允�?�出现空格 -->
        <!-- 表示下面所有服务,不允�?�10.10和11.11为前缀的IP地址注册(全局过滤) -->
        <blacklist filter-value="10.10;11.11">
            <!-- 表示下面服务,不允�?�172.16和10.10和11.11为前缀的IP地址注册 -->
            <service service-name="discovery-springcloud-example-a" filter-value="172.16"/>
        </blacklist>

        <!-- <whitelist filter-value="">
            <service service-name="" filter-value=""/>
        </whitelist>  -->

        <!-- 服务注册的数�?限制注册过滤,只在服务启动的时候生效。当某个服务的�?�例注册达到指�?�数�?时候,更多的�?�例将无法注册 -->
        <!-- service-name,表示服务名 -->
        <!-- filter-value,表示最大�?�例注册数 -->
        <!-- 表示下面所有服务,最大�?�例注册数为10000(全局配�?) -->
        <count filter-value="10000">
            <!-- 表示下面服务,最大�?�例注册数为5000,全局配�?值10000将不起作用,以局部配�?值为准 -->
            <service service-name="discovery-springcloud-example-a" filter-value="5000"/>
        </count>
    </register>

    <discovery>
        <!-- 服务发现的黑/白名单发现过滤,使用方式跟“服务注册的黑/白名单过滤”一致 -->
        <!-- 表示下面所有服务,不允�?�10.10和11.11为前缀的IP地址被发现(全局过滤) -->
        <blacklist filter-value="10.10;11.11">
            <!-- 表示下面服务,不允�?�172.16和10.10和11.11为前缀的IP地址被发现 -->
            <service service-name="discovery-springcloud-example-b" filter-value="172.16"/>
        </blacklist>

        <!-- 服务发现的多版本灰度匹配控制 -->
        <!-- service-name,表示服务名 -->
        <!-- version-value,表示可供�?��?的版本,如果多个用“;”分隔,不允�?�出现空格 -->
        <!-- 版本策略介绍 -->
        <!-- 1. 标准配�?,举例如下 -->
        <!--    <service consumer-service-name="a" provider-service-name="b" consumer-version-value="1.0" provider-version-value="1.0;1.1"/> 表示消费端1.0版本,允�?��?��?提供端1.0和1.1版本 -->
        <!-- 2. 版本值不配�?,举例如下 -->
        <!--    <service consumer-service-name="a" provider-service-name="b" provider-version-value="1.0;1.1"/> 表示消费端任何版本,允�?��?��?提供端1.0和1.1版本 -->
        <!--    <service consumer-service-name="a" provider-service-name="b" consumer-version-value="1.0"/> 表示消费端1.0版本,允�?��?��?提供端任何版本 -->
        <!--    <service consumer-service-name="a" provider-service-name="b"/> 表示消费端任何版本,允�?��?��?提供端任何版本 -->
        <!-- 3. 版本值空字符串,举例如下 -->
        <!--    <service consumer-service-name="a" provider-service-name="b" consumer-version-value="" provider-version-value="1.0;1.1"/> 表示消费端任何版本,允�?��?��?提供端1.0和1.1版本 -->
        <!--    <service consumer-service-name="a" provider-service-name="b" consumer-version-value="1.0" provider-version-value=""/> 表示消费端1.0版本,允�?��?��?提供端任何版本 -->
        <!--    <service consumer-service-name="a" provider-service-name="b" consumer-version-value="" provider-version-value=""/> 表示消费端任何版本,允�?��?��?提供端任何版本 -->
        <!-- 4. 版本对应关系未�?�义,默�?�消费端任何版本,允�?��?��?提供端任何版本 -->
        <!-- 特�?�情况处理,在使用上需要极力避免该情况发生 -->
        <!-- 1. 消费端的application.properties未�?�义版本号,则该消费端可以�?��?提供端任何版本 -->
        <!-- 2. 提供端的application.properties未�?�义版本号,当消费端在xml里不做任何版本配�?,才可以�?��?该提供端 -->
        <version>
            <!-- 表示网关g的1.0,允�?��?��?提供端服务a的1.0版本 -->
            <service consumer-service-name="discovery-springcloud-example-gateway" provider-service-name="discovery-springcloud-example-a" consumer-version-value="1.0" provider-version-value="1.0"/>
            <!-- 表示网关g的1.1,允�?��?��?提供端服务a的1.1版本 -->
            <service consumer-service-name="discovery-springcloud-example-gateway" provider-service-name="discovery-springcloud-example-a" consumer-version-value="1.1" provider-version-value="1.1"/>
            <!-- 表示网关z的1.0,允�?��?��?提供端服务a的1.0版本 -->
            <service consumer-service-name="discovery-springcloud-example-zuul" provider-service-name="discovery-springcloud-example-a" consumer-version-value="1.0" provider-version-value="1.0"/>
            <!-- 表示网关z的1.1,允�?��?��?提供端服务a的1.1版本 -->
            <service consumer-service-name="discovery-springcloud-example-zuul" provider-service-name="discovery-springcloud-example-a" consumer-version-value="1.1" provider-version-value="1.1"/>
            <!-- 表示消费端服务a的1.0,允�?��?��?提供端服务b的1.0版本 -->
            <service consumer-service-name="discovery-springcloud-example-a" provider-service-name="discovery-springcloud-example-b" consumer-version-value="1.0" provider-version-value="1.0"/>
            <!-- 表示消费端服务a的1.1,允�?��?��?提供端服务b的1.1版本 -->
            <service consumer-service-name="discovery-springcloud-example-a" provider-service-name="discovery-springcloud-example-b" consumer-version-value="1.1" provider-version-value="1.1"/>
            <!-- 表示消费端服务b的1.0,允�?��?��?提供端服务c的1.0和1.1版本 -->
            <service 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"/>
            <!-- 表示消费端服务b的1.1,允�?��?��?提供端服务c的1.2版本 -->
            <service consumer-service-name="discovery-springcloud-example-b" provider-service-name="discovery-springcloud-example-c" consumer-version-value="1.1" provider-version-value="1.2"/>
        </version>

        <!-- 服务发现的多区域灰度匹配控制 -->
        <!-- service-name,表示服务名 -->
        <!-- region-value,表示可供�?��?的区域,如果多个用“;”分隔,不允�?�出现空格 -->
        <!-- 区域策略介绍 -->
        <!-- 1. 标准配�?,举例如下 -->
        <!--    <service consumer-service-name="a" provider-service-name="b" consumer-region-value="dev" provider-region-value="dev"/> 表示dev区域的消费端,允�?��?��?dev区域的提供端 -->
        <!-- 2. 区域值不配�?,举例如下 -->
        <!--    <service consumer-service-name="a" provider-service-name="b" provider-region-value="dev;qa"/> 表示任何区域的消费端,允�?��?��?dev区域和qa区域的提供端 -->
        <!--    <service consumer-service-name="a" provider-service-name="b" consumer-region-value="dev"/> 表示dev区域的消费端,允�?��?��?任何区域的提供端 -->
        <!--    <service consumer-service-name="a" provider-service-name="b"/> 表示任何区域的消费端,允�?��?��?任何区域的提供端 -->
        <!-- 3. 区域值空字符串,举例如下 -->
        <!--    <service consumer-service-name="a" provider-service-name="b" consumer-region-value="" provider-region-value="dev;qa"/> 表示任何区域的消费端,允�?��?��?dev区域和qa区域的提供端 -->
        <!--    <service consumer-service-name="a" provider-service-name="b" consumer-region-value="dev" provider-region-value=""/> 表示dev区域的消费端,允�?��?��?任何区域的提供端 -->
        <!--    <service consumer-service-name="a" provider-service-name="b" consumer-region-value="" provider-region-value=""/> 表示任何区域的消费端,允�?��?��?任何区域的提供端 -->
        <!-- 4. 区域对应关系未�?�义,默�?�表示任何区域的消费端,允�?��?��?任何区域的提供端 -->
        <!-- 特�?�情况处理,在使用上需要极力避免该情况发生 -->
        <!-- 1. 消费端的application.properties未�?�义区域值,则该消费端可以�?��?任何区域的提供端 -->
        <!-- 2. 提供端的application.properties未�?�义区域值,当消费端在xml里不做任何区域配�?,才可以�?��?该提供端 -->
        <region>
            <!-- 表示dev区域的消费端服务a,允�?��?��?dev区域的提供端服务b -->
            <service consumer-service-name="discovery-springcloud-example-a" provider-service-name="discovery-springcloud-example-b" consumer-region-value="dev" provider-region-value="dev"/>
            <!-- 表示qa区域的消费端服务a,允�?��?��?qa区域的提供端服务b -->
            <service consumer-service-name="discovery-springcloud-example-a" provider-service-name="discovery-springcloud-example-b" consumer-region-value="qa" provider-region-value="qa"/>
            <!-- 表示dev区域的消费端服务b,允�?��?��?dev区域的提供端服务c -->
            <service consumer-service-name="discovery-springcloud-example-b" provider-service-name="discovery-springcloud-example-c" consumer-region-value="dev" provider-region-value="dev"/>
            <!-- 表示qa区域的消费端服务b,允�?��?��?qa区域的提供端服务c -->
            <service consumer-service-name="discovery-springcloud-example-b" provider-service-name="discovery-springcloud-example-c" consumer-region-value="qa" provider-region-value="qa"/>
        </region>

        <!-- 服务发现的多版本或者多区域的灰度权重控制 -->
        <!-- service-name,表示服务名 -->
        <!-- weight-value,表示版本对应的权重值,格式为"版本/区域值=权重值",如果多个用“;”分隔,不允�?�出现空格 -->
        <!-- 版本权重策略介绍 -->
        <!-- 1. 标准配�?,举例如下 -->
        <!--    <service consumer-service-name="a" provider-service-name="b" provider-weight-value="1.0=90;1.1=10"/> 表示消费端�?��?提供端的时候,提供端的1.0版本提供90%的权重流量,1.1版本提供10%的权重流量 -->
        <!--    <service provider-service-name="b" provider-weight-value="1.0=90;1.1=10"/> 表示所有消费端�?��?提供端的时候,提供端的1.0版本提供90%的权重流量,1.1版本提供10%的权重流量 -->
        <!-- 2. 局部配�?,即指�?�consumer-service-name,专门为该消费端配�?权重。全局配�?,即不指�?�consumer-service-name,为所有消费端配�?相同情形的权重。当局部配�?和全局配�?同时存在的时候,以局部配�?优先 -->
        <!-- 3. 尽量为线上所有版本都赋予权重值 -->
        <!-- 全局版本权重策略介绍 -->
        <!-- 1. 标准配�?,举例如下 -->
        <!--    <version provider-weight-value="1.0=85;1.1=15"/> 表示版本为1.0的服务提供85%的权重流量,版本为1.1的服务提供15%的权重流量 -->
        <!-- 2. 全局版本权重可以切换整条调用链的权重配比 -->
        <!-- 3. 尽量为线上所有版本都赋予权重值   -->

        <!-- 区域权重策略介绍 -->
        <!-- 1. 标准配�?,举例如下 -->
        <!--    <service consumer-service-name="a" provider-service-name="b" provider-weight-value="dev=85;qa=15"/> 表示消费端�?��?提供端的时候,区域为dev的服务提供85%的权重流量,区域为qa的服务提供15%的权重流量 -->
        <!--    <service provider-service-name="b" provider-weight-value="dev=85;qa=15"/> 表示所有消费端�?��?提供端的时候,区域为dev的服务提供85%的权重流量,区域为qa的服务提供15%的权重流量 -->
        <!-- 2. 局部配�?,即指�?�consumer-service-name,专门为该消费端配�?权重。全局配�?,即不指�?�consumer-service-name,为所有消费端配�?相同情形的权重。当局部配�?和全局配�?同时存在的时候,以局部配�?优先 -->
        <!-- 3. 尽量为线上所有版本都赋予权重值 -->
        <!-- 全局区域权重策略介绍 -->
        <!-- 1. 标准配�?,举例如下 -->
        <!--    <region provider-weight-value="dev=85;qa=15"/> 表示区域为dev的服务提供85%的权重流量,区域为qa的服务提供15%的权重流量 -->
        <!-- 2. 全局区域权重可以切换整条调用链的权重配比 -->
        <!-- 3. 尽量为线上所有区域都赋予权重值 -->
        <weight>
            <!-- 权重流量配�?有如下六种方式,优先级分别是由高到底,即先从第一种方式取权重流量值,取不到则到第二种方式取值,以此类推,最后仍取不到则忽略。使用者按照�?�际情况,选择一种即可 -->
            <!-- 表示消费端服务b�?��?提供端服务c的时候,提供端服务c的1.0版本提供90%的权重流量,1.1版本提供10%的权重流量 -->
            <service consumer-service-name="discovery-springcloud-example-b" provider-service-name="discovery-springcloud-example-c" provider-weight-value="1.0=90;1.1=10" type="version"/>
            <!-- 表示所有消费端服务�?��?提供端服务c的时候,提供端服务c的1.0版本提供90%的权重流量,1.1版本提供10%的权重流量 -->
            <service provider-service-name="discovery-springcloud-example-c" provider-weight-value="1.0=90;1.1=10" type="version"/>
            <!-- 表示所有版本为1.0的服务提供90%的权重流量,版本为1.1的服务提供10%的权重流量 -->
            <version provider-weight-value="1.0=90;1.1=10"/>

            <!-- 表示消费端服务b�?��?提供端服务c的时候,提供端服务c的dev区域提供85%的权重流量,qa区域提供15%的权重流量 -->
            <service consumer-service-name="discovery-springcloud-example-b" provider-service-name="discovery-springcloud-example-c" provider-weight-value="dev=85;qa=15" type="region"/>
            <!-- 表示所有消费端服务�?��?提供端服务c的时候,提供端服务c的dev区域提供85%的权重流量,qa区域提供15%的权重流量 -->
            <service provider-service-name="discovery-springcloud-example-c" provider-weight-value="dev=85;qa=15" type="region"/>
            <!-- 表示所有区域为dev的服务提供85%的权重流量,区域为qa的服务提供15%的权重流量 -->
            <region provider-weight-value="dev=85;qa=15"/>
        </weight>
    </discovery>

    <!-- 基于Http Header传递的策略路由,全局缺省路由(第三优先级) -->
    <strategy>
        <!-- 版本路由 -->
        <version>{"discovery-springcloud-example-a":"1.0", "discovery-springcloud-example-b":"1.0", "discovery-springcloud-example-c":"1.0;1.2"}</version>
        <!-- <version>1.0</version> -->
        <!-- 区域路由 -->
        <region>{"discovery-springcloud-example-a":"qa;dev", "discovery-springcloud-example-b":"dev", "discovery-springcloud-example-c":"qa"}</region>
        <!-- <region>dev</region> -->
        <!-- IP和端口路由 -->
        <address>{"discovery-springcloud-example-a":"192.168.43.101:1100", "discovery-springcloud-example-b":"192.168.43.101:1201", "discovery-springcloud-example-c":"192.168.43.101:1300"}</address>
        <!-- 权重流量配�?有如下四种方式,优先级分别是由高到底,即先从第一种方式取权重流量值,取不到则到第二种方式取值,以此类推,最后仍取不到则忽略。使用者按照�?�际情况,选择一种即可 -->
        <!-- 版本权重路由 -->
        <version-weight>{"discovery-springcloud-example-a":"1.0=90;1.1=10", "discovery-springcloud-example-b":"1.0=90;1.1=10", "discovery-springcloud-example-c":"1.0=90;1.1=10"}</version-weight>
        <!-- <version-weight>1.0=90;1.1=10</version-weight> -->
        <!-- 区域权重路由 -->
        <region-weight>{"discovery-springcloud-example-a":"dev=85;qa=15", "discovery-springcloud-example-b":"dev=85;qa=15", "discovery-springcloud-example-c":"dev=85;qa=15"}</region-weight>
        <!-- <region-weight>dev=85;qa=15</region-weight> -->
    </strategy>

    <!-- 基于Http Header传递的�?�制化策略路由,支持蓝绿部署和灰度发布两种模式。如果都不命中,则执行上面的全局缺省路由 -->
    <strategy-customization>
        <!-- Spel表达式在XML中的转义符:-->
        <!-- 和符号 & 转义为 &amp; 必须转义 -->
        <!-- 小于号 < 转义为 &lt; 必须转义 -->
        <!-- 双引号 " 转义为 &quot; 必须转义 -->
        <!-- 大于号 > 转义为 &gt; -->
        <!-- 单引号 ' 转义为 &apos; -->

        <!-- 全链路蓝绿部署:条件命中的匹配方式(第一优先级),支持版本匹配、区域匹配、IP地址和端口匹配、版本权重匹配、区域权重匹配 -->
        <!-- Header节点不允�?�缺失 -->
        <conditions type="blue-green">
            <condition id="1" header="#H['a'] == '1' &amp;&amp; #H['b'] == '2'" version-id="a-1" region-id="b-1" address-id="c-1" version-weight-id="d-1" region-weight-id="e-1"/>
            <condition id="2" header="#H['c'] == '3'" version-id="a-2" region-id="b-2" address-id="c-2" version-weight-id="d-2" region-weight-id="e-2"/>
        </conditions>

        <!-- 全链路灰度发布:条件命中的随机权重(第二优先级),支持版本匹配、区域匹配、IP地址和端口匹配 -->
        <!-- Header节点允�?�缺失,当含Header和未含Header的配�?并存时,以未含Header的配�?为优先 -->
        <conditions type="gray">
            <condition id="1" header="#H['a'] == '1' &amp;&amp; #H['b'] == '2'" version-id="a-1=10;a-2=90" region-id="b-1=20;b-2=80" address-id="c-1=30;c-2=70"/>
            <condition id="2" header="#H['c'] == '3'" version-id="a-1=90;a-2=10" region-id="b-1=80;b-2=20" address-id="c-1=70;c-2=30"/>
            <condition id="3" version-id="a-1=5;a-2=95" region-id="b-1=5;b-2=95" address-id="c-1=5;c-2=95"/>
        </conditions>

        <routes>
            <route id="a-1" type="version">{"discovery-springcloud-example-a":"1.0", "discovery-springcloud-example-b":"1.0", "discovery-springcloud-example-c":"1.0;1.2"}</route>
            <route id="a-2" type="version">{"discovery-springcloud-example-a":"1.1", "discovery-springcloud-example-b":"1.1", "discovery-springcloud-example-c":"1.2"}</route>
            <route id="b-1" type="region">{"discovery-springcloud-example-a":"qa;dev", "discovery-springcloud-example-b":"dev", "discovery-springcloud-example-c":"qa"}</route>
            <route id="b-2" type="region">{"discovery-springcloud-example-a":"qa", "discovery-springcloud-example-b":"qa", "discovery-springcloud-example-c":"qa"}</route>
            <route id="c-1" type="address">{"discovery-springcloud-example-a":"192.168.43.101:1100", "discovery-springcloud-example-b":"192.168.43.101:1201", "discovery-springcloud-example-c":"192.168.43.101:1300"}</route>
            <route id="c-2" type="address">{"discovery-springcloud-example-a":"192.168.43.101:1101", "discovery-springcloud-example-b":"192.168.43.101:1201", "discovery-springcloud-example-c":"192.168.43.101:1301"}</route>
            <route id="d-1" type="version-weight">{"discovery-springcloud-example-a":"1.0=90;1.1=10", "discovery-springcloud-example-b":"1.0=90;1.1=10", "discovery-springcloud-example-c":"1.0=90;1.1=10"}</route>
            <route id="d-2" type="version-weight">{"discovery-springcloud-example-a":"1.0=10;1.1=90", "discovery-springcloud-example-b":"1.0=10;1.1=90", "discovery-springcloud-example-c":"1.0=10;1.1=90"}</route>
            <route id="e-1" type="region-weight">{"discovery-springcloud-example-a":"dev=85;qa=15", "discovery-springcloud-example-b":"dev=85;qa=15", "discovery-springcloud-example-c":"dev=85;qa=15"}</route>
            <route id="e-2" type="region-weight">{"discovery-springcloud-example-a":"dev=15;qa=85", "discovery-springcloud-example-b":"dev=15;qa=85", "discovery-springcloud-example-c":"dev=15;qa=85"}</route>
        </routes>

        <!-- 策略中配�?条件表达式中的Header来决策蓝绿和灰度,可以代替外部传入Header -->
        <headers>
            <header key="a" value="1"/>
        </headers>
    </strategy-customization>

    <!-- 参数控制,由远程推送参数的改变,�?�现一些特色化的灰度发布,例如,基于数�?库的灰度发布 -->
    <parameter>
        <!-- 服务a和c分别有两个库的配�?,分别是测试数�?库(database的value为qa)和生产数�?库(database的value为prod) -->
        <!-- 上线后,一开始数�?库指向测试数�?库,对应value为qa,然后灰度发布的时候,改对应value为prod,即�?�现数�?库的灰度发布 -->
        <service service-name="discovery-springcloud-example-a" key="database" value="qa"/>
        <service service-name="discovery-springcloud-example-c" key="database" value="prod"/>
    </parameter>
</rule>

黑/白名单的IP地址注册的过滤规则

�?服务启动的时候,禁止指�?�的IP地址注册到服务注册发现中心。支持黑/白名单,白名单表示只允�?�指�?�IP地址前缀注册,黑名单表示不允�?�指�?�IP地址前缀注册。规则如何使用,见示例说明

  • 全局过滤,指注册到服务注册发现中心的所有�?服务,只有IP地址包含在全局过滤字�?�的前缀中,都允�?�注册(对于白名单而言),或者不允�?�注册(对于黑名单而言)
  • 局部过滤,指专门针对某个�?服务而言,那么真正的过滤条件是全局过滤+局部过滤结合在一起

最大注册数的限制的过滤规则

�?服务启动的时候,一旦�?服务集群下注册的�?�例数�?已经达到上限(可配�?),将禁止后续的�?服务进行注册。规则如何使用,见示例说明

  • 全局配�?值,只下面配�?所有的�?服务集群,最多能注册多少个
  • 局部配�?值,指专门针对某个�?服务而言,那么该值如存在,全局配�?值失效

黑/白名单的IP地址发现的过滤规则

�?服务启动的时候,禁止指�?�的IP地址被服务发现。�?�使用的方式和“黑/白名单的IP地址注册的过滤规则”一致

版本匹配的灰度发布规则

1. 标准配�?,举例如下
   <service consumer-service-name="a" provider-service-name="b" consumer-version-value="1.0" provider-version-value="1.0;1.1"/> 表示消费端1.0版本,允�?��?��?提供端1.0和1.1版本
2. 版本值不配�?,举例如下
   <service consumer-service-name="a" provider-service-name="b" provider-version-value="1.0;1.1"/> 表示消费端任何版本,允�?��?��?提供端1.0和1.1版本
   <service consumer-service-name="a" provider-service-name="b" consumer-version-value="1.0"/> 表示消费端1.0版本,允�?��?��?提供端任何版本
   <service consumer-service-name="a" provider-service-name="b"/> 表示消费端任何版本,允�?��?��?提供端任何版本
3. 版本值空字符串,举例如下
   <service consumer-service-name="a" provider-service-name="b" consumer-version-value="" provider-version-value="1.0;1.1"/> 表示消费端任何版本,允�?��?��?提供端1.0和1.1版本
   <service consumer-service-name="a" provider-service-name="b" consumer-version-value="1.0" provider-version-value=""/> 表示消费端1.0版本,允�?��?��?提供端任何版本
   <service consumer-service-name="a" provider-service-name="b" consumer-version-value="" provider-version-value=""/> 表示消费端任何版本,允�?��?��?提供端任何版本
4. 版本对应关系未�?�义,默�?�消费端任何版本,允�?��?��?提供端任何版本

特�?�情况处理,在使用上需要极力避免该情况发生
1. 消费端的application.properties未�?�义版本号,则该消费端可以�?��?提供端任何版本
2. 提供端的application.properties未�?�义版本号,当消费端在xml里不做任何版本配�?,才可以�?��?该提供端

版本权重的灰度发布规则

1. 标准配�?,举例如下
   <service consumer-service-name="a" provider-service-name="b" provider-weight-value="1.0=90;1.1=10"/> 表示消费端�?��?提供端的时候,提供端的1.0版本提供90%的权重流量,1.1版本提供10%的权重流量
   <service provider-service-name="b" provider-weight-value="1.0=90;1.1=10"/> 表示所有消费端�?��?提供端的时候,提供端的1.0版本提供90%的权重流量,1.1版本提供10%的权重流量
2. 局部配�?,即指�?�consumer-service-name,专门为该消费端配�?权重。全局配�?,即不指�?�consumer-service-name,为所有消费端配�?相同情形的权重。当局部配�?和全局配�?同时存在的时候,以局部配�?优先
3. 尽量为线上所有版本都赋予权重值

全局版本权重的灰度发布规则

1. 标准配�?,举例如下
   <version provider-weight-value="1.0=85;1.1=15"/> 表示版本为1.0的服务提供85%的权重流量,版本为1.1的服务提供15%的权重流量
2. 全局版本权重可以切换整条调用链的权重配比
3. 尽量为线上所有版本都赋予权重值

区域匹配的灰度发布规则

1. 标准配�?,举例如下
   <service consumer-service-name="a" provider-service-name="b" consumer-region-value="dev" provider-region-value="dev"/> 表示dev区域的消费端,允�?��?��?dev区域的提供端
2. 区域值不配�?,举例如下
   <service consumer-service-name="a" provider-service-name="b" provider-region-value="dev;qa"/> 表示任何区域的消费端,允�?��?��?dev区域和qa区域的提供端
   <service consumer-service-name="a" provider-service-name="b" consumer-region-value="dev"/> 表示dev区域的消费端,允�?��?��?任何区域的提供端
   <service consumer-service-name="a" provider-service-name="b"/> 表示任何区域的消费端,允�?��?��?任何区域的提供端
3. 区域值空字符串,举例如下
   <service consumer-service-name="a" provider-service-name="b" consumer-region-value="" provider-region-value="dev;qa"/> 表示任何区域的消费端,允�?��?��?dev区域和qa区域的提供端
   <service consumer-service-name="a" provider-service-name="b" consumer-region-value="dev" provider-region-value=""/> 表示dev区域的消费端,允�?��?��?任何区域的提供端
   <service consumer-service-name="a" provider-service-name="b" consumer-region-value="" provider-region-value=""/> 表示任何区域的消费端,允�?��?��?任何区域的提供端
4. 区域对应关系未�?�义,默�?�表示任何区域的消费端,允�?��?��?任何区域的提供端

特�?�情况处理,在使用上需要极力避免该情况发生
1. 消费端的application.properties未�?�义区域值,则该消费端可以�?��?任何区域的提供端
2. 提供端的application.properties未�?�义区域值,当消费端在xml里不做任何区域配�?,才可以�?��?该提供端

区域权重的灰度发布规则

1. 标准配�?,举例如下
   <service consumer-service-name="a" provider-service-name="b" provider-weight-value="dev=85;qa=15"/> 表示消费端�?��?提供端的时候,区域为dev的服务提供85%的权重流量,区域为qa的服务提供15%的权重流量
   <service provider-service-name="b" provider-weight-value="dev=85;qa=15"/> 表示所有消费端�?��?提供端的时候,区域为dev的服务提供85%的权重流量,区域为qa的服务提供15%的权重流量
2. 局部配�?,即指�?�consumer-service-name,专门为该消费端配�?权重。全局配�?,即不指�?�consumer-service-name,为所有消费端配�?相同情形的权重。当局部配�?和全局配�?同时存在的时候,以局部配�?优先
3. 尽量为线上所有版本都赋予权重值

全局区域权重的灰度发布规则

1. 标准配�?,举例如下
   <region provider-weight-value="dev=85;qa=15"/> 表示区域为dev的服务提供85%的权重流量,区域为qa的服务提供15%的权重流量
2. 全局区域权重可以切换整条调用链的权重配比
3. 尽量为线上所有区域都赋予权重值

网关端全链路路由策略的灰度发布规则

1. 标准配�?,举例如下
    <strategy>
        <!-- 版本路由 -->
        <version>{"discovery-springcloud-example-a":"1.0", "discovery-springcloud-example-b":"1.0", "discovery-springcloud-example-c":"1.0;1.2"}</version>
        <!-- <version>1.0</version> -->
        <!-- 区域路由 -->
        <region>{"discovery-springcloud-example-a":"qa;dev", "discovery-springcloud-example-b":"dev", "discovery-springcloud-example-c":"qa"}</region>
        <!-- <region>dev</region> -->
        <!-- IP和端口路由 -->
        <address>{"discovery-springcloud-example-a":"192.168.43.101:1100", "discovery-springcloud-example-b":"192.168.43.101:1201", "discovery-springcloud-example-c":"192.168.43.101:1300"}</address>
        <!-- 权重流量配�?有如下四种方式,优先级分别是由高到底,即先从第一种方式取权重流量值,取不到则到第二种方式取值,以此类推,最后仍取不到则忽略。使用者按照�?�际情况,选择一种即可 -->
        <!-- 版本权重路由 -->
        <version-weight>{"discovery-springcloud-example-a":"1.0=90;1.1=10", "discovery-springcloud-example-b":"1.0=90;1.1=10", "discovery-springcloud-example-c":"1.0=90;1.1=10"}</version-weight>
        <!-- <version-weight>1.0=90;1.1=10</version-weight> -->
        <!-- 区域权重路由 -->
        <region-weight>{"discovery-springcloud-example-a":"dev=85;qa=15", "discovery-springcloud-example-b":"dev=85;qa=15", "discovery-springcloud-example-c":"dev=85;qa=15"}</region-weight>
        <!-- <region-weight>dev=85;qa=15</region-weight> -->
    </strategy>
2. 用法和基于Http Header头部传路由参数一致。前�?是通过前端或者网关传入,后者是配�?在配�?文件里。�?�两者全部启用的时候,以前端或者网关传入Header方式优先

Image 注意:

路由策略的入口有三个为例:

  • 从外界传入(例如:Postman),在Header上加入。例如:n-d-version={"discovery-springcloud-example-a":"1.0", "discovery-springcloud-example-b":"1.0", "discovery-springcloud-example-c":"1.0;1.2"}
  • 在网关Zuul或者Spring Cloud Gateway的Filter中指�?�Header
  • 网关端全链路路由策略的灰度发布规则,在配�?中心或者本地rule.xml配�?

其作用的优先级

  • 在服务中,Header方式>配�?中心或者本地rule.xml配�?
  • 在网关中,通过如下配�?,决�?�优先级
# 当外界传值Header的时候,网关也�?��?并传递同名的Header,需要决�?�哪个Header传递到后边的服务去。如果下面开关为true,以网关�?��?为优先,否则以外界传值为优先。缺失则默�?�为true
spring.application.strategy.gateway.header.priority=false

# 当外界传值Header的时候,网关也�?��?并传递同名的Header,需要决�?�哪个Header传递到后边的服务去。如果下面开关为true,以网关�?��?为优先,否则以外界传值为优先。缺失则默�?�为true
spring.application.strategy.zuul.header.priority=false

自�?�义的灰度发布规则

通过�?�阅业务参数的变化,�?�现参数化灰度发布,例如,多数�?源的数�?库切换的灰度发布

1. 标准配�?,举例如下
   <service service-name="discovery-springcloud-example-a" key="database" value="prod"/>
2. 上述示例,是基于多数�?源的数�?库切换的灰度发布
   服务a有两个库的配�?,分别是测试数�?库(database的value为qa)和生产数�?库(database的value为prod)
   上线后,一开始数�?库指向测试数�?库,对应value为qa,然后灰度发布的时候,改对应value为prod,即�?�现数�?库的灰度发布

动态改变规则

�?服务启动的时候,由于规则(例如:rule.xml)已经配�?在本地,使用者希望改变一下规则,而不重启�?服务,达到规则的改变

  • 规则分为本地规则和动态规则
  • 本地规则是通过在本地规则(例如:rule.xml)文件�?�义的,也可以从远程配�?中心获取,在�?服务启动的时候读取
  • 动态规则是通过POST方式动态�?��?,或者由远程配�?中心推送�?��?
  • 规则初始化的时候,如果接入了远程配�?中心,先读取远程规则,如果不存在,再读取本地规则文件
  • 多规则灰度获取规则的时候,先获取动态规则,如果不存在,再获取本地规则
  • 规则可以持久化到远程配�?中心,一旦�?服务死掉后,再次启动,仍旧可以拿到灰度规则,所以动态改变规则策略属于永久灰度发布手�?�
  • 规则推送到远程配�?中心可以分为局部推送和全局推送
    • 局部推送是基于Group+ServiceId来推送的,就是同一个Group下同一个ServiceId的服务集群独立拥有一个规则配�?,如果采用这种方式,需要在每个�?服务集群下做一次灰度发布。优点是独立封闭,本服务集群灰度发布失败不会影响到其�?�服务集群,缺点是相对繁琐
    • 全局推送是基于Group来推送的(接口参数中的ServiceId由Group来代替),就是同一个Group下所有服务集群共同拥有一个规则配�?,如果采用这种方式,只需要做一次灰度发布,所有服务集群都生效。优点是非常�?�便,缺点具有一�?�风险,因为这个规则配�?掌握着所有服务集群的命运。全局推送用于全链路灰度发布
    • 如果既执行了全局推送,又执行了局部推送,那么,当服务运行中,优先接受最后一次推送的规则;当服务重新启动的时候,优先读取局部推送的规则

动态改变版本

Image 注意:动态改变版本,只允�?�发生在调用链的起点,例如网关,如果没有网关,则取第一个服务,其�?�层级的服务不能使用该功能

�?服务启动的时候,由于版本已经写死在application.properties里,使用者希望改变一下版本,而不重启�?服务,达到�?��?版本的路径改变

  • 版本分为本地版本和动态版本
  • 本地版本是通过在application.properties里配�?的,在�?服务启动的时候读取
  • 动态版本是通过POST方式动态�?��?
  • 多版本灰度获取版本值的时候,先获取动态版本,如果不存在,再获取本地版本
  • 版本不会持久化到远程配�?中心,一旦�?服务死掉后,再次启动,拿到的还是本地版本,所以动态改变版本策略属于临时灰度发布手�?�

策略�?�义

策略是通过REST或者RPC调用传递Header或者参数,达到路由策略的�?的。使用者可以�?�现跟业务有关的路由策略,根�?业务参数的不同,负载均衡到不同的服务器,其核心代码参考discovery-plugin-strategy以及�?�的扩展

版本匹配的灰度路由策略

基于Feign/RestTemplate的REST调用的多版本灰度路由,在Header上传入服务名和版本对应关系的Json字符串,如下表示,如果REST请求要经过a,b,c三个服务,那么只有a服务的1.0版本,b服务的1.1版本,c服务的1.1或1.2版本,允�?�被调用到 Header的Key为"n-d-version",value为:

{"discovery-springcloud-example-a":"1.0", "discovery-springcloud-example-b":"1.1", "discovery-springcloud-example-c":"1.1;1.2"}

如果,链路调用中所有的服务都是指�?�某个版本(例如1.1),那么value的格式可以�?�化,不需要Json字符串,直接是

1.1

如果上述表达式还未满足需求,也可以采用通配符(具体详细用法,参考Spring AntPathMatcher)

"discovery-springcloud-example-c":"1.*;1.2.?" - 表示c服务的版本调用范围是1开头的所有版本,或者是1.2开头的所有版本(末尾必须是1个字符)
* - 表示调用范围为所有服务的所有版本
1.* - 表示调用范围为所有服务的1开头的所有版本

多版本灰度路由架构图 Alt text

区域匹配的灰度路由策略

基于Feign/RestTemplate的REST调用的多区域灰度路由,在Header上传入服务名和版本对应关系的Json字符串,如下表示,如果REST请求要经过a,b,c三个服务,那么只有dev区域的a服务,qa区域的b服务,dev和qa区域c服务,允�?�被调用到 Header的Key为"n-d-region",value为:

{"discovery-springcloud-example-a":"dev", "discovery-springcloud-example-b":"qa", "discovery-springcloud-example-c":"dev;qa"}

如果,链路调用中所有的服务都是指�?�某个区域(例如dev),那么value的格式可以�?�化,不需要Json字符串,直接是

dev

如果上述表达式还未满足需求,也可以采用通配符(具体详细用法,参考Spring AntPathMatcher)

"discovery-springcloud-example-c":"d*;q?" - 表示c服务的区域调用范围是d开头的所有区域,或者是q开头的所有区域(末尾必须是1个字符)
* - 表示调用范围为所有服务的所有区域
d* - 表示调用范围为所有服务的d开头的所有区域

多区域灰度路由架构图 Alt text

Image 注意:Spring Cloud内�?zone的策略,功能跟region策略很相似,但zone策略不能跟自�?�义路由组合使用,故提供了更友好的region策略

IP和端口匹配的灰度路由策略

基于Feign/RestTemplate的REST调用的多版本灰度路由,在Header上传入服务名和版本对应关系的Json字符串,如下表示,如果REST请求要经过a,b,c三个服务,那么只需要指�?�三个服务所给�?�的IP(或者IP和端口组合),允�?�被调用到 Header的Key为"n-d-address",value为:

{"discovery-springcloud-example-a":"192.168.43.101:1101", "discovery-springcloud-example-b":"192.168.43.101:1201", "discovery-springcloud-example-c":"192.168.43.101:1302"}

如果上述表达式还未满足需求,也可以采用通配符(具体详细用法,参考Spring AntPathMatcher)

"discovery-springcloud-example-c":"192.168.43.*;192.168.44.10?" - 表示c服务的地址调用范围是192.168.43开头的所有IP,或者是192.168.44.10开头的所有IP(末尾必须是1个字符)
* - 表示调用范围为所有服务的所有IP
192.168.43* - 表示调用范围为所有服务的192.168.43开头的所有IP

多IP和端口灰度路由架构图 Alt text

版本权重的灰度路由策略

基于Feign/RestTemplate的REST调用的多版本权重灰度路由,在Header上传入服务名和版本流量百分比对应关系的Json字符串,如下表示,如果REST请求要经过a,b,c三个服务的版本权重配比,那么只需要�?�们版本对于流量的百分比 Header的Key为"n-d-version-weight",value为:

{"discovery-springcloud-example-a":"1.0=90;1.1=10", "discovery-springcloud-example-b":"1.0=90;1.1=10", "discovery-springcloud-example-c":"1.0=90;1.1=10"}

如果三个服务权重比一致,那么value的格式可以�?�化,不需要Json字符串,直接是

1.0=90;1.1=10

区域权重的灰度路由策略

基于Feign/RestTemplate的REST调用的多区域灰度路由,在Header上传入区域流量百分比对应关系的字符串,如下表示,如果REST请求要经过两个区域,那么只需要�?�们区域对于流量的百分比 Header的Key为"n-d-region-weight",value为:

{"discovery-springcloud-example-a":"dev=85;qa=15", "discovery-springcloud-example-b":"dev=85;qa=15", "discovery-springcloud-example-c":"dev=85;qa=15"}

如果三个服务权重比一致,那么value的格式可以�?�化,不需要Json字符串,直接是

dev=85;qa=15

自�?�义的灰度路由策略

  • 服务端的灰度路由策略

基于服务端的灰度路由,�?�现DiscoveryEnabledStrategy,通过RequestContextHolder(获取来自网关的Header参数)和ServiceStrategyContext(获取来自RPC方式的方法参数)获取业务上下文参数,进行路由自�?�义

  • Zuul端的灰度路由策略

基于Zuul端的灰度路由,�?�现DiscoveryEnabledStrategy,通过Zuul自带的RequestContext(获取来自网关的Header参数)获取业务上下文参数,进行路由自�?�义

  • Gateway端的灰度路由策略

基于Spring Cloud Gateway端的灰度路由,�?�现DiscoveryEnabledStrategy,通过GatewayStrategyContext(获取来自网关的Header参数)获取业务上下文参数,进行路由自�?�义

规则和策略

规则和策略的区别

属性 规则 策略
方式 通过XML或者Json配�? 通过REST或者RPC调用传递Header或者参数
频率 灰度发布期间更新,频率低 每次调用时候传递,频率高
扩展性 内�?,有限扩展,继承三个AbstractXXXListener 内�?,�?�全扩展,�?�现DiscoveryEnabledStrategy
作用域 运行前,运行期 运行期
依赖性 依赖配�?中心或者本地配�?文件 依赖每次调用

灰度方式区别图

Alt text

规则和策略的关系

  • 规则和策略,可以混合在一起工作,也关闭一项,�?�另一项单独工作
  • 规则和策略,一起工作的时候,先执行规则过滤逻辑,再执行策略过滤逻辑
  • 规则和策略关闭
    • 规则关闭,spring.application.register.control.enabled=false和spring.application.discovery.control.enabled=false
    • 策略关闭,spring.application.strategy.control.enabled=false

服务隔离

内�?服务隔离

元数�?中的Group在一�?�意义上代表着系统ID或者系统逻辑分组,基于Group策略意味着只有同一个系统中的服务才能调用

  • 注册服务隔离,基于Group黑/白名单的策略,即当前的服务所在的Group,不在Group的黑名单或者在白名单里,才允�?�被注册。只需要在网关或者服务端,开启如下配�?即可:
# 启动和关闭注册的服务隔离(基于Group黑/白名单的策略)。缺失则默�?�为false
spring.application.strategy.register.isolation.enabled=true

黑/白名单通过如下方式配�?

spring.application.strategy.register.isolation.group.blacklist=
spring.application.strategy.register.isolation.group.whitelist=
  • 消费端服务隔离,基于Group是否相同的策略,即消费端拿到的提供端列表,两者的Group必须相同。只需要在网关或者服务端,开启如下配�?即可:
# 启动和关闭消费端的服务隔离(基于Group是否相同的策略)。缺失则默�?�为false
spring.application.strategy.consumer.isolation.enabled=true
  • 提供端服务隔离,基于Group是否相同的策略,即服务端被消费端调用,两者的Group必须相同,否则拒绝调用,异构系统可以通过Header方式传递n-d-service-group值进行匹配。只需要在服务端(不适用网关),开启如下配�?即可:
# 启动和关闭提供端的服务隔离(基于Group是否相同的策略)。缺失则默�?�为false
spring.application.strategy.provider.isolation.enabled=true

# 路由策略的时候,需要指�?�对业务RestController类的扫描路径。此项配�?作用于RPC方式的调用拦截和消费端的服务隔离两项工作
spring.application.strategy.scan.packages=com.nepxion.discovery.gray.service.feign

自�?�义服务隔离

使用者可以继承如下类

  • AbstractRegisterListener,�?�现自�?�义”禁止注册“,用法参考discovery-springcloud-example-service下MyRegisterListener
  • AbstractDiscoveryListener,�?�现自�?�义”禁止被发现“,用法参考discovery-springcloud-example-service下MyDiscoveryListener。注意,在Consul下,同时会触发service和management两个�?�例的事件,需要区别判断,见上图“集成了健康检查的Consul界面”
  • AbstractLoadBalanceListener,�?�现自�?�义”禁止被负载均衡“,用法参考discovery-springcloud-example-service下MyLoadBalanceListener

配�?文件

基础属性配�?

不同的服务注册发现组件对应的不同的配�?值(region配�?可选),请仔细阅读

# Eureka config for discovery
eureka.instance.metadataMap.group=xxx-service-group
eureka.instance.metadataMap.version=1.0
eureka.instance.metadataMap.region=dev
eureka.instance.metadataMap.env=env1

# Consul config for discovery
# 参考https://springcloud.cc/spring-cloud-consul.html - 元数�?和Consul标签
spring.cloud.consul.discovery.tags=group=xxx-service-group,version=1.0,region=dev,env=env1

# Zookeeper config for discovery
spring.cloud.zookeeper.discovery.metadata.group=xxx-service-group
spring.cloud.zookeeper.discovery.metadata.version=1.0
spring.cloud.zookeeper.discovery.metadata.region=dev
spring.cloud.zookeeper.discovery.metadata.env=env1

# Nacos config for discovery
spring.cloud.nacos.discovery.metadata.group=example-service-group
spring.cloud.nacos.discovery.metadata.version=1.0
spring.cloud.nacos.discovery.metadata.region=dev
spring.cloud.nacos.discovery.metadata.env=env1

# Management config
# E版配�?方式
# 关闭�?��?Rest接口时候的权限验证
management.security.enabled=false
management.port=5100

# F版或以上配�?方式
management.server.port=5100

功能开关配�?

服务端配�?

# Plugin core config
# 开启和关闭服务注册层面的控制。一旦关闭,服务注册的黑/白名单过滤功能将失效,最大注册数的限制过滤功能将失效。缺失则默�?�为true
spring.application.register.control.enabled=true
# 开启和关闭服务发现层面的控制。一旦关闭,服务多版本调用的控制功能将失效,动态屏蔽指�?�IP地址的服务�?�例被发现的功能将失效。缺失则默�?�为true
spring.application.discovery.control.enabled=true
# 开启和关闭通过Rest方式对规则配�?的控制和推送。一旦关闭,只能通过远程配�?中心来控制和推送。缺失则默�?�为true
spring.application.config.rest.control.enabled=true
# 规则文件的格式,支持xml和json。缺失则默�?�为xml
spring.application.config.format=xml
# spring.application.config.format=json
# 本地规则文件的路径,支持两种方式:classpath:rule.xml(rule.json) - 规则文件放在resources�?录下,便于打包进jar;file:rule.xml(rule.json) - 规则文件放在工程根�?录下,放�?在外部便于�?改。缺失则默�?�为不装载本地规则
spring.application.config.path=classpath:rule.xml
# spring.application.config.path=classpath:rule.json
# 为�?服务归类的Key,一般通过group字�?�来归类,例如eureka.instance.metadataMap.group=xxx-group或者eureka.instance.metadataMap.application=xxx-application。缺失则默�?�为group
spring.application.group.key=group
# spring.application.group.key=application
# 业务系统希望大多数时候Spring、SpringBoot或者SpringCloud的基本配�?、调优参数(非业务系统配�?参数),不配�?在业务端,集成到基础框架里。但特�?�情况下,业务系统有时候也希望能把基础框架里配�?的参数给覆盖掉,用他们自己的配�?
# 对于此类型的配�?需求,可以配�?在下面的配�?文件里。该文件一般放在resource�?录下。缺失则默�?�为spring-application-default.properties
spring.application.default.properties.path=spring-application-default.properties
# 负载均衡下,消费端尝试获取对应提供端初始服务�?�例列表为空的时候,进行重试。缺失则默�?�为false
spring.application.no.servers.retry.enabled=false
# 负载均衡下,消费端尝试获取对应提供端初始服务�?�例列表为空的时候,进行重试的次数。缺失则默�?�为5
spring.application.no.servers.retry.times=5
# 负载均衡下,消费端尝试获取对应提供端初始服务�?�例列表为空的时候,进行重试的时间间隔。缺失则默�?�为2000
spring.application.no.servers.retry.await.time=2000
# 负载均衡下,消费端尝试获取对应提供端服务�?�例列表为空的时候,通过日志方式通知。缺失则默�?�为false
spring.application.no.servers.notify.enabled=false

# Plugin strategy config
# 开启和关闭路由策略的控制。一旦关闭,路由策略功能将失效。缺失则默�?�为true
spring.application.strategy.control.enabled=true
# 开启和关闭Ribbon默�?�的ZoneAvoidanceRule负载均衡策略。一旦关闭,则使用RoundRobin�?�单�?询负载均衡策略。缺失则默�?�为true
spring.application.strategy.zone.avoidance.rule.enabled=true
# 启动和关闭路由策略的时候,对REST方式的调用拦截。缺失则默�?�为true
spring.application.strategy.rest.intercept.enabled=true
# 启动和关闭路由策略的时候,对REST方式在异步调用场景下在服务端的Request请求的装饰,当主线程先于子线程执行�?�的时候,Request会被Destory,导致Header仍旧拿不到,开启装饰,就可以�?保拿到。缺失则默�?�为false
spring.application.strategy.rest.request.decorator.enabled=true
# 启动和关闭Header传递的Debug日志打印,注意:每调用一次都会打印一次,会对性能有所影响,建�??压测环境和生产环境关闭。缺失则默�?�为false
spring.application.strategy.rest.intercept.debug.enabled=true
# 路由策略的时候,对REST方式调用拦截的时候(支持Feign或者RestTemplate调用),希望把来自外部自�?�义的Header参数(用于框架内�?上下文Header,例如:trace-id, span-id等)传递到服务里,那么配�?如下值。如果多个用“;”分隔,不允�?�出现空格
spring.application.strategy.context.request.headers=trace-id;span-id
# 路由策略的时候,对REST方式调用拦截的时候(支持Feign或者RestTemplate调用),希望把来自外部自�?�义的Header参数(用于业务系统子�?�义Header,例如:mobile)传递到服务里,那么配�?如下值。如果多个用“;”分隔,不允�?�出现空格
spring.application.strategy.business.request.headers=token
# 启动和关闭路由策略的时候,对RPC方式的调用拦截。缺失则默�?�为false
spring.application.strategy.rpc.intercept.enabled=true
# 路由策略的时候,需要指�?�对业务RestController类的扫描路径。此项配�?作用于RPC方式的调用拦截、消费端的服务隔离和调用链三项功能
spring.application.strategy.scan.packages=com.nepxion.discovery.plugin.example.service.feign
# 启动和关闭注册的服务隔离(基于Group黑/白名单的策略)。缺失则默�?�为false
spring.application.strategy.register.isolation.enabled=true
# 启动和关闭消费端的服务隔离(基于Group是否相同的策略)。缺失则默�?�为false
spring.application.strategy.consumer.isolation.enabled=true
# 启动和关闭提供端的服务隔离(基于Group是否相同的策略)。缺失则默�?�为false
spring.application.strategy.provider.isolation.enabled=true

# 启动和关闭监控,一旦关闭,调用链和日志输出都将关闭。缺失则默�?�为false
spring.application.strategy.monitor.enabled=true
# 启动和关闭日志输出。缺失则默�?�为false
spring.application.strategy.logger.enabled=true
# 日志输出中,是否显示MDC前面的Key。缺失则默�?�为true
spring.application.strategy.logger.mdc.key.shown=true
# 启动和关闭Debug日志打印,注意:每调用一次都会打印一次,会对性能有所影响,建�??压测环境和生产环境关闭。缺失则默�?�为false
spring.application.strategy.logger.debug.enabled=true
# 启动和关闭调用链输出。缺失则默�?�为false
spring.application.strategy.tracer.enabled=true
# 启动和关闭调用链的灰度信息以独立的Span节点输出,如果关闭,则灰度信息输出到原生的Span节点中(Skywalking不支持原生模式)。缺失则默�?�为true
spring.application.strategy.tracer.separate.span.enabled=true
# 启动和关闭调用链的灰度规则策略信息输出。缺失则默�?�为true
spring.application.strategy.tracer.rule.output.enabled=true
# 启动和关闭调用链的异常信息是否以详细格式输出。缺失则默�?�为false
spring.application.strategy.tracer.exception.detail.output.enabled=true
# 启动和关闭类方法上入参和出参输出到调用链。缺失则默�?�为false
spring.application.strategy.tracer.method.context.output.enabled=true
# 显示在调用链界面上灰度Span的名称,建�??改成具有公司特色的框架产品名称。缺失则默�?�为NEPXION
spring.application.strategy.tracer.span.value=NEPXION
# 显示在调用链界面上灰度Span Tag的插件名称,建�??改成具有公司特色的框架产品的描述。缺失则默�?�为Nepxion Discovery
spring.application.strategy.tracer.span.tag.plugin.value=Nepxion Discovery
# 启动和关闭Sentinel调用链上规则在Span上的输出,注意:原生的Sentinel不是Spring技术栈,下面参数必须通过-D方式或者System.setProperty方式等�?��?进去。缺失则默�?�为true
spring.application.strategy.tracer.sentinel.rule.output.enabled=true
# 启动和关闭Sentinel调用链上方法入参在Span上的输出,注意:原生的Sentinel不是Spring技术栈,下面参数必须通过-D方式或者System.setProperty方式等�?��?进去。缺失则默�?�为false
spring.application.strategy.tracer.sentinel.args.output.enabled=true

# 开启服务端�?�现Hystrix线程隔离模式做服务隔离时,必须把spring.application.strategy.hystrix.threadlocal.supported�?��?为true,同时要引入discovery-plugin-strategy-starter-hystrix包,否则线程切换时会发生ThreadLocal上下文对象丢失。缺失则默�?�为false
spring.application.strategy.hystrix.threadlocal.supported=true

# 启动和关闭Sentinel限流降级熔断权限等原生功能的数�?来源扩展和调用链埋点输出。缺失则默�?�为false
spring.application.strategy.sentinel.enabled=true
# 流控规则文件路径。缺失则默�?�为classpath:sentinel-flow.json
spring.application.strategy.sentinel.flow.path=classpath:sentinel-flow.json
# 降级规则文件路径。缺失则默�?�为classpath:sentinel-degrade.json
spring.application.strategy.sentinel.degrade.path=classpath:sentinel-degrade.json
# 授权规则文件路径。缺失则默�?�为classpath:sentinel-authority.json
spring.application.strategy.sentinel.authority.path=classpath:sentinel-authority.json
# 系统规则文件路径。缺失则默�?�为classpath:sentinel-system.json
spring.application.strategy.sentinel.system.path=classpath:sentinel-system.json
# 热点参数流控规则文件路径。缺失则默�?�为classpath:sentinel-param-flow.json
spring.application.strategy.sentinel.param.flow.path=classpath:sentinel-param-flow.json
# 服务端执行规则时候,以Http请求中的Header值作为关�?Key。缺失则默�?�为n-d-service-id,即以服务名作为关�?Key
spring.application.strategy.service.sentinel.request.origin.key=n-d-service-id
# 启动和关闭Sentinel LimitApp限流等功能。缺失则默�?�为false
spring.application.strategy.service.sentinel.limit.app.enabled=true

# 防止多个网关上并行�?�施灰度路由产生混乱,对处于非灰度状态的服务,调用�?�的时候,只取�?�的老的稳�?�版本的�?�例;灰度状态的服务,还是根�?传递的Header版本号进行匹配
# 启动和关闭调用对端服务,是否执行调用�?�的时候只取�?�的老的稳�?�版本的�?�例的策略。缺失则默�?�为false
spring.application.strategy.version.filter.enabled=true

# 流量路由到指�?�的环境下。不允�?�为保留值default,缺失则默�?�为common
spring.application.environment.route=common

# 开启和关闭使用服务名前缀来作为服务组名。缺失则默�?�为false
spring.application.group.generator.enabled=true
# 服务名前缀的截断长度,必须大于0
spring.application.group.generator.length=15
# 服务名前缀的截断标志。当截断长度配�?了,则取截断长度方式,否则取截断标志方式
spring.application.group.generator.character=-

# 开启和关闭使用Git信息中的字�?�单个或者多个组合来作为服务版本号。缺失则默�?�为false
spring.application.git.generator.enabled=true
# 插件git-commit-id-plugin产生git信息文件的输出路径,支持properties和json两种格式,支持classpath:xxx和file:xxx两种路径,这些需要和插件里的配�?保持一致。缺失则默�?�为classpath:git.properties
spring.application.git.generator.path=classpath:git.properties
# spring.application.git.generator.path=classpath:git.json
# 使用Git信息中的字�?�单个或者多个组合来作为服务版本号。缺失则默�?�为{git.commit.time}-{git.total.commit.count}
spring.application.git.version.key={git.commit.id.abbrev}-{git.commit.time}
# spring.application.git.version.key={git.build.version}-{git.commit.time}

Spring Cloud Gateway端配�?

# Plugin core config
# 开启和关闭服务注册层面的控制。一旦关闭,服务注册的黑/白名单过滤功能将失效,最大注册数的限制过滤功能将失效。缺失则默�?�为true
spring.application.register.control.enabled=true
# 开启和关闭服务发现层面的控制。一旦关闭,服务多版本调用的控制功能将失效,动态屏蔽指�?�IP地址的服务�?�例被发现的功能将失效。缺失则默�?�为true
spring.application.discovery.control.enabled=true
# 开启和关闭通过Rest方式对规则配�?的控制和推送。一旦关闭,只能通过远程配�?中心来控制和推送。缺失则默�?�为true
spring.application.config.rest.control.enabled=true
# 规则文件的格式,支持xml和json。缺失则默�?�为xml
spring.application.config.format=xml
# spring.application.config.format=json
# 本地规则文件的路径,支持两种方式:classpath:rule.xml(rule.json) - 规则文件放在resources�?录下,便于打包进jar;file:rule.xml(rule.json) - 规则文件放在工程根�?录下,放�?在外部便于�?改。缺失则默�?�为不装载本地规则
spring.application.config.path=classpath:rule.xml
# spring.application.config.path=classpath:rule.json
# 为�?服务归类的Key,一般通过group字�?�来归类,例如eureka.instance.metadataMap.group=xxx-group或者eureka.instance.metadataMap.application=xxx-application。缺失则默�?�为group
spring.application.group.key=group
# spring.application.group.key=application
# 业务系统希望大多数时候Spring、SpringBoot或者SpringCloud的基本配�?、调优参数(非业务系统配�?参数),不配�?在业务端,集成到基础框架里。但特�?�情况下,业务系统有时候也希望能把基础框架里配�?的参数给覆盖掉,用他们自己的配�?
# 对于此类型的配�?需求,可以配�?在下面的配�?文件里。该文件一般放在resource�?录下。缺失则默�?�为spring-application-default.properties
spring.application.default.properties.path=spring-application-default.properties
# 负载均衡下,消费端尝试获取对应提供端初始服务�?�例列表为空的时候,进行重试。缺失则默�?�为false
spring.application.no.servers.retry.enabled=false
# 负载均衡下,消费端尝试获取对应提供端初始服务�?�例列表为空的时候,进行重试的次数。缺失则默�?�为5
spring.application.no.servers.retry.times=5
# 负载均衡下,消费端尝试获取对应提供端初始服务�?�例列表为空的时候,进行重试的时间间隔。缺失则默�?�为2000
spring.application.no.servers.retry.await.time=2000
# 负载均衡下,消费端尝试获取对应提供端服务�?�例列表为空的时候,通过日志方式通知。缺失则默�?�为false
spring.application.no.servers.notify.enabled=false

# Plugin strategy config
# 开启和关闭路由策略的控制。一旦关闭,路由策略功能将失效。缺失则默�?�为true
spring.application.strategy.control.enabled=true
# 开启和关闭Ribbon默�?�的ZoneAvoidanceRule负载均衡策略。一旦关闭,则使用RoundRobin�?�单�?询负载均衡策略。缺失则默�?�为true
spring.application.strategy.zone.avoidance.rule.enabled=true
# 路由策略过滤器的执行顺序(Order)。缺失则默�?�为9000
spring.application.strategy.gateway.route.filter.order=9000
# 当外界传值Header的时候,网关也�?��?并传递同名的Header,需要决�?�哪个Header传递到后边的服务去。如果下面开关为true,以网关�?��?为优先,否则以外界传值为优先。缺失则默�?�为true
spring.application.strategy.gateway.header.priority=false
# 当以网关�?��?为优先的时候,网关未配�?Header,而外界配�?了Header,仍旧忽略外界的Header。缺失则默�?�为true
spring.application.strategy.gateway.original.header.ignored=true
# 启动和关闭注册的服务隔离(基于Group黑/白名单的策略)。缺失则默�?�为false
spring.application.strategy.register.isolation.enabled=true
# 启动和关闭消费端的服务隔离(基于Group是否相同的策略)。缺失则默�?�为false
spring.application.strategy.consumer.isolation.enabled=true

# 启动和关闭监控,一旦关闭,调用链和日志输出都将关闭。缺失则默�?�为false
spring.application.strategy.monitor.enabled=true
# 启动和关闭日志输出。缺失则默�?�为false
spring.application.strategy.logger.enabled=true
# 日志输出中,是否显示MDC前面的Key。缺失则默�?�为true
spring.application.strategy.logger.mdc.key.shown=true
# 启动和关闭Debug日志打印,注意:每调用一次都会打印一次,会对性能有所影响,建�??压测环境和生产环境关闭。缺失则默�?�为false
spring.application.strategy.logger.debug.enabled=true
# 启动和关闭调用链输出。缺失则默�?�为false
spring.application.strategy.tracer.enabled=true
# 启动和关闭调用链的灰度信息以独立的Span节点输出,如果关闭,则灰度信息输出到原生的Span节点中(Skywalking不支持原生模式)。缺失则默�?�为true
spring.application.strategy.tracer.separate.span.enabled=true
# 启动和关闭调用链的灰度规则策略信息输出。缺失则默�?�为true
spring.application.strategy.tracer.rule.output.enabled=true
# 启动和关闭调用链的异常信息是否以详细格式输出。缺失则默�?�为false
spring.application.strategy.tracer.exception.detail.output.enabled=true
# 显示在调用链界面上灰度Span的名称,建�??改成具有公司特色的框架产品名称。缺失则默�?�为NEPXION
spring.application.strategy.tracer.span.value=NEPXION
# 显示在调用链界面上灰度Span Tag的插件名称,建�??改成具有公司特色的框架产品的描述。缺失则默�?�为Nepxion Discovery
spring.application.strategy.tracer.span.tag.plugin.value=Nepxion Discovery
# 启动和关闭Sentinel调用链上规则在Span上的输出,注意:原生的Sentinel不是Spring技术栈,下面参数必须通过-D方式或者System.setProperty方式等�?��?进去。缺失则默�?�为true
spring.application.strategy.tracer.sentinel.rule.output.enabled=true
# 启动和关闭Sentinel调用链上方法入参在Span上的输出,注意:原生的Sentinel不是Spring技术栈,下面参数必须通过-D方式或者System.setProperty方式等�?��?进去。缺失则默�?�为false
spring.application.strategy.tracer.sentinel.args.output.enabled=true

# 开启Spring Cloud Gateway网关上�?�现Hystrix线程隔离模式做服务隔离时,必须把spring.application.strategy.hystrix.threadlocal.supported�?��?为true,同时要引入discovery-plugin-strategy-starter-hystrix包,否则线程切换时会发生ThreadLocal上下文对象丢失。缺失则默�?�为false
spring.application.strategy.hystrix.threadlocal.supported=true

# 防止多个网关上并行�?�施灰度路由产生混乱,对处于非灰度状态的服务,调用�?�的时候,只取�?�的老的稳�?�版本的�?�例;灰度状态的服务,还是根�?传递的Header版本号进行匹配
# 启动和关闭调用对端服务,是否执行调用�?�的时候只取�?�的老的稳�?�版本的�?�例的策略。缺失则默�?�为false
spring.application.strategy.version.filter.enabled=true

# 流量路由到指�?�的环境下。不允�?�为保留值default,缺失则默�?�为common
spring.application.environment.route=common

# 开启和关闭使用服务名前缀来作为服务组名。缺失则默�?�为false
spring.application.group.generator.enabled=true
# 服务名前缀的截断长度,必须大于0
spring.application.group.generator.length=15
# 服务名前缀的截断标志。当截断长度配�?了,则取截断长度方式,否则取截断标志方式
spring.application.group.generator.character=-

# 开启和关闭使用Git信息中的字�?�单个或者多个组合来作为服务版本号。缺失则默�?�为false
spring.application.git.generator.enabled=true
# 插件git-commit-id-plugin产生git信息文件的输出路径,支持properties和json两种格式,支持classpath:xxx和file:xxx两种路径,这些需要和插件里的配�?保持一致。缺失则默�?�为classpath:git.properties
spring.application.git.generator.path=classpath:git.properties
# spring.application.git.generator.path=classpath:git.json
# 使用Git信息中的字�?�单个或者多个组合来作为服务版本号。缺失则默�?�为{git.commit.time}-{git.total.commit.count}
spring.application.git.version.key={git.commit.id.abbrev}-{git.commit.time}
# spring.application.git.version.key={git.build.version}-{git.commit.time}

Zuul端配�?

# Plugin core config
# 开启和关闭服务注册层面的控制。一旦关闭,服务注册的黑/白名单过滤功能将失效,最大注册数的限制过滤功能将失效。缺失则默�?�为true
spring.application.register.control.enabled=true
# 开启和关闭服务发现层面的控制。一旦关闭,服务多版本调用的控制功能将失效,动态屏蔽指�?�IP地址的服务�?�例被发现的功能将失效。缺失则默�?�为true
spring.application.discovery.control.enabled=true
# 开启和关闭通过Rest方式对规则配�?的控制和推送。一旦关闭,只能通过远程配�?中心来控制和推送。缺失则默�?�为true
spring.application.config.rest.control.enabled=true
# 规则文件的格式,支持xml和json。缺失则默�?�为xml
spring.application.config.format=xml
# spring.application.config.format=json
# 本地规则文件的路径,支持两种方式:classpath:rule.xml(rule.json) - 规则文件放在resources�?录下,便于打包进jar;file:rule.xml(rule.json) - 规则文件放在工程根�?录下,放�?在外部便于�?改。缺失则默�?�为不装载本地规则
spring.application.config.path=classpath:rule.xml
# spring.application.config.path=classpath:rule.json
# 为�?服务归类的Key,一般通过group字�?�来归类,例如eureka.instance.metadataMap.group=xxx-group或者eureka.instance.metadataMap.application=xxx-application。缺失则默�?�为group
spring.application.group.key=group
# spring.application.group.key=application
# 业务系统希望大多数时候Spring、SpringBoot或者SpringCloud的基本配�?、调优参数(非业务系统配�?参数),不配�?在业务端,集成到基础框架里。但特�?�情况下,业务系统有时候也希望能把基础框架里配�?的参数给覆盖掉,用他们自己的配�?
# 对于此类型的配�?需求,可以配�?在下面的配�?文件里。该文件一般放在resource�?录下。缺失则默�?�为spring-application-default.properties
spring.application.default.properties.path=spring-application-default.properties
# 负载均衡下,消费端尝试获取对应提供端初始服务�?�例列表为空的时候,进行重试。缺失则默�?�为false
spring.application.no.servers.retry.enabled=false
# 负载均衡下,消费端尝试获取对应提供端初始服务�?�例列表为空的时候,进行重试的次数。缺失则默�?�为5
spring.application.no.servers.retry.times=5
# 负载均衡下,消费端尝试获取对应提供端初始服务�?�例列表为空的时候,进行重试的时间间隔。缺失则默�?�为2000
spring.application.no.servers.retry.await.time=2000
# 负载均衡下,消费端尝试获取对应提供端服务�?�例列表为空的时候,通过日志方式通知。缺失则默�?�为false
spring.application.no.servers.notify.enabled=false

# Plugin strategy config
# 开启和关闭路由策略的控制。一旦关闭,路由策略功能将失效。缺失则默�?�为true
spring.application.strategy.control.enabled=true
# 开启和关闭Ribbon默�?�的ZoneAvoidanceRule负载均衡策略。一旦关闭,则使用RoundRobin�?�单�?询负载均衡策略。缺失则默�?�为true
spring.application.strategy.zone.avoidance.rule.enabled=true
# 路由策略过滤器的执行顺序(Order)。缺失则默�?�为0
spring.application.strategy.zuul.route.filter.order=0
# 当外界传值Header的时候,网关也�?��?并传递同名的Header,需要决�?�哪个Header传递到后边的服务去。如果下面开关为true,以网关�?��?为优先,否则以外界传值为优先。缺失则默�?�为true
spring.application.strategy.zuul.header.priority=false
# 当以网关�?��?为优先的时候,网关未配�?Header,而外界配�?了Header,仍旧忽略外界的Header。缺失则默�?�为true
spring.application.strategy.zuul.original.header.ignored=true
# 启动和关闭注册的服务隔离(基于Group黑/白名单的策略)。缺失则默�?�为false
spring.application.strategy.register.isolation.enabled=true
# 启动和关闭消费端的服务隔离(基于Group是否相同的策略)。缺失则默�?�为false
spring.application.strategy.consumer.isolation.enabled=true

# 启动和关闭监控,一旦关闭,调用链和日志输出都将关闭。缺失则默�?�为false
spring.application.strategy.monitor.enabled=true
# 启动和关闭日志输出。缺失则默�?�为false
spring.application.strategy.logger.enabled=true
# 日志输出中,是否显示MDC前面的Key。缺失则默�?�为true
spring.application.strategy.logger.mdc.key.shown=true
# 启动和关闭Debug日志打印,注意:每调用一次都会打印一次,会对性能有所影响,建�??压测环境和生产环境关闭。缺失则默�?�为false
spring.application.strategy.logger.debug.enabled=true
# 启动和关闭调用链输出。缺失则默�?�为false
spring.application.strategy.tracer.enabled=true
# 启动和关闭调用链的灰度信息以独立的Span节点输出,如果关闭,则灰度信息输出到原生的Span节点中(Skywalking不支持原生模式)。缺失则默�?�为true
spring.application.strategy.tracer.separate.span.enabled=true
# 启动和关闭调用链的灰度规则策略信息输出。缺失则默�?�为true
spring.application.strategy.tracer.rule.output.enabled=true
# 启动和关闭调用链的异常信息是否以详细格式输出。缺失则默�?�为false
spring.application.strategy.tracer.exception.detail.output.enabled=true
# 显示在调用链界面上灰度Span的名称,建�??改成具有公司特色的框架产品名称。缺失则默�?�为NEPXION
spring.application.strategy.tracer.span.value=NEPXION
# 显示在调用链界面上灰度Span Tag的插件名称,建�??改成具有公司特色的框架产品的描述。缺失则默�?�为Nepxion Discovery
spring.application.strategy.tracer.span.tag.plugin.value=Nepxion Discovery
# 启动和关闭Sentinel调用链上规则在Span上的输出,注意:原生的Sentinel不是Spring技术栈,下面参数必须通过-D方式或者System.setProperty方式等�?��?进去。缺失则默�?�为true
spring.application.strategy.tracer.sentinel.rule.output.enabled=true
# 启动和关闭Sentinel调用链上方法入参在Span上的输出,注意:原生的Sentinel不是Spring技术栈,下面参数必须通过-D方式或者System.setProperty方式等�?��?进去。缺失则默�?�为false
spring.application.strategy.tracer.sentinel.args.output.enabled=true

# 开启Zuul网关上�?�现Hystrix线程隔离模式做服务隔离时,必须把spring.application.strategy.hystrix.threadlocal.supported�?��?为true,同时要引入discovery-plugin-strategy-starter-hystrix包,否则线程切换时会发生ThreadLocal上下文对象丢失。缺失则默�?�为false
spring.application.strategy.hystrix.threadlocal.supported=true

# 防止多个网关上并行�?�施灰度路由产生混乱,对处于非灰度状态的服务,调用�?�的时候,只取�?�的老的稳�?�版本的�?�例;灰度状态的服务,还是根�?传递的Header版本号进行匹配
# 启动和关闭调用对端服务,是否执行调用�?�的时候只取�?�的老的稳�?�版本的�?�例的策略。缺失则默�?�为false
spring.application.strategy.version.filter.enabled=true

# 流量路由到指�?�的环境下。不允�?�为保留值default,缺失则默�?�为common
spring.application.environment.route=common

# 开启和关闭使用服务名前缀来作为服务组名。缺失则默�?�为false
spring.application.group.generator.enabled=true
# 服务名前缀的截断长度,必须大于0
spring.application.group.generator.length=15
# 服务名前缀的截断标志。当截断长度配�?了,则取截断长度方式,否则取截断标志方式
spring.application.group.generator.character=-

# 开启和关闭使用Git信息中的字�?�单个或者多个组合来作为服务版本号。缺失则默�?�为false
spring.application.git.generator.enabled=true
# 插件git-commit-id-plugin产生git信息文件的输出路径,支持properties和json两种格式,支持classpath:xxx和file:xxx两种路径,这些需要和插件里的配�?保持一致。缺失则默�?�为classpath:git.properties
spring.application.git.generator.path=classpath:git.properties
# spring.application.git.generator.path=classpath:git.json
# 使用Git信息中的字�?�单个或者多个组合来作为服务版本号。缺失则默�?�为{git.commit.time}-{git.total.commit.count}
spring.application.git.version.key={git.commit.id.abbrev}-{git.commit.time}
# spring.application.git.version.key={git.build.version}-{git.commit.time}

外部元数�?配�?

外部系统(例如:运维发布平台)在远程启动�?服务的时候,可以通过参数传递来动态改变元数�?或者增加运维特色的参数,最后注册到远程配�?中心。有如下两种方式:

  • 通过Program arguments来传递,�?�的用法是前面加“--”。支持Eureka、Zookeeper和Nacos的增量覆盖,Consul由于使用了全量覆盖的tag方式,不适用改变单个元数�?的方式。例如:--spring.cloud.nacos.discovery.metadata.version=1.0
  • 通过VM arguments来传递,�?�的用法是前面加“-D”。支持上述所有的注册组件,�?�的限制是变量前面必须要加“metadata.”,推荐使用该方式。例如:-Dmetadata.version=1.0
  • 两种方式尽量避免同时用

配�?中心

  • 默�?�集成
  • 扩展集成
    • 使用者也可以跟更多远程配�?中心集成
    • 参考三个跟Apollo、Nacos和Redis有关的工程

�?�理中心

PORT端口号为服务端口或者�?�理端口都可以

  • 配�?接口
  • 版本接口
  • 路由接口 参考Swagger界面,如下图

Alt text

控制平台

为UI提供相关接口,包括

  • 一系列批量功能
  • 跟Nacos、Apollo和Redis集成,�?�现配�?拉取、推送和清除

PORT端口号为服务端口或者�?�理端口都可以

  • 控制平台接口 参考Swagger界面,如下图

Alt text

监控平台

Spring Boot Admin监控平台

参考https://github.com/codecentric/spring-boot-admin

熔断隔离限流降级平台

基于Alibaba Sentinel的熔断隔离限流降级平台

参考https://github.com/alibaba/Sentinel

界面工具

基于Apollo界面的灰度发布

Alt text

  • 参考Apollo�?�方文档https://github.com/ctripcorp/apollo相关文档,搭建Apollo环境,以及熟悉相关的基本操作
  • 根�?上图,做如下步骤操作
    • �?��?页面中AppId和配�?文件里面app.id一致
    • �?��?页面中Namespace和配�?文件里面apollo.plugin.namespace一致,如果配�?文件里不�?��?,那么页面默�?�采用内�?的“application”
    • 在页面中添加配�?
      • 局部配�?方式:一个服务集群(eureka.instance.metadataMap.group和spring.application.name都相同的服务)对应一个配�?文件,通过group+serviceId方式添加,Key为“group-serviceId”,Value为Xml或者Json格式的规则内�?�。group取值于配�?文件里的eureka.instance.metadataMap.group配�?项,serviceId取值于spring.application.name配�?项�?
      • 全局配�?方式:一组服务集群(eureka.instance.metadataMap.group相同,但spring.application.name可以不相同的服务)对应一个配�?文件,通过group方式添加,Key为“group-group”,Value为Xml或者Json格式的规则内�?�。group取值于配�?文件里的eureka.instance.metadataMap.group配�?项
      • 强烈建�??局部配�?方式和全局配�?方式不要混用,否则连使用者自己都无法搞清楚到底是哪种配�?方式在起作用
    • 其他更多参数,例如evn, cluster等,请自行参考Apollo�?�方文档,保持一致
  • 特别注意
    • 局部配�?方式建�??使用Apollo的私有(private)配�?方式,全局配�?方式必须采用Apollo的共享(public)配�?方式
    • 如果业务配�?和灰度配�?在同一个namespace里且namespace只有一个,灰度配�?可以通过apollo.bootstrap.namespaces或者apollo.plugin.namespace来指�?�(如果namespace为application则都不需要配�?)
    • 如果业务配�?和灰度配�?不在同一个namespace里或者业务配�?横跨几个namespace,灰度配�?必须通过apollo.plugin.namespace来指�?�唯一的namespace

基于Nacos界面的灰度发布

Alt text

  • 参考Nacos�?�方文档https://github.com/alibaba/nacos相关文档,搭建Nacos环境,以及熟悉相关的基本操作
  • 添加配�?步骤跟Apollo配�?界面中的“在页面中添加配�?”操作项相似

基于Rest方式的灰度发布

  • Swagger方式 见“�?�理中心”和“控制平台”

  • Postman方式 导入Postman的测试脚本,脚本地址

基于图形化桌面程序的灰度发布

  • 桌面程序对Windows和Mac操作系统都支持,但在Mac操作系统中界面显示有点瑕疵,但不影响功能使用
  • Clone https://github.com/Nepxion/Discovery.git获取源码
  • 通过IDE启动
    • 运行discovery-console-desktop\ConsoleLauncher.java启动
  • 通过脚本启动
    • 在discovery-console-desktop�?录下执行mvn clean install,target�?录下将产生discovery-console-desktop-[版本号]-release的�?录
    • 进入discovery-console-desktop-[版本号]-release,请�?改config/console.properties中的url,该地址指向控制平台的地址
    • 运行“Discovery灰度发布控制台.bat”,启动桌面程序
    • 如果您是操作系统,请参考“Discovery灰度发布控制台.bat”,自行编写“Discovery灰度发布控制台.sh”脚本,启动桌面程序
  • 操作界面
    • 登录�?�证,用户名和密码为admin/admin或者nepxion/nepxion。顺便说一下,控制台支持�?�单的�?�证,用户名和密码配�?在discovery-springcloud-example-console\bootstrap.properties中,您可以自己扩展AuthenticationResource并注入,�?�现更专业的�?�证功能 Alt text
    • 点击“显示服务拓扑”按�?,弹出“服务集群组过滤”对话框,列表是以服务所在的集群组列表(例如:eureka.instance.metadataMap.group=example-service-group),选择若干个并点击“�?�?�”按�?,如果使用者想获取全部的服务集群(可能会耗性能),则直接点击“取消”按�? Alt text
    • 从服务注册发现中心获取服务拓扑 Alt text
    • 执行灰度路由,选择一个服务,右�?菜单“执行灰度路由” Alt text
    • 通过“服务列表”切换,或者点击增加和删除服务按�?,�?�?�灰度路由路径,点击“执行路由” Alt text Alt text
    • 推送模式�?��?,“异步推送”和“同步推送”,前者是推送�?�后立刻返回,后者是推送�?�后等待推送结果(包括规则XML解析的异常等都能在界面上反映出来);“规则推送到远程配�?中心”和“规则推送到服务或者服务集群”,前者是推送到配�?中心(持久化),后者是推送到一个或者多个服务机器的内存(非持久化,重启后丢失) Alt text
    • 执行灰度发布,选择一个服务或者服务组,右�?菜单“执行灰度发布”,前者是通过单个服务�?�例执行灰度发布,后者是通过一组服务�?�例执行灰度发布 Alt text
    • 灰度发布,包括“更改版本”和“更改规则”,前者通过更改版本号去适配灰度规则中的版本匹配关系,后者直接�?改规则。“更改版本”是推送到一个或者多个服务机器的内存(非持久化,重启后丢失),“更改规则”是根�?不同的推送模式,两种方式都支持 Alt text
    • 全链路灰度发布,所有在同一个集群组(例如:eureka.instance.metadataMap.group=example-service-group)里的服务统一做灰度发布,即一个规则配�?搞�?�所有服务的灰度发布。点击“全链路灰度发布”按�?,弹出“全链路灰度发布”对话框 Alt text Alt text
    • 刷新灰度状态,选择一个服务或者服务组,右�?菜单“刷新灰度状态”,查看某个服务或者服务组是否正在做灰度发布 Alt text
  • 操作视频(有点老,请参考学习)

基于图形化Web程序的灰度发布

  • 参考图形化Web
  • 操作过程跟“基于图形化桌面程序的灰度发布”类似

自动化测试

性能压力测试

  • 机器配�?
服务 配�? 数�?
Spring Cloud Gateway 16C 32G 1
Zuul 1.x 16C 32G 1
Service 4C 8G 2
  • 优化方式
    • Spring Cloud Gateway,不需要优化
    • Zuul 1.x,优化如下
zuul.host.max-per-route-connections=1000
zuul.host.max-total-connections=1000
zuul.semaphore.max-semaphores=5000
  • 压测报告

基于WRK极限压测,报告如下

服务 性质 线程数 连接数 每秒最大请求数 资源耗费
Spring Cloud Gateway为起始的调用链 原生框架 5000 20000 28100左右 CPU占用率42%
Spring Cloud Gateway为起始的调用链 本框架 5000 20000 27800左右 CPU占用率42.3%
Zuul 1.x为起始的调用链 原生框架 5000 20000 24050左右 CPU占用率56%
Zuul 1.x为起始的调用链 本框架 5000 20000 23500左右 CPU占用率56.5%

Star走势图

Stargazers over time

About

🐳 Nepxion Discovery is an enhancement for Spring Cloud Discovery with gray release, router, weight, limitation, circuit breaker, degrade, isolation, monitor, tracing 灰度发布、路由、权重、限流、熔断、降级、隔离、监控、追踪

Topics

Resources

License

You can’t perform that action at this time.