Spring Cloud Alibaba 本地调试介绍及方案设计

目录
  • 1 本地调试介绍
  • 2 框架环境
  • 3 方案设计
  • 4 实现要点
  • 5. 总结
  • 附:工具方法

1 本地调试介绍

本地调试: 这里是指在开发环境中,部署了一整套的某个项目或者产品的服务,开发人员开发时,本地会起一个或多个服务,这些服务和开发环境中部署的服务是相同的,这种情况下,一个服务就会有多个实例,大多数微服务中的默认负载均衡策略都是轮询,这些实例会轮流被调用。

为了方便 本地调试,需要提供一种策略,可以指定在负载均衡时,选择哪个实例进行调用。在使用 Nacos 作为注册中心时,可以通过 上线和下线 的方式来选择使用哪个实例,但是这种方式只能强制调用某个实例,如果开发环境还有其他人在调试,自己程序 设置断点 时会阻塞所有调用,非常不利于多人调试的协调。

为了解决 本地调试 的问题,本文实现了一种简单实用的策略,可以通过 Nacos 动态配置服务路由,还可以基于用户,部门,组织等级别配置服务路由,实现 本地调试 的同时,实际上也实现 灰度发布

2 框架环境

本文基于 Spring Cloud Alibaba 框架,和 Spring Cloud 相比增加了一部分针对 Dubbo 的方案,因此本文适合以下框架参考:

  • Spring Cloud Alibaba
  • Spring Cloud

Spring Cloud Gateway
Spring Cloud Ribbon

  • Dubbo

下图是 Spring Cloud Alibaba 框架中,一次方法调用的可能情况,Ailbaba 这部分多的是图中 ServiceA -> ServiceB 部分使用 Dubbo 协议。Spring Cloud 框架中,用的是 ServiceA -> ServiceC 这种 Feign(HTTP) 方式。

图中的所有过滤器和拦截器,虽然名称不同,但是作用相同。这部分的主要作用就是 获取或传递路由规则,例如,可以实现基于 HTTP Header 设置路由规则的配置,可以基于 HTTP 和 token 实现基于用户的路由规则配置,这部分的实现和需求有关,没有统一的实现。

3 方案设计

这里以这两种场景简单举个例子。

3.1 基于 HTTP Header 的本地调试方案

在这个方案中,按照上面的流程图叙述一遍。

  1. 用户调用服务前,在 Header 中设置调用规则,比如增加 service-route 请求头,请求头的内容为 servicea:10.10.10.130;serviceb:10.10.10.100;servicec:10.10.10.0/24,在请求头中指明需要控制路由的服务信息(不需要控制的直接省略走默认)。
  2. 通过 Spring Cloud Gateway 的 GlobalFilter 实现提取请求头信息,将配置信息记录下来(如 ThreadLocal
  3. 负载均衡时,根据这里的配置选择优先路由的服务,调用 ServiceA 时,仍然是 HTTP 请求,请求头会传递过去。
  4. 拦截器获取请求头中的路由规则,这一步和 1 类似,但是属于 Spring MVC 的拦截器,获取路由规则后记录下来(如 ThreadLocal
  5. ServiceA 调用 ServiceB 是 Dubbo 协议的路径,和 7,8 Feign 方式没有先后顺序,是两个分支。 在 4 这一步通过 Dubbo 的 Consumer Filter 过滤器和 RpcContext 将路由信息记录到 attachment 中,这样可以把路由配置传递到 ServiceB,如果 ServiceB 还需要调用其他服务,路由仍然会起到作用。
  6. 在 Dubbo 的 Router 实现中,根据路由信息选择优先调用的服务,然后进行调用。
  7. Dubbo 的 Provider Filter 从 RpcContext 获取路由配置,记录下来(如 ThreadLocal),如果后续调用其他服务,逻辑和 4,5,6一样。在 6 这一步的 Provider Filter 结束调用的时候,注意清空路由信息(如 ThreadLocal.clear()),避免对其他调用产生污染。
  8. 这一步和4,5,6没有顺序关系,是纯 Spring Cloud 方式的调用,在 ServiceA 调用时,通过自定义 Ribbon 中的 IRule 实现基于自己路由规则的调用。
  9. 在最终调用 ServiceC 之前,通过 Feign 的 RequestInterceptor 拦截器添加 service-route 头,将服务路由传递下去。
  10. 和第3步相同,通过 Spring MVC 拦截器获取服务路由记录下来。后续在调用其他服务时,Dubbo服务走4,5,6,Feign方式走7,8,9。

3.2 基于操作用户的本地调试方案

基于操作用户的方案中,和上面类似,但是不需要在每次请求的时候设置 HTTP Header,但是需要一种方式存取服务路由的配置。

这里以使用 Nacos 配置管理实现服务路由配置的存取。

根据自己使用的用户在 Nacos 配置服务路由,配置名规则如 服务名.user-routes,使用 Spring Cloud Alibaba 的默认组 dubbo,用户服务路由的配置规则可以自己定义,这里举个简单例子:

enabled: true # 启用,停用
ip: 10.10.0.0/24 # 默认优先IP或网段,所有IP都支持具体IP和网段
userIps: # Map<Long, String>,优先级最高,针对用户配置 IP 优先
  # userId: IP
  1: 10.10.0.100
  2: 10.10.0.101
# 这部分定义根据自己需要设计
deptIps: # 针对部门配置
  # deptId: IP
  1: 10.10.0.0/24
orgIps: # 针对组织配置
  # orgId: IP
  1: 10.10.10.0/24

Spring Cloud Gateway 的 GlobalFilter 根据请求 token 获取 用户信息,记录用户信息(如 ThreadLocal)。

  1. 负载均衡时,使用 Nacos ConfigService,根据 服务名.user-routes 查询配置信息,同时监听该配置信息,根据这里的配置选择优先路由的服务。
  2. 拦截器根据请求 token 获取 用户信息,记录用户信息(如 ThreadLocal)。
  3. ServiceA 调用 ServiceB 是 Dubbo 协议的路径,和 7,8 Feign 方式没有先后顺序,是两个分支。 在 4 这一步通过 Dubbo 的 Consumer Filter 过滤器和 RpcContext 将用户信息记录到 attachment 中,这样可以把用户信息传递到 ServiceB,如果 ServiceB 还需要调用其他服务,用户信息仍然会起到作用。
  4. 在 Dubbo 的 Router 实现中,根据路由信息选择优先调用的服务,然后进行调用。
  5. Dubbo 的 Provider Filter 从 RpcContext 获取用户信息,记录下来(如 ThreadLocal),如果后续调用其他服务,逻辑和 4,5,6一样。在 6 这一步的 Provider Filter 结束调用的时候,注意清空用户信息(如 ThreadLocal.clear()),避免对其他调用产生污染。
  6. 这一步和4,5,6没有顺序关系,是纯 Spring Cloud 方式的调用,在 ServiceA 调用时,通过自定义 Ribbon 中的 IRule 实现基于自己路由规则的调用。
  7. 在最终调用 ServiceC 之前,通过 Feign 的 RequestInterceptor 拦截器设置token或用户信息,将操作用户传递下去。
  8. 和第3步相同,通过 Spring MVC 拦截器获取用户信息记录下来。后续在调用其他服务时,Dubbo服务走4,5,6,Feign方式走7,8,9。

本文选择第 2 种方案,针对 1~9 步,分别讲解需要实现的接口和接口应用(生效)的配置。

4 实现要点

上面提到的 ThreadLocal,实现时使用一个 static 变量存储,提供相应的存取清空的静态方法,方便跨接口的 用户信息 传递。

4.1 Spring Cloud Gateway 全局过滤器

假设有一个 UserGlobalFilter,该过滤器根据 token 获取并缓存用户信息,在请求完成后需要清空缓存的用户信息。

Spring Cloud Gateway 中的过滤器,直接在 @Configuration 的配置类中用 @Bean 提供即可。

4.2 Ribbon 负载均衡

实现 ribbon-loadbalancer 中的 com.netflix.loadbalancer.IRule 接口,将来调用具体服务时通过 choose 接口返回符合条件的实例。

实现这个接口之后,需要特殊的方式注册该接口,在启动类增加注解 @RibbonClients(defaultConfiguration = UserRuleConfiguration.class)
注解中指定了一个配置类,这个类一定不要添加 @Configuration 注解!!!

在这个类中,通过 @Bean 注解返回一个 IRule 接口的实现。

在 Ribbon 中,会创建一个新的 ApplicationContext 来初始化这些配置,在这个新的 ApplicationContext 中,配置的 IRule 实现会被使用。

4.3 Spring MVC 拦截器

实现 HandlerInterceptor 拦截器,从请求获取用户信息并记录下来。

拦截器想要生效,需要提供一个配置类,继承 WebMvcConfigurer 接口,实现 addInterceptors 方法,在这个方法实现中添加拦截器的实现类。

4.4 Dubbo Consumer Filter 过滤器

实现Dubbo 的Filter接口,通过 RpcContext 传递前面记录的用户信息。

可以在实现类添加 @Activate 注解,指定 groupCommonConstants.CONSUMER

按照 dubbo SPI 要求,添加 META-INF/dubbo/org.apache.dubbo.rpc.Filter 文件,写上实现类。

4.5 Dubbo Router 路由

这一步实际上可以放在 Dubbo 负载均衡实现,也可以用 Router 实现。

使用 Router 时,需要同时使用 RouterFactoryRouter 接口,然后配置 RouterFactory 的 SPI 配置文件。

Routerroute 方法中根据规则返回合适的 Invoker

4.6 Dubbo Provider Filter 过滤器

实现Dubbo 的Filter接口,通过 RpcContext 获取传递过来的用户信息。

可以在实现类添加 @Activate 注解,指定 groupCommonConstants.PROVIDER

按照 dubbo SPI 要求,添加 META-INF/dubbo/org.apache.dubbo.rpc.Filter 文件,写上实现类。

这个实现类可以和 4.4 的放一个 Filter 实现中,需要自己区分当前是 consumer 还是 provider 实现不同的逻辑。

4.7 Ribbon 负载均衡,同 4.2

这一步的实现和 4.2 一样,4.2 是用在 Spring Cloud Gateway 中,这里是配置到具体的服务中。配置方式一样。

4.8 Feign RequestInterceptor 拦截器

首先实现 RequestInterceptor 接口,在实现中往 requst 的 Header 中放置要传递的数据。

接口想要生效,需要和 Ribbon 类似的配置。

@EnableFeignClients 的注解中,通过 defaultConfiguration 设置一个 Feign 的配置类。在这个配置中通过 @Bean 提供 RequestInterceptor 接口的实现。

4.9 Spring MVC 拦截器,同 4.3

4.3 中是网关调用服务,4.9是服务通过 Feign (或resttemplate)调用服务,对被调用的服务来说都是 HTTP 请求,因此都会执行 Spring MVC 的拦截器,所以这里的实现是一样的。

5. 总结

本文提供了本地调试的方案和主要的实现要点,可以根据文中的关键指引和自己的实际需求实现自己的方案。关于本地调试如果有更好的方案,欢迎留言讨论。

附:工具方法

判断IP是否相等或输入子网IP的方法:

public static boolean ipInRange(String ip, String cidr) {
	if(cidr.indexOf('/') < 0) {
		return ip.equals(cidr);
	}
	int ipAddr = ipToInt(ip);
	int type = Integer.parseInt(cidr.replaceAll(".*/", ""));
	String cidrIp = cidr.replaceAll("/.*", "");
	if(type == 32){
		return ip.equals(cidrIp);
	}
	int cidrIpAddr = ipToInt(cidrIp);
	int mask = 0xFFFFFFFF << (32 - type);
	return (ipAddr & mask) == (cidrIpAddr & mask);
}

public static int ipToInt(String ip) {
	String[] ips = ip.split("\\.");
	return (Integer.parseInt(ips[0] << 24) |
			Integer.parseInt(ips[1] << 16) |
			Integer.parseInt(ips[2] << 8) |
			Integer.parseInt(ips[3]));
}

到此这篇关于Spring Cloud Alibaba 本地调试方案的文章就介绍到这了,更多相关Spring Cloud Alibaba 本地调试内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 详解Spring Cloud Alibaba Sidecar多语言微服务异构

    自 Spring Cloud Alibaba 2.1.1 版本后增加了 spring-cloud-alibaba-sidecar 模块作为作为一个代理的服务来间接性的让其他语言可以使用spring cloud alibaba等相关组件.通过与网关的来进行路由的映射,从而可以做到服务的获取,然后可以使用Ribbon间接性调用. 如上图, Spring Cloud 应用 请求 sidercar 然后转发给其他语言的模块,优势是对于异构服务代码 零侵入,不需要直接根据 nacos 或其他注册中心 ap

  • Spring Cloud Alibaba Nacos 入门详解

    概览 阿里巴巴在2018年7月份发布Nacos, Nacos是一个更易于构建云原生应用的动态服务发现.配置管理和服务管理平台.并表示在6-8个月完成到生产可用的0.8版本,目前版本是0.9版本. Nacos提供四大功能 服务发现和服务健康检查 Nacos使服务更容易注册自己并通过DNS或HTTP接口发现其他服务.Nacos还提供服务的实时健康检查,以防止向不健康的主机或服务实例发送请求. 动态配置管理 动态配置服务允许您在所有环境中以集中和动态的方式管理所有服务的配置.Nacos消除了在更新配置

  • SpringCloud-Alibaba-Nacos启动失败解决方案

    下载及启动 Nacos 下载地址:https://github.com/alibaba/nacos/releases 在Windows下,进入bin目录,双击 startup.cmd 即可运行 启动出现问题 问题:双击 startup.cmd 启动失败,窗口一闪而过 你需要先去试试你的 Tomcat 能否启动:进入 Tomcat 安装目录 bin 文件夹,双击 startup.bat 如果能正常启动,出门右转,下面的不用看了

  • 关于IDEA中spring-cloud-starter-alibaba-nacos-discovery 无法引入问题

    1.spring-cloud-starter-alibaba-nacos-discovery 这里依赖报红,无法引入,或显示无法找到,更换版本也无法解决,启动项目后nacos中也无法发现服务 ①错误显示unknown就需要加上版本号 2.解决 ①修改IDEA中的maven配置,把下面这个属性修改为Fail Fast(原来默认为default) ②给依赖加上版本 ③刷新maven,重启项目 3.查看nacos服务发现,就成功了 更多精彩内容关注公众号[Java技术迷] 到此这篇关于关于IDEA中s

  • Spring Cloud Alibaba 之 Nacos教程详解

    Nacos 技术讲解 一提到分布式系统就不的不提一下 CAP 原则 Nacos简介 Nacos是阿里的一个开源产品,它是针对微服务架构中的服务发现.配置管理.服务治理的综合性解决方案. 官方介绍是这样的: Nacos致力于帮助您发现.配置和管理微服务.Nacos提供了一组简单易用的特性集,帮助您实现动态服务发现.服务配置管理.服务及流量管理.Nacos帮助您更敏捷和容易地构建.交付和管理微服务平台.Nacos是构建以"服务"为中心的现代应用架构的服务基础设施. 什么是CAP CAP原则

  • Spring Cloud Alibaba使用Sentinel实现接口限流

    最近管点闲事浪费了不少时间,感谢网友 libinwalan 的留言提醒.及时纠正路线,继续跟大家一起学习Spring Cloud Alibaba. Nacos作为注册中心和配置中心的基础教程,到这里先告一段落,后续与其他结合的内容等讲到的时候再一起拿出来说,不然内容会有点跳跃.接下来我们就来一起学习一下Spring Cloud Alibaba下的另外一个重要组件:Sentinel. Sentinel是什么 Sentinel的官方标题是:分布式系统的流量防卫兵.从名字上来看,很容易就能猜到它是用来

  • Spring Cloud Alibaba 本地调试介绍及方案设计

    目录 1 本地调试介绍 2 框架环境 3 方案设计 4 实现要点 5. 总结 附:工具方法 1 本地调试介绍 本地调试: 这里是指在开发环境中,部署了一整套的某个项目或者产品的服务,开发人员开发时,本地会起一个或多个服务,这些服务和开发环境中部署的服务是相同的,这种情况下,一个服务就会有多个实例,大多数微服务中的默认负载均衡策略都是轮询,这些实例会轮流被调用. 为了方便 本地调试,需要提供一种策略,可以指定在负载均衡时,选择哪个实例进行调用.在使用 Nacos 作为注册中心时,可以通过 上线和下

  • IDEA 中 30 秒创建一个 Spring Cloud Alibaba 工程

    如果你想使用 Spring Cloud Alibaba,那么你遇到的第一个问题一定是如何快速的创建一个脚手架工程. 近日,阿里巴巴发布了 Spring 的国内脚手架定制版 Aliyun Java Initializer,因为全中文界面和流畅速度,被广大开发者热传.Spring 脚手架为开发者提供了丰富的可选组件,并且可以选择多种打包方式,大大方便了开发人员的使用.Web 端 Spring 脚手架可以帮助用户快速上手,但很多开发者也面临一个问题:在 Web 版本 Spring 脚手架生成工程最终要

  • Spring Cloud Alibaba之Sentinel实现熔断限流功能

    微服务中为了防止某个服务出现问题,导致影响整个服务集群无法提供服务的情况,我们在系统访问量和业务量高起来了后非常有必要对服务进行熔断限流处理. 其中熔断即服务发生异常时能够更好的处理:限流是限制每个服务的资源(比如说访问量). spring-cloud中很多使用的是Hystrix组件来进行限流的,现在我们这里使用阿里的sentinel来实现熔断限流功能. sentinel简介 这个在阿里云有企业级的商用版本 应用高可用服务 AHAS:现在有免费的入门级可以先体验下,之后再决定是否使用付费的专业版

  • 浅谈如何在项目中使用Spring Cloud Alibaba Sentinel组件

    目录 Sentinel 是什么 Sentinel与Hystrix的区别 Sentinel分为两大部分: 一.控制台(Dashboard) 二.搭建客户端 1.在自己的项目中引入依赖 2.编辑项目中的 application.yml或者bootstrap.yml文件 3.资源是 Sentinel 中的一个关键概念.它可以是任何东西,例如服务.方法,甚至是代码片段. 三.查看接口的流量的详情 1.实时监控 2.簇点链路 3.等等:其他使用方法有待发掘 Sentinel 是什么 随着微服务的流行,服务

  • Spring Cloud Alibaba Nacos Config加载配置详解流程

    目录 1.加载节点 2.NacosPropertySourceLocator的注册 3.加载 3.1.加载share 3.2.加载extention 3.3.加载主配置文件 1.加载节点 SpringBoot启动时,会执行这个方法:SpringApplication#run,这个方法中会调prepareContext来准备上下文,这个方法中调用了applyInitializers方法来执行实现了ApplicationContextInitializer接口的类的initialize方法.其中包括

  • Spring Cloud Alibaba教程之Sentinel的使用

    什么是Sentinel Sentinel,中文翻译为哨兵,是为微服务提供流量控制.熔断降级的功能,它和Hystrix提供的功能一样,可以有效的解决微服务调用产生的"雪崩"效应,为微服务系统提供了稳定性的解决方案.随着Hytrxi进入了维护期,不再提供新功能,Sentinel是一个不错的替代方案.通常情况,Hystrix采用线程池对服务的调用进行隔离,Sentinel才用了用户线程对接口进行隔离,二者相比,Hystrxi是服务级别的隔离,Sentinel提供了接口级别的隔离,Sentin

  • spring cloud alibaba Nacos 注册中心搭建过程详解

    这篇文章主要介绍了spring cloud alibaba Nacos 注册中心搭建过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 nacos下载地址 什么是 Nacos? nacos主要起到俩个作用一个是注册中心,另外一个是配置中心. 下面图 是nacos的功能结构图 运行环境 JDK 1.8+: Maven 3.2.x+: 下载 你可以通过源码和发行包两种方式来获取 Nacos. nacos发行包下载地址 选择版本解压 unzip

  • 简单了解Spring Cloud Alibaba相关知识

    这篇文章主要介绍了简单了解Spring Cloud Alibaba相关知识,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 官方github地址 Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案.此项目包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务. 主要功能 服务限流降级:默认支持 WebServlet.WebFlux, OpenFeign

  • Spring Cloud Alibaba整合Sentinel的实现步骤

    一.需求 实现一个简单的 整合 sentinel,不涉及sentinel的用法 二.实现步骤 1.下载 sentinel dashboard https://github.com/alibaba/Sentinel/releases 注意: 默认会启动8080端口,如果端口冲突,可以在启动命令上加入 -Dserver.port=新端口 默认用户名和密码[sentinel/sentinel] 启动控制台可用的配置项 2.服务提供者和消费者引入sentinel依赖 <dependency> <

随机推荐