Nepxion Discovery【探索】微服务企业级解决方案

  • 时间:
  • 浏览:0
  • 来源:5分时时彩官网_去哪玩5分时时彩_哪里可以玩5分时时彩

Nepxion Discovery【探索】使用指南,基于Spring Cloud Greenwich版、Finchley版和Hoxton版而制作,对于Edgware版,使用者必须自行修改。使用指南主要涉及的功能包括:

  • 基于Header传递的全链路灰度路由,网关为路由触发点。采用配置中心配置路由规则映射在网关过滤器中植入Header信息而实现,路由规则传递到全链路服务中。路由法律法律依据 主要包括版本和区域的匹配路由、版本和区域的权重路由、基于机器IP地址和端口的路由
  • 基于规则订阅的全链路灰度发布。采用配置中心配置灰度规则映射在全链路服务而实现,所有服务都订阅某个共享配置。发布法律法律依据 主要包括版本和区域的匹配发布、版本和区域的权重发布
  • 全链路服务隔离。包括注册隔离、消费端隔离和提供端服务隔离,示例仅提供基于Group隔离。除此之外,不在 本文介绍内的,还包括:
    • 注册隔离:黑/白名单的IP地址的注册隔离、最大注册数限制的注册隔离
    • 消费端隔离:黑/白名单的IP地址的消费端隔离
  • 全链路服务限流熔断降级权限,集成阿里巴巴Sentinel,有机整合灰度路由,扩展LimitApp的机制,通过动态的Http Header法律法律依据 实现组合式防护机制,包括基于服务名、基于灰度组、基于灰度版本、基于灰度区域、基于机器地址和端口等防护机制,支持自定义任意的业务参数组合实现该功能。支持原生的流控规则、降级规则、授权规则、系统规则、热点参数流控规则
  • 全链路灰度调用链。包括Header法律法律依据 和日志法律法律依据 ,Header法律法律依据 框架外部集成,日志法律法律依据 通过MDC输出(需使用者自行集成)
  • 同城双活多机房切换支持。它含有在“基于Header传递的全链路灰度路由”里
  • 数据库灰度发布。内置简单的数据库灰度发布策略,它不在 本文的介绍范围内
  • 灰度路由和发布的自动化测试
  • Docker容器化和Kubernetes平台的无缝支持部署

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

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

[Spring Cloud Alibaba] 阿里巴巴里面件部门开发的Spring Cloud增强套件,致力于提供微服务开发的一站式处理方案。此项目含有开发分布式应用微服务的必需组件,方便开发者通过Spring Cloud编程模型轻松使用什么组件来开发分布式应用服务。依托Spring Cloud Alibaba,只必须加上一些注解和极少量配置,就可否 将Spring Cloud应用接入阿里微服务处理方案,通过阿里里面件来比较慢搭建分布式应用系统

示例以Nacos为服务注册中心和配置中心(使用者可自行加上其它服务注册中心和配置中心),集成Spring Cloud Alibaba,通过Gateway和Zuul调用一一有有另一个版本原应区域的服务,模拟网关灰度路由和服务灰度权重的功能

原应使用者必须更强大的功能,请参考源码主页。规则策略太大,请使用者确定最适合被委托人业务场景的法律法律依据

目录

  • 请联系我
  • 相关链接
    • 源码主页
    • 指南主页
    • 文档主页
  • 相关图示
    • 部署架构拓扑图
    • 服务治理架构图
    • 灰度法律法律依据 区别图
  • 环境搭建
  • 启动服务
  • 环境验证
  • 基于Header传递法律法律依据 的网关灰度路由策略
    • 灰度路由架构图
      • 多版本灰度路由架构图
      • 多区域灰度路由架构图
      • 多IP和端口灰度路由架构图
    • 配置网关灰度路由策略
      • 版本匹配灰度路由策略
      • 版本权重灰度路由策略
      • 区域匹配灰度路由策略
      • 区域权重灰度路由策略
    • 通过其它法律法律依据 设置网关灰度路由策略
      • 通过前端传入灰度路由策略
      • 通过业务参数在网关过滤器中自定义灰度路由策略
      • 通过业务参数在策略类中自定义灰度路由策略
    • 配置前端灰度&网关灰度路由组合式策略
  • 基于订阅法律法律依据 的全链路灰度发布规则
    • 配置全链路灰度匹配规则
      • 版本匹配灰度规则
      • 区域匹配灰度规则
    • 配置全链路灰度权重规则
      • 全局版本权重灰度规则
      • 局部版本权重灰度规则
      • 全局区域权重灰度规则
      • 局部区域权重灰度规则
    • 配置全链路灰度权重&灰度版本组合式规则
  • 全链路服务隔离
    • 注册服务隔离
    • 消费端服务隔离
    • 提供端服务隔离
  • 基于Sentinel的全链路服务限流熔断降级权限和灰度融合
    • 原生Sentinel注解
    • 原生Sentinel规则
      • 流控规则
      • 降级规则
      • 授权规则
      • 系统规则
      • 热点参数流控规则
    • 基于灰度路由和Sentinel-LimitApp扩展的防护机制
      • 基于服务名的防护机制
      • 基于灰度组的防护机制
      • 基于灰度版本的防护机制
      • 基于灰度区域的防护机制
      • 基于机器地址和端口的防护机制
      • 自定义业务参数的组合式防护机制
  • 基于Hystrix的全链路服务限流熔断和灰度融合
  • 全链路灰度调用链
    • Header输出法律法律依据
    • 日志输出法律法律依据
  • 全链路Header传递
    • 自定义Feign-Header传递
    • 自定义RestTemplate-Header传递
  • Docker容器化和Kubernetes平台支持

请联系我

微信、公众号和文档

相关链接

源码主页

源码主页

指南主页

指南主页

文档主页

文档主页

相关图示

部署架构拓扑图

服务治理架构图

灰度法律法律依据 区别图

环境搭建

  • 下载代码
    • Git clone https://github.com/Nepxion/DiscoveryGuide.git
  • 代码导入IDE
  • 下载Nacos服务器
    • 从https://github.com/alibaba/nacos/releases获取nacos-server-x.x.x.zip,并解压
  • 启动Nacos服务器
    • Windows环境下,运行bin目录下的startup.cmd
    • Linux环境下,运行bin目录下的startup.sh

启动服务

  • 在IDE中,启动两个应用服务和一一有有另一个网关服务,如下:
DiscoveryGuideServiceA1.java A1 60 1 1.0 dev
DiscoveryGuideServiceA2.java A2 60 2 1.1 qa
DiscoveryGuideServiceB1.java B1 60 1 1.0 qa
DiscoveryGuideServiceB2.java B2 60 2 1.1 dev
DiscoveryGuideGateway.java Gateway 60 01 1.0
DiscoveryGuideZuul.java Zuul 60 02 1.0

注:启动不分前后次序

环境验证

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

  • 在Postman中执行目录形状下 ”Nepxion“ -> ”Discovery指南网关接口“ -> ”Gateway网关调用示例“,调用地址为http://localhost:60 01/discovery-guide-service-a/invoke/gateway,相关的Header值原应预设,供开发者修改。测试通过Spring Cloud Gateway网关的调用结果,结果为如下格式:
gateway -> discovery-guide-service-a[192.168.0.107:60

1][V=1.0][R=dev][G=discovery-guide-group] 
-> discovery-guide-service-b[192.168.0.107:60

1][V=1.0][R=qa][G=discovery-guide-group]
  • 在Postman中执行目录形状下 ”Nepxion“ -> ”Discovery指南网关接口“ -> ”Zuul网关调用示例“,调用地址为http://localhost:60 02/discovery-guide-service-a/invoke/zuul,相关的Header值原应预设,供开发者修改。测试通过Zuul网关的调用结果,结果为如下格式:
zuul -> discovery-guide-service-a[192.168.0.107:60

1][V=1.0][R=dev][G=discovery-guide-group] 
-> discovery-guide-service-b[192.168.0.107:60

1][V=1.0][R=qa][G=discovery-guide-group]
  • 上述步骤在下面每次更改规则策略的我让你执行,并验证结果和规则策略的期望值是否是相同

灰度路由架构图

多版本灰度路由架构图

多区域灰度路由架构图

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

配置网关灰度路由策略

在Nacos配置中心,增加网关灰度路由策略

版本匹配灰度路由策略

增加Spring Cloud Gateway的基于版本匹配路由的灰度策略,Group为discovery-guide-group,Data Id为discovery-guide-gateway,策略内容如下,实现从Spring Cloud Gateway发起的调用都走版本为1.0的服务:

<?xml version="1.0" encoding="UTF-8"?>
<rule>
    <strategy>
        <version>1.0</version>
    </strategy>
</rule>

每个服务调用的版本都可否 自行指定,见下面第二条。当所有服务都选同一版本的我让你,可否 繁杂成下面第根小

1. <version>1.0</version>
2. <version>{"discovery-guide-service-a":"1.0", "discovery-guide-service-b":"1.0"}</version>

原应上述表达式还未满足需求,也可否 采用通配符(具体全版用法,参考Spring AntPathMatcher)

* - 表示调用范围为所有服务的所有版本
1.* - 表示调用范围为所有服务的1开头的所有版本

原应

"discovery-guide-service-b":"1.*;1.2.?"

表示discovery-guide-service-b服务的版本调用范围是1开头的所有版本,原应是1.2开头的所有版本(末尾必须是一一有有另一个字符)

版本权重灰度路由策略

增加Spring Cloud Gateway的基于版本权重路由的灰度策略,Group为discovery-guide-group,Data Id为discovery-guide-gateway,策略内容如下,实现从Spring Cloud Gateway发起的调用1.0版本流量调用为90%,1.1流量调用为10%:

<?xml version="1.0" encoding="UTF-8"?>
<rule>
    <strategy>
        <version-weight>1.0=90;1.1=10</version-weight>
    </strategy>
</rule>

每个服务调用的版本权重都可否 自行指定,见下面第二条。当所有服务都选相同版本权重的我让你,可否 繁杂成下面第根小

1. <version-weight>1.0=90;1.1=10</version-weight>
2. <version-weight>{"discovery-guide-service-a":"1.0=90;1.1=10", "discovery-guide-service-b":"1.0=90;1.1=10"}</version-weight>

区域匹配灰度路由策略

增加Zuul的基于区域匹配路由的灰度策略,Group为discovery-guide-group,Data Id为discovery-guide-zuul,策略内容如下,实现从Zuul发起的调用都走区域为dev的服务:

<?xml version="1.0" encoding="UTF-8"?>
<rule>
    <strategy>
        <region>dev</region>
    </strategy>
</rule>

每个服务调用的区域都可否 自行指定,见下面第二条。当所有服务都选同一区域的我让你,可否 繁杂成下面第根小

1. <region>dev</region>
2. <region>{"discovery-guide-service-a":"dev", "discovery-guide-service-b":"dev"}</region>

原应上述表达式还未满足需求,也可否 采用通配符(具体全版用法,参考Spring AntPathMatcher)

* - 表示调用范围为所有服务的所有区域
d* - 表示调用范围为所有服务的d开头的所有区域

原应

"discovery-guide-service-b":"d*;q?"

表示discovery-guide-service-b服务的区域调用范围是d开头的所有区域,原应是q开头的所有区域(末尾必须是一一有有另一个字符)

区域权重灰度路由策略

增加Zuul的基于区域权重路由的灰度策略,Group为discovery-guide-group,Data Id为discovery-guide-zuul,策略内容如下,实现从Zuul发起的调用dev区域流量调用为85%,qa区域流量调用为15%:

<?xml version="1.0" encoding="UTF-8"?>
<rule>
    <strategy>
        <region-weight>dev=85;qa=15</region-weight>
    </strategy>
</rule>

每个服务调用的区域权重都可否 自行指定,见下面第二条。当所有服务都选相同区域权重的我让你,可否 繁杂成下面第根小

1. <region-weight>dev=85;qa=15</region-weight>
2. <region-weight>{"discovery-guide-service-a":"dev=85;qa=15", "discovery-guide-service-b":"dev=85;qa=15"}</region-weight>

通过其它法律法律依据 设置网关灰度路由策略

除了里面通过配置中心发布灰度规路由则外,还有如下有一种法律法律依据 :

通过前端传入灰度路由策略

通过前端(Postman)法律法律依据 传入灰度路由策略,来代替配置中心法律法律依据 ,传递全链路路由策略。注意:当配置中心和界面都配置后,以界面传入优先

  • 版本匹配策略,Header格式如下任选一一有有另一个:
1. n-d-version=1.0
2. n-d-version={"discovery-guide-service-a":"1.0", "discovery-guide-service-b":"1.0"}
  • 版本权重策略,Header格式如下任选一一有有另一个:
1. n-d-version-weight=1.0=90;1.1=10
2. n-d-version-weight={"discovery-guide-service-a":"1.0=90;1.1=10", "discovery-guide-service-b":"1.0=90;1.1=10"}
  • 区域匹配策略,Header格式如下任选一一有有另一个:
1. n-d-region=qa
2. n-d-region={"discovery-guide-service-a":"qa", "discovery-guide-service-b":"qa"}
  • 区域权重策略,Header格式如下任选一一有有另一个:
1. n-d-region-weight=dev=99;qa=1
2. n-d-region-weight={"discovery-guide-service-a":"dev=99;qa=1", "discovery-guide-service-b":"dev=99;qa=1"}
  • 机器IP地址和端口策略:
n-d-address={"discovery-guide-service-a":"127.0.0.1:60

1", "discovery-guide-service-b":"127.0.0.1:60

2"}

当外界传值Header的我让你,网关也设置并传递同名的Header,必须决定哪个Header传递到里面的服务去。必须通过如下开关做控制:

# 当外界传值Header的我让你,网关也设置并传递同名的Header,必须决定哪个Header传递到里面的服务去。原应下面开关为true,以网关设置为优先,我让你以外界传值为优先。缺失则默认为true
spring.application.strategy.gateway.header.priority=false
# 当以网关设置为优先的我让你,网关未配置Header,而外界配置了Header,仍旧忽略外界的Header。缺失则默认为true
spring.application.strategy.gateway.original.header.ignored=true

# 当外界传值Header的我让你,网关也设置并传递同名的Header,必须决定哪个Header传递到里面的服务去。原应下面开关为true,以网关设置为优先,我让你以外界传值为优先。缺失则默认为true
spring.application.strategy.zuul.header.priority=false
# 当以网关设置为优先的我让你,网关未配置Header,而外界配置了Header,仍旧忽略外界的Header。缺失则默认为true
spring.application.strategy.zuul.original.header.ignored=true

通过业务参数在网关过滤器中自定义灰度路由策略

通过网关过滤器传递Http Header的法律法律依据 传递全链路灰度路由策略。下面代码只适用于Zuul和Spring Cloud Gateway网关,Service微服务后该须加该法律法律依据

  • 内置策略解析映射到过滤器的自定义法律法律依据

增加Spring Cloud Gateway的解析策略,Group为discovery-guide-group,Data Id为discovery-guide-gateway,原应,增加Spring Cloud Gateway的解析策略,Group为discovery-guide-group,Data Id为discovery-guide-zuul,策略内容见下面XML内容,它所表达的功能逻辑:

1. 当外部调用含有的Http Header中的值a=1并肩b=2
   <condition>节点中header="a=1;b=2"对应的version-id="version-route1",找到下面
   <route>节点中id="version-route1" type="version"的那项,没法路由即为:
   {"discovery-guide-service-a":"1.1", "discovery-guide-service-b":"1.1"}

2. 当外部调用含有的Http Header中的值a=1
   <condition>节点中header="a=1"对应的version-id="version-route2",找到下面
   <route>中id="version-route2" type="version"的那项,没法路由即为:
   {"discovery-guide-service-a":"1.0", "discovery-guide-service-b":"1.1"}

3. 当外部调用含有的Http Header中的值全版一定会命中,找到里面
   <strategy>节点中的全局缺省路由,没法路由即为:
   {"discovery-guide-service-a":"1.0", "discovery-guide-service-b":"1.0"}

4. 策略解析总共支持5种,可否

单独一项使用,也可否

多项叠加使用:
   1)version 版本路由
   2)region 区域路由
   3)address 机器地址路由
   4)version-weight 版本权重路由
   5)region-weight 区域权重路由
<?xml version="1.0" encoding="UTF-8"?>
<rule>
    <!-- 基于Http Header传递的策略路由,全局缺省路由 -->
    <strategy>
        <version>{"discovery-guide-service-a":"1.0", "discovery-guide-service-b":"1.0"}</version>
    </strategy>

    <!-- 基于Http Header传递的策略路由,客户定制化控制,跟业务参数绑定。原应不命中,则执行里面的全局缺省路由 -->
    <strategy-customization>
        <conditions>
            <condition id="condition1" header="a=1" version-id="version-route2"/>
            <condition id="condition2" header="a=1;b=2" version-id="version-route1"/>
        </conditions>

        <routes>
            <route id="version-route1" type="version">{"discovery-guide-service-a":"1.1", "discovery-guide-service-b":"1.1"}</route>
            <route id="version-route2" type="version">{"discovery-guide-service-a":"1.0", "discovery-guide-service-b":"1.1"}</route>
        </routes>
    </strategy-customization>
</rule>

  • 用户覆盖过滤器的自定义法律法律依据

继承GatewayStrategyRouteFilter原应ZuulStrategyRouteFilter,覆盖掉如下法律法律依据 中的一一有有另一个原应多个,通过@Bean法律法律依据 覆盖框架内置的过滤类

protected String getRouteVersion();

protected String getRouteRegion();

protected String getRouteAddress();

GatewayStrategyRouteFilter示例

在代码里根据不同的Header确定不同的路由路径

// 适用于A/B Testing原应更根据某业务参数决定灰度路由路径。可否

结合配置中心分别配置A/B两条路径,可否

动态改变并通知
// 当Header中传来的用户为张三,执行根小路由路径;为李四,执行另根小路由路径
public class MyGatewayStrategyRouteFilter extends DefaultGatewayStrategyRouteFilter {
    private static final String DEFAULT_A_ROUTE_VERSION = "{\"discovery-guide-service-a\":\"1.0\", \"discovery-guide-service-b\":\"1.1\"}";
    private static final String DEFAULT_B_ROUTE_VERSION = "{\"discovery-guide-service-a\":\"1.1\", \"discovery-guide-service-b\":\"1.0\"}";

    @Value("${a.route.version:" + DEFAULT_A_ROUTE_VERSION + "}")
    private String aRouteVersion;

    @Value("${b.route.version:" + DEFAULT_B_ROUTE_VERSION + "}")
    private String bRouteVersion;

    @Override
    public String getRouteVersion() {
        String user = strategyContextHolder.getHeader("user");

        if (StringUtils.equals(user, "zhangsan")) {
            return aRouteVersion;
        } else if (StringUtils.equals(user, "lisi")) {
            return bRouteVersion;
        }

        return super.getRouteVersion();
    }
}

在配置类里@Bean法律法律依据 进行过滤类创建,覆盖框架内置的过滤类

@Bean
public GatewayStrategyRouteFilter gatewayStrategyRouteFilter() {
    return new MyGatewayStrategyRouteFilter();
}

ZuulStrategyRouteFilter示例

在代码中 ,根据不同的Header确定不同的路由路径

// 适用于A/B Testing原应更根据某业务参数决定灰度路由路径。可否

结合配置中心分别配置A/B两条路径,可否

动态改变并通知
// 当Header中传来的用户为张三,执行根小路由路径;为李四,执行另根小路由路径
public class MyZuulStrategyRouteFilter extends DefaultZuulStrategyRouteFilter {
    private static final String DEFAULT_A_ROUTE_VERSION = "{\"discovery-guide-service-a\":\"1.0\", \"discovery-guide-service-b\":\"1.1\"}";
    private static final String DEFAULT_B_ROUTE_VERSION = "{\"discovery-guide-service-a\":\"1.1\", \"discovery-guide-service-b\":\"1.0\"}";

    @Value("${a.route.version:" + DEFAULT_A_ROUTE_VERSION + "}")
    private String aRouteVersion;

    @Value("${b.route.version:" + DEFAULT_B_ROUTE_VERSION + "}")
    private String bRouteVersion;

    @Override
    public String getRouteVersion() {
        String user = strategyContextHolder.getHeader("user");

        if (StringUtils.equals(user, "zhangsan")) {
            return aRouteVersion;
        } else if (StringUtils.equals(user, "lisi")) {
            return bRouteVersion;
        }

        return super.getRouteVersion();
    }
}

在配置类里@Bean法律法律依据 进行过滤类创建,覆盖框架内置的过滤类

@Bean
public ZuulStrategyRouteFilter zuulStrategyRouteFilter() {
    return new MyZuulStrategyRouteFilter();
}

通过业务参数在策略类中自定义灰度路由策略

通过策略法律法律依据 自定义灰度路由策略。下面代码既适用于Zuul和Spring Cloud Gateway网关,也适用于Service微服务,并肩全链路中网关和服务都必须加该法律法律依据

// 实现了组合策略,版本路由策略+区域路由策略+IP和端口路由策略+自定义策略
public class MyDiscoveryEnabledStrategy extends DefaultDiscoveryEnabledStrategy {
    private static final Logger LOG = LoggerFactory.getLogger(MyDiscoveryEnabledStrategy.class);

    // 对Rest调用传来的Header参数(这名:mobile)做策略
    @Override
    public boolean apply(Server server) {
        String mobile = strategyContextHolder.getHeader("mobile");
        String serviceId = pluginAdapter.getServerServiceId(server);
        String version = pluginAdapter.getServerVersion(server);
        String region = pluginAdapter.getServerRegion(server);

        LOG.info("负载均衡用户定制触发:mobile={}, serviceId={}, version={}, region={}", mobile, serviceId, version, region);

        if (StringUtils.isNotEmpty(mobile)) {
            // 手机号以移动138开头,路由到1.0版本的服务上
            if (mobile.startsWith("138") && StringUtils.equals(version, "1.0")) {
                return true;
                // 手机号以联通133开头,路由到2.0版本的服务上
            } else if (mobile.startsWith("133") && StringUtils.equals(version, "1.1")) {
                return true;
            } else {
                // 其它状态,直接拒绝请求
                return false;
            }
        }

        return true;
    }
}

在配置类里@Bean法律法律依据 进行策略类创建

@Bean
public DiscoveryEnabledStrategy discoveryEnabledStrategy() {
    return new MyDiscoveryEnabledStrategy();
}

在网关和服务中支持基于Rest Header传递的自定义灰度路由策略,除此之外,服务还支持基于Rpc法律法律依据 参数传递的自定义灰度路由策略,它包括接口名、法律法律依据 名、参数名或参数值等多种形式。下面的示例表示在服务中并肩开启基于Rest Header传递和Rpc法律法律依据 参数传递的自定义组合式灰度路由策略

// 实现了组合策略,版本路由策略+区域路由策略+IP和端口路由策略+自定义策略
public class MyDiscoveryEnabledStrategy implements DiscoveryEnabledStrategy {
    private static final Logger LOG = LoggerFactory.getLogger(MyDiscoveryEnabledStrategy.class);

    @Autowired
    private PluginAdapter pluginAdapter;

    @Autowired
    private ServiceStrategyContextHolder serviceStrategyContextHolder;

    @Override
    public boolean apply(Server server) {
        boolean enabled = applyFromHeader(server);
        if (!enabled) {
            return false;
        }

        return applyFromMethod(server);
    }

    // 根据Rest调用传来的Header参数(这名:mobile),确定执行调用请求的服务实例
    private boolean applyFromHeader(Server server) {
        String mobile = serviceStrategyContextHolder.getHeader("mobile");
        String serviceId = pluginAdapter.getServerServiceId(server);
        String version = pluginAdapter.getServerVersion(server);
        String region = pluginAdapter.getServerRegion(server);

        LOG.info("负载均衡用户定制触发:mobile={}, serviceId={}, version={}, region={}", mobile, serviceId, version, region);

        if (StringUtils.isNotEmpty(mobile)) {
            // 手机号以移动138开头,路由到1.0版本的服务上
            if (mobile.startsWith("138") && StringUtils.equals(version, "1.0")) {
                return true;
                // 手机号以联通133开头,路由到2.0版本的服务上
            } else if (mobile.startsWith("133") && StringUtils.equals(version, "1.1")) {
                return true;
            } else {
                // 其它状态,直接拒绝请求
                return false;
            }
        }

        return true;
    }

    // 根据RPC调用传来的法律法律依据

参数(这名接口名、法律法律依据

名、参数名或参数值等),确定执行调用请求的服务实例
    // 本示例只作用在discovery-guide-service-a服务上
    @SuppressWarnings("unchecked")
    private boolean applyFromMethod(Server server) {
        Map<String, Object> attributes = serviceStrategyContextHolder.getRpcAttributes();
        String serviceId = pluginAdapter.getServerServiceId(server);
        String version = pluginAdapter.getServerVersion(server);
        String region = pluginAdapter.getServerRegion(server);

        LOG.info("负载均衡用户定制触发:attributes={}, serviceId={}, version={}, region={}", attributes, serviceId, version, region);

        if (attributes.containsKey(ServiceStrategyConstant.PARAMETER_MAP)) {
            Map<String, Object> parameterMap = (Map<String, Object>) attributes.get(ServiceStrategyConstant.PARAMETER_MAP);
            String value = parameterMap.get("value").toString();
            if (StringUtils.isNotEmpty(value)) {
                // 输入值含有dev,路由到dev区域的服务上
                if (value.contains("dev") && StringUtils.equals(region, "dev")) {
                    return true;
                    // 输入值含有qa,路由到qa区域的服务上
                } else if (value.contains("qa") && StringUtils.equals(region, "qa")) {
                    return true;
                } else {
                    // 其它状态,直接通过请求
                    return true;
                }
            }
        }

        return true;
    }
}

必须通过如下开关开启该功能

# 启动和关闭路由策略的我让你,对RPC法律法律依据

的调用拦截。缺失则默认为false
spring.application.strategy.rpc.intercept.enabled=true

配置前端灰度&网关灰度路由组合式策略

当前端(这名:APP)和后端微服务并肩所处多个版本时,可否 执行“前端灰度&网关灰度路由组合式策略”

这名:前端所处1.0和2.0版本,微服务所处1.0和2.0版本,原应所处版本不兼容的状态(前端1.0版本必须调用微服务的1.0版本,前端2.0版本必须调用微服务的2.0版本),没法前端调用网关我让你,可否 通过Header传递它的版本号给网关,网关根据前端版本号,去路由对应版本的微服务

该场景可否 用“通过业务参数在网关过滤器中自定义灰度路由策略”的方案来处理,如下:

<?xml version="1.0" encoding="UTF-8"?>
<rule>
    <strategy-customization>
        <conditions>
            <condition id="condition1" header="app-version=1.0" version-id="version-route1"/>
            <condition id="condition2" header="app-version=2.0" version-id="version-route2"/>
        </conditions>

        <routes>
            <route id="version-route1" type="version">{"discovery-guide-service-a":"1.0", "discovery-guide-service-b":"1.0"}</route>
            <route id="version-route2" type="version">{"discovery-guide-service-a":"1.1", "discovery-guide-service-b":"1.1"}</route>
        </routes>
    </strategy-customization>
</rule>

上述配置,模拟出全链路中,两条独立不受干扰的调用路径:

1. APP v1.0 -> 网关 -> A服务 v1.0 -> B服务 v1.0
2. APP v1.1 -> 网关 -> A服务 v1.1 -> B服务 v1.1

基于订阅法律法律依据 的全链路灰度发布规则

在Nacos配置中心,增加全链路灰度发布规则

注意:该功能和网关灰度路由和灰度权重功能会叠加,为了不影响演示效果,请先清除网关灰度路由的策略

配置全链路灰度匹配规则

版本匹配灰度规则

增加版本匹配的灰度规则,Group为discovery-guide-group,Data Id为discovery-guide-group(全局发布,两者全版一定会组名),规则内容如下,实现a服务1.0版本必须访问b服务1.0版本,a服务1.1版本必须访问b服务1.1版本:

<?xml version="1.0" encoding="UTF-8"?>
<rule>
    <discovery>
        <version>
            <service consumer-service-name="discovery-guide-service-a" provider-service-name="discovery-guide-service-b" consumer-version-value="1.0" provider-version-value="1.0"/>
            <service consumer-service-name="discovery-guide-service-a" provider-service-name="discovery-guide-service-b" consumer-version-value="1.1" provider-version-value="1.1"/>
        </version>
    </discovery>
</rule>

区域匹配灰度规则

增加区域匹配的灰度规则,Group为discovery-guide-group,Data Id为discovery-guide-group(全局发布,两者全版一定会组名),规则内容如下,实现dev区域的a服务必须访问dev区域的b服务,qa区域的a服务必须访问qa区域的b服务:

<?xml version="1.0" encoding="UTF-8"?>
<rule>
    <discovery>
        <region>
            <service consumer-service-name="discovery-guide-service-a" provider-service-name="discovery-guide-service-b" consumer-region-value="dev" provider-region-value="dev"/>
            <service consumer-service-name="discovery-guide-service-a" provider-service-name="discovery-guide-service-b" consumer-region-value="qa" provider-region-value="qa"/>
        </region>
    </discovery>
</rule>

配置全链路灰度权重规则

全局版本权重灰度规则

增加全局版本权重的灰度规则,Group为discovery-guide-group,Data Id为discovery-guide-group(全局发布,两者全版一定会组名),规则内容如下,实现版本为1.0的服务提供90%的流量,版本为1.1的服务提供10%的流量:

<?xml version="1.0" encoding="UTF-8"?>
<rule>
    <discovery>
        <weight>
            <version provider-weight-value="1.0=90;1.1=10"/>
        </weight>
    </discovery>
</rule>

局部版本权重灰度规则

增加局部版本权重的灰度规则,Group为discovery-guide-group,Data Id为discovery-guide-group(全局发布,两者全版一定会组名),规则内容如下,实现a服务1.0版本提供90%的流量,1.1版本提供10%的流量;b服务1.0版本提供20%的流量,1.1版本提供60 %的流量:

<?xml version="1.0" encoding="UTF-8"?>
<rule>
    <discovery>
        <weight>
            <service provider-service-name="discovery-guide-service-a" provider-weight-value="1.0=90;1.1=10" type="version"/>
            <service provider-service-name="discovery-guide-service-b" provider-weight-value="1.0=20;1.1=60

" type="version"/>
        </weight>
    </discovery>
</rule>

全局区域权重灰度规则

增加全局区域权重的灰度规则,Group为discovery-guide-group,Data Id为discovery-guide-group(全局发布,两者全版一定会组名),规则内容如下,实现区域为dev的服务提供90%的流量,区域为qa的服务提供10%的流量:

<?xml version="1.0" encoding="UTF-8"?>
<rule>
    <discovery>
        <weight>
            <region provider-weight-value="dev=90;qa=10"/>
        </weight>
    </discovery>
</rule>

局部区域权重灰度规则

增加局部区域权重的灰度规则,Group为discovery-guide-group,Data Id为discovery-guide-group(全局发布,两者全版一定会组名),规则内容如下,实现a服务dev区域提供90%的流量,qa区域提供10%的流量;b服务dev区域提供20%的流量,qa区域提供60 %的流量:

<?xml version="1.0" encoding="UTF-8"?>
<rule>
    <discovery>
        <weight>
            <service provider-service-name="discovery-guide-service-a" provider-weight-value="dev=90;qa=10" type="region"/>
            <service provider-service-name="discovery-guide-service-b" provider-weight-value="dev=20;qa=60

" type="region"/>
        </weight>
    </discovery>
</rule>

注意:局部权重优先级高于全局权重,版本权重优先级高于区域权重

请执行Postman操作,请仔细观察服务被随机权重调用到的概率

配置全链路灰度权重&灰度版本组合式规则

增加组合式的灰度规则,Group为discovery-guide-group,Data Id为discovery-guide-group(全局发布,两者全版一定会组名),规则内容如下,实现功能:

  • a服务1.0版本向网关提供90%的流量,1.1版本向网关提供10%的流量
  • a服务1.0版本必须访问b服务1.0版本,1.1版本必须访问b服务1.1版本

该功能的意义是,网关随机权重调用服务,而服务链路按照版本匹配法律法律依据 调用

<?xml version="1.0" encoding="UTF-8"?>
<rule>
    <discovery>
        <version>
            <service consumer-service-name="discovery-guide-service-a" provider-service-name="discovery-guide-service-b" consumer-version-value="1.0" provider-version-value="1.0"/>
            <service consumer-service-name="discovery-guide-service-a" provider-service-name="discovery-guide-service-b" consumer-version-value="1.1" provider-version-value="1.1"/>
        </version>

        <weight>
            <service consumer-service-name="discovery-guide-gateway" provider-service-name="discovery-guide-service-a" provider-weight-value="1.0=90;1.1=10" type="version"/>
            <service consumer-service-name="discovery-guide-zuul" provider-service-name="discovery-guide-service-a" provider-weight-value="1.0=90;1.1=10" type="version"/>
        </weight>
    </discovery>
</rule>

图形化界面验证

全链路服务隔离

元数据中的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

通过修改discovery-guide-service-b的Group名为其它名称,执行Postman调用,将发现从discovery-guide-service-a无法拿到discovery-guide-service-b的任何实例。原应在discovery-guide-service-a消费端进行了隔离

提供端服务隔离

基于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.guide.service.feign

在Postman调用,执行http://localhost:60 1/invoke/abc,去调用discovery-guide-service-b服务,将经常出现如下异常。原应在discovery-guide-service-b提供端进行了隔离

Reject to invoke because of isolation with different service group



原应加上n-d-service-group=discovery-guide-group的Header,没法两者保持Group相同,则调用通过。这是处理异构系统调用微服务被隔离的有一种手段

基于Sentinel的全链路服务限流熔断降级权限和灰度融合

通过集成Sentinel,在服务端实现该功能

封装NacosDataSource和ApolloDataSource,支持Nacos和Apollo一一有有另一个远程配置中心,零代码实现Sentinel功能。更多的远程配置中心,请参照Sentinel官方的DataSource并自行集成

1. Nacos的Key格式:Group为元数据中配置的[组名],Data Id为[服务名]-[规则类型]
2. Apollo的Key格式:[组名]-[服务名]-[规则类型]

支持远程配置中心和本地规则文件的读取逻辑,即优先读取远程配置,原应不所处原应规则错误,则读取本地规则文件。动态实现远程配置中心对于规则的热刷新

支持如下开关开启该动能,默认是关闭的

# 启动和关闭Sentinel限流降级熔断权限等功能。缺失则默认为false
spring.application.strategy.sentinel.enabled=true

原生Sentinel注解

参照下面代码,为接口法律法律依据 增加@SentinelResource注解,value为sentinel-resource,blockHandler和fallback是防护其作用后必须执行的法律法律依据

@RestController
@ConditionalOnProperty(name = DiscoveryConstant.SPRING_APPLICATION_NAME, havingValue = "discovery-guide-service-b")
public class BFeignImpl extends AbstractFeignImpl implements BFeign {
    private static final Logger LOG = LoggerFactory.getLogger(BFeignImpl.class);

    @Override
    @SentinelResource(value = "sentinel-resource", blockHandler = "handleBlock", fallback = "handleFallback")
    public String invoke(@PathVariable(value = "value") String value) {
        value = doInvoke(value);

        LOG.info("调用路径:{}", value);

        return value;
    }

    public String handleBlock(String value, BlockException e) {
        return value + "-> B server sentinel block, cause=" + e.getClass().getName() + ", rule=" + e.getRule() + ", limitApp=" + e.getRuleLimitApp();
    }

    public String handleFallback(String value) {
        return value + "-> B server sentinel fallback";
    }
}

原生Sentinel规则

原生Sentinel规则的用法,请参照Sentinel官方文档

流控规则

增加服务discovery-guide-service-b的规则,Group为discovery-guide-group,Data Id为discovery-guide-service-b-sentinel-flow,规则内容如下:

[
    {
        "resource": "sentinel-resource",
        "limitApp": "default",
        "grade": 1,
        "count": 1,
        "strategy": 0,
        "refResource": null,
        "controlBehavior": 0,
        "warmUpPeriodSec": 10,
        "maxQueueingTimeMs": 60

0,
        "clusterMode": false,
        "clusterConfig": null
    }
]

降级规则

增加服务discovery-guide-service-b的规则,Group为discovery-guide-group,Data Id为discovery-guide-service-b-sentinel-degrade,规则内容如下:

[
    {
        "resource": "sentinel-resource",
        "limitApp": "default",
        "count": 2,
        "timeWindow": 10,
        "grade": 0,
        "passCount": 0
    }
]

授权规则

增加服务discovery-guide-service-b的规则,Group为discovery-guide-group,Data Id为discovery-guide-service-b-sentinel-authority,规则内容如下:

[
    {
        "resource": "sentinel-resource",
        "limitApp": "discovery-guide-service-a",
        "strategy": 0
    }
]

系统规则

增加服务discovery-guide-service-b的规则,Group为discovery-guide-group,Data Id为discovery-guide-service-b-sentinel-system,规则内容如下:

[
    {
        "resource": null,
        "limitApp": null,
        "highestSystemLoad": -1.0,
        "highestCpuUsage": -1.0,
        "qps": 60

.0,
        "avgRt": -1,
        "maxThread": -1
    }
]

热点参数流控规则

增加服务discovery-guide-service-b的规则,Group为discovery-guide-group,Data Id为discovery-guide-service-b-sentinel-param-flow,规则内容如下:

[
    {
        "resource": "sentinel-resource",
        "limitApp": "default",
        "grade": 1,
        "paramIdx": 0,
        "count": 1,
        "controlBehavior": 0,
        "maxQueueingTimeMs": 0,
        "burstCount": 0,
        "durationInSec": 1,
        "paramFlowItemList": [],
        "clusterMode": false
    }
]

基于灰度路由和Sentinel-LimitApp扩展的防护机制

该法律法律依据 对于里面5种规则全版一定会效,这里以授权规则展开阐述

授权规则中,limitApp,原应有多个,可否 通过“,”分隔。"strategy": 0 表示白名单,"strategy": 1 表示黑名单

基于服务名的防护机制

修改配置项Sentinel Request Origin Key为服务名的Header名称,修改授权规则中limitApp为对应的服务名,可实现基于服务名的防护机制

配置项,该配置项默认为n-d-service-id,可否 不配置

spring.application.strategy.service.sentinel.request.origin.key=n-d-service-id

增加服务discovery-guide-service-b的规则,Group为discovery-guide-group,Data Id为discovery-guide-service-b-sentinel-authority,规则内容如下,表示所有discovery-guide-service-a服务允许访问discovery-guide-service-b服务

[
    {
        "resource": "sentinel-resource",
        "limitApp": "discovery-guide-service-a",
        "strategy": 0
    }
]

基于灰度组的防护机制

修改配置项Sentinel Request Origin Key为灰度组的Header名称,修改授权规则中limitApp为对应的组名,可实现基于组名的防护机制

配置项

spring.application.strategy.service.sentinel.request.origin.key=n-d-service-group

增加服务discovery-guide-service-b的规则,Group为discovery-guide-group,Data Id为discovery-guide-service-b-sentinel-authority,规则内容如下,表示隶属my-group组的所有服务都允许访问服务discovery-guide-service-b

[
    {
        "resource": "sentinel-resource",
        "limitApp": "my-group",
        "strategy": 0
    }
]

基于灰度版本的防护机制

修改配置项Sentinel Request Origin Key为灰度版本的Header名称,修改授权规则中limitApp为对应的版本,可实现基于版本的防护机制

配置项

spring.application.strategy.service.sentinel.request.origin.key=n-d-service-version

增加服务discovery-guide-service-b的规则,Group为discovery-guide-group,Data Id为discovery-guide-service-b-sentinel-authority,规则内容如下,表示版本为1.0的所有服务都允许访问服务discovery-guide-service-b

[
    {
        "resource": "sentinel-resource",
        "limitApp": "1.0",
        "strategy": 0
    }
]

基于灰度区域的防护机制

修改配置项Sentinel Request Origin Key为灰度区域的Header名称,修改授权规则中limitApp为对应的区域,可实现基于区域的防护机制

配置项

spring.application.strategy.service.sentinel.request.origin.key=n-d-service-region

增加服务discovery-guide-service-b的规则,Group为discovery-guide-group,Data Id为discovery-guide-service-b-sentinel-authority,规则内容如下,表示区域为dev的所有服务都允许访问服务discovery-guide-service-b

[
    {
        "resource": "sentinel-resource",
        "limitApp": "dev",
        "strategy": 0
    }
]

基于机器地址和端口的防护机制

修改配置项Sentinel Request Origin Key为灰度区域的Header名称,修改授权规则中limitApp为对应的区域值,可实现基于机器地址和端口的防护机制

配置项

spring.application.strategy.service.sentinel.request.origin.key=n-d-service-address

增加服务discovery-guide-service-b的规则,Group为discovery-guide-group,Data Id为discovery-guide-service-b-sentinel-authority,规则内容如下,表示地址和端口为192.168.0.88:60 81和192.168.0.88:60 82的服务都允许访问服务discovery-guide-service-b

[
    {
        "resource": "sentinel-resource",
        "limitApp": "192.168.0.88:60

81,192.168.0.88:60

82",
        "strategy": 0
    }
]

自定义业务参数的组合式防护机制

通过适配类实现自定义业务参数的组合式防护机制

// 自定义版本号+用户名,实现组合式熔断
public class MyServiceSentinelRequestOriginAdapter extends DefaultServiceSentinelRequestOriginAdapter {
    @Override
    public String parseOrigin(HttpServletRequest request) {
        String version = request.getHeader(DiscoveryConstant.N_D_SERVICE_VERSION);
        String user = request.getHeader("user");

        return version + "&" + user;
    }
}

在配置类里@Bean法律法律依据 进行适配类创建

@Bean
public ServiceSentinelRequestOriginAdapter ServiceSentinelRequestOriginAdapter() {
    return new MyServiceSentinelRequestOriginAdapter();
}

增加服务discovery-guide-service-b的规则,Group为discovery-guide-group,Data Id为discovery-guide-service-b-sentinel-authority,规则内容如下,表示版本为1.0且传入的Http Header的user=zhangsan,并肩满足这名一有有另一个条件下的所有服务都允许访问服务discovery-guide-service-b

[
    {
        "resource": "sentinel-resource",
        "limitApp": "1.0&zhangsan",
        "strategy": 0
    }
]

运行效果

  • 当传递的Http Header中user=zhangsan,当全链路调用中,API网关负载均衡discovery-guide-service-a服务到1.0版本后再去调用discovery-guide-service-b服务,最终调用成功

  • 当传递的Http Header中user=lisi,不满足条件,最终调用在discovery-guide-service-b服务端被拒绝掉

  • 当传递的Http Header中user=zhangsan,满足条件之一,当全链路调用中,API网关负载均衡discovery-guide-service-a服务到1.1版本后再去调用discovery-guide-service-b服务,不满足version=1.0的条件,最终调用在discovery-guide-service-b服务端被拒绝掉

基于Hystrix的全链路服务限流熔断和灰度融合

通过引入Hystrix组件实现服务限流熔断的功能,在执行灰度发布和路由我让你,系统进程池隔离模式下进行调用会丢失上下文,没法必须下述步骤处理该状态。下面步骤并肩适用于网关端和服务端

  • Pom引入
<!-- 当服务用Hystrix做系统进程隔离的我让你,才必须导入下面的包 -->
<dependency>
    <groupId>com.nepxion</groupId>
    <artifactId>discovery-plugin-strategy-starter-hystrix</artifactId>
    <version>${discovery.version}</version>
</dependency>
  • 配置开启
# 开启服务端实现Hystrix系统进程隔离模式做服务隔离时,必须把spring.application.strategy.hystrix.threadlocal.supported设置为true,同必须引入discovery-plugin-strategy-starter-hystrix包,我让你系统进程切换一定会所处ThreadLocal上下文对象丢失。缺失则默认为false
spring.application.strategy.hystrix.threadlocal.supported=true

全链路灰度调用链

灰度调用链主要包括如下6个参数。使用者可否 自行定义要传递的调用链参数,这名:traceId, spanId等;也可否 自行定义要传递的业务调用链参数,这名:mobile, user等

1. n-d-service-group - 服务所属组原应应用
2. n-d-service-type - 服务类型,分为“网关”和“服务”
3. n-d-service-id - 服务ID
4. n-d-service-address - 服务地址,包括Host和Port
5. n-d-service-version - 服务版本
6. n-d-service-region - 服务所属区域

灰度调用链输出分为Header法律法律依据 和日志法律法律依据

Header法律法律依据 框架外部集成

  • Spring Cloud Gateway网关端自行会传输Header值(参考Discovery源码中的AbstractGatewayStrategyRouteFilter.java)
  • Zuul网关端自行会传输Header值(参考Discovery源码中的AbstractZuulStrategyRouteFilter.java)
  • 服务端通过Feign和RestTemplate拦截器传输Header值(参考Discovery源码中的FeignStrategyInterceptor.java和RestTemplateStrategyInterceptor.java)

日志输出法律法律依据

  • Spring Cloud Gateway网关

继承GatewayStrategyTracer.java,trace法律法律依据 里把6个参数(参考父类里debugTraceHeader法律法律依据 )原应更多通过MDC法律法律依据 输出到日志

// 自定义调用链和灰度调用链通过MDC输出到日志。使用者集成我让你,关注trace法律法律依据

中的MDC.put和release法律法律依据

中MDC.clear代码每段即可
public class MyGatewayStrategyTracer extends DefaultGatewayStrategyTracer {
    @Override
    public void trace(ServerWebExchange exchange) {
        super.trace(exchange);
        
        // 输出到日志
        MDC.put("traceid", "traceid=" + strategyContextHolder.getHeader("traceid"));
        ...

        MDC.put(DiscoveryConstant.N_D_SERVICE_GROUP, "服务组名=" + strategyContextHolder.getHeader(DiscoveryConstant.N_D_SERVICE_GROUP));
        ...
    }

    @Override
    public void release(ServerWebExchange exchange) {
        MDC.clear();
    }
}

在配置类里@Bean法律法律依据 进行调用链类创建,覆盖框架内置的调用链类

@Bean
@ConditionalOnProperty(value = StrategyConstant.SPRING_APPLICATION_STRATEGY_TRACE_ENABLED, matchIfMissing = false)
public GatewayStrategyTracer gatewayStrategyTracer() {
    return new MyGatewayStrategyTracer();
}
  • Zuul网关

继承ZuulStrategyTracer.java,trace法律法律依据 里把6个参数(参考父类里debugTraceHeader法律法律依据 )原应更多通过MDC法律法律依据 输出到日志

// 自定义调用链和灰度调用链通过MDC输出到日志。使用者集成我让你,关注trace法律法律依据

中的MDC.put和release法律法律依据

中MDC.clear代码每段即可
public class MyZuulStrategyTracer extends DefaultZuulStrategyTracer {
    @Override
    public void trace(RequestContext context) {
        super.trace(context);
        
        // 输出到日志
        MDC.put("traceid", "traceid=" + strategyContextHolder.getHeader("traceid"));
        ...

        MDC.put(DiscoveryConstant.N_D_SERVICE_GROUP, "服务组名=" + strategyContextHolder.getHeader(DiscoveryConstant.N_D_SERVICE_GROUP));
        ...
    }

    @Override
    public void release(RequestContext context) {
        MDC.clear();
    }
}

在配置类里@Bean法律法律依据 进行调用链类创建,覆盖框架内置的调用链类

@Bean
@ConditionalOnProperty(value = StrategyConstant.SPRING_APPLICATION_STRATEGY_TRACE_ENABLED, matchIfMissing = false)
public ZuulStrategyTracer zuulStrategyTracer() {
    return new MyZuulStrategyTracer();
}
  • Service服务

继承ServiceStrategyTracer.java,trace法律法律依据 里把6个参数(参考父类里debugTraceLocal法律法律依据 )原应更多通过MDC法律法律依据 输出到日志

// 自定义调用链和灰度调用链通过MDC输出到日志。使用者集成我让你,关注trace法律法律依据

中的MDC.put和release法律法律依据

中MDC.clear代码每段即可
public class MyServiceStrategyTracer extends DefaultServiceStrategyTracer {
    @Override
    public void trace(ServiceStrategyTracerInterceptor interceptor, MethodInvocation invocation) {
        super.trace(interceptor, invocation);
        
        // 输出到日志
        MDC.put("traceid", "traceid=" + strategyContextHolder.getHeader("traceid"));
        ...

        MDC.put(DiscoveryConstant.N_D_SERVICE_GROUP, "服务组名=" + pluginAdapter.getGroup());
        ...
    }

    @Override
    public void release(ServiceStrategyTracerInterceptor interceptor, MethodInvocation invocation) {
        MDC.clear();
    }
}

在配置类里@Bean法律法律依据 进行调用链类创建,覆盖框架内置的调用链类

@Bean
@ConditionalOnProperty(value = StrategyConstant.SPRING_APPLICATION_STRATEGY_TRACE_ENABLED, matchIfMissing = false)
public ServiceStrategyTracer serviceStrategyTracer() {
    return new MyServiceStrategyTracer();
}

请参考在IDE控制台打印的结果

对于调用链功能的开启和关闭,必须通过如下开关做控制:

# 启动和关闭调用链。缺失则默认为false
spring.application.strategy.trace.enabled=true
# 启动和关闭调用链的Debug日志打印,注意每调用一次一定会打印一次,会对性能有所影响,建议压测环境跟生产环境关闭。缺失则默认为false
spring.application.strategy.trace.debug.enabled=true

框架会默认把相关的Header,进行全链路传递,可否 通过如下配置进行。除此之外,凡是以“n-d-”开头的任何Header,框架一定会默认全链路传递

# 启动和关闭路由策略的我让你,对REST法律法律依据

的调用拦截。缺失则默认为true
spring.application.strategy.rest.intercept.enabled=true
# 启动和关闭Header传递的Debug日志打印,注意每调用一次一定会打印一次,会对性能有所影响,建议压测环境跟生产环境关闭。缺失则默认为false
spring.application.strategy.rest.intercept.debug.enabled=true
# 灰度路由策略的我让你,对REST法律法律依据

调用拦截的我让你(支持Feign原应RestTemplate调用),希望把来自外部自定义的Header参数(用于框架内置上下文Header,这名:traceid, spanid等)传递到服务里,没法配置如下值。原应多个用“;”分隔,不允许经常出现空格
spring.application.strategy.context.request.headers=traceid;spanid
# 灰度路由策略的我让你,对REST法律法律依据

调用拦截的我让你(支持Feign原应RestTemplate调用),希望把来自外部自定义的Header参数(用于业务系统子定义Header,这名:mobile)传递到服务里,没法配置如下值。原应多个用“;”分隔,不允许经常出现空格
spring.application.strategy.business.request.headers=user;mobile

原生的Feign Header传递可否 使用RequestInterceptor拦截器实现,原生的RestTemplate Header传递可否 使用ClientHttpRequestInterceptor拦截器实现

本框架也使用什么原生的拦截器用作Header在灰度功能上的传递,为了处理使用者再去多创建一层拦截器,框架抽象出一一有有另一个拦截适配器,用法和原生的一一有有另一个拦截器一致,可否 帮助使用者实现自定义Header的传递

实现FeignStrategyInterceptorAdapter.java,在apply法律法律依据 里加入自定义的Header传递

// 自定义Feign拦截器中的Header传递
public class MyFeignStrategyInterceptorAdapter extends DefaultFeignStrategyInterceptorAdapter {
    @Override
    public void apply(RequestTemplate requestTemplate) {
        requestTemplate.header("n-d-my-id", "123");
    }
}

在配置类里@Bean法律法律依据 进行拦截适配器创建

@Bean
public FeignStrategyInterceptorAdapter feignStrategyInterceptorAdapter() {
    return new MyFeignStrategyInterceptorAdapter();
}

实现RestTemplateStrategyInterceptorAdapter.java,在intercept法律法律依据 里加入自定义的Header传递

// 自定义RestTemplate拦截器中的Header传递
public class MyRestTemplateStrategyInterceptorAdapter extends DefaultRestTemplateStrategyInterceptorAdapter {
    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        HttpHeaders headers = request.getHeaders();
        headers.add("n-d-my-id", "456");

        return execution.execute(request, body);
    }
}

在配置类里@Bean法律法律依据 进行拦截适配器创建

@Bean
public RestTemplateStrategyInterceptorAdapter restTemplateStrategyInterceptorAdapter() {
    return new MyRestTemplateStrategyInterceptorAdapter();
}

Docker容器化和Kubernetes平台

Docker容器化

  • 搭建Windows10操作系统原应Linux操作系统下的Docker环境
    • Windows10环境下,具体步骤参考Docker安装步骤
    • Linux环境请自行研究
  • 全自动部署和运行Docker化的服务。在根目录下
    • 一键运行install-docker-gateway.bat原应.sh,把Spring Cloud Gateway网关全自动部署且运行起来
    • 一键运行install-docker-zuul.bat原应.sh,把Zuul网关全自动部署且运行起来
    • 一键运行install-docker-service-xx.bat原应.sh,把微服务全自动部署且运行起来。注意,必须依次运行,即等上一一有有另一个部署完毕后并能执行下一一有有另一个

Kubernetes平台

请自行研究

本文由博文多发平台 OpenWrite 发布!

本文由博客一文多发平台 OpenWrite 发布!