Spring Cloud体系实现标签路由的方法示例

如果你正在使用Spring Cloud体系,在实际使用过程中正遇到以下问题,可以阅读本文章的内容作为后续你解决这些问题的参考,文章内容不保证无错,请务必仔细思考之后再进行实践。

问题:

1,本地连上开发或测试环境的集群连调,正常测试请求可能会请求到本地,被自己的debug阻塞。

2,测试环境维护时,多项目并发提测,维护多个相同的集群进行测试是否必要,是否有更好的方案。

一般,我们在使用Spring Cloud全家桶的时候,会选择zuul作为网关,Ribbon作为负载均衡器,Feign作为远程服务调用模版。使用过Spring Cloud的同学对这些组件的作用必然非常熟悉。这里就拿这些组件组合成的微服务集群来实现标签路由的功能。

实现的效果如图所示,在头上带上标签的请求会在经过网关和各个应用时进行标签判断流量应该打到哪一个去,而每一个应用自己本身的标签是通过eureka上的matedate实现的。

如下图可以构想动态修改标签控制应用所能承接的请求,这里暂时不描述mq部分的功能:

答案:

实现一个ZoneAvoidanceRule的继承类,重写getPredicate方法:

@Override
public AbstractServerPredicate getPredicate() {
  OfflineEnvMetadataAwarePredicate offlineEnvMetadataAwarePredicate = new OfflineEnvMetadataAwarePredicate();
  offlineEnvMetadataAwarePredicate.setEnv(env);
  return offlineEnvMetadataAwarePredicate;
}

Predicate的实现屏蔽了开发测试环境中非这个环境网段启动的应用,并且比对请求的标签和本地的标签,来控制路由给哪一个服务器。

@Override
public AbstractServerPredicate getPredicate() {
  OfflineEnvMetadataAwarePredicate offlineEnvMetadataAwarePredicate = new OfflineEnvMetadataAwarePredicate();
  offlineEnvMetadataAwarePredicate.setEnv(env);
  return offlineEnvMetadataAwarePredicate;
}

那么我们注意到请求头上的标签要在初始时就拿到,所以需要一个ServletRequestListener,将拿到的zone放入RequestZoneLabelContext。我们知道在一个请求中如果是一个io线程执行到底,我们只需要利用threadlocal来存储线程变量,可是如果一个请求中会产生不定的子线程完成,数据在线程间的传递就成为问题,这里使用了InheritableThreadLocal来决解,在RequestZoneLabelContext中可以看到。

public class RequestZoneLabelContextListener implements ServletRequestListener {

  private static final String ZONE_LABEL_NAME = "zone";

  @Override
  public void requestDestroyed(ServletRequestEvent sre) {
    RequestZoneLabelContext.remove();
  }

  @Override
  public void requestInitialized(ServletRequestEvent requestEvent) {
    HttpServletRequest request = (HttpServletRequest)requestEvent.getServletRequest();
    String lbZone = request.getHeader(ZONE_LABEL_NAME);
    if(StringUtils.isNotBlank(lbZone)){
      RequestZoneLabelContext.setZone(lbZone);
    }
  }
}
/**
 * 从request header上传递label到feign请求
 */
public class RequestZoneLabelContext {

  private static InheritableThreadLocal<String> zoneLabelThreadLocal = new InheritableThreadLocal<>();

  public static void setZone(String zone){
    zoneLabelThreadLocal.set(zone);
  }

  public static String getRequestZone(){
    return zoneLabelThreadLocal.get();
  }

  public static void remove(){
    zoneLabelThreadLocal.remove();
  }
}

那么在应用之间调用的feign中我们是需要继续把这个zone通过header传递下去的,所以又扩展了RequestInterceptor:

public class FeignZoneHeaderInterceptor implements RequestInterceptor {

  @Override
  public void apply(RequestTemplate template) {
    String requestZone = RequestZoneLabelContext.getRequestZone();
    if(StringUtils.isNotBlank(requestZone)){
      template.header("zone", requestZone);
    }
  }
}

至此就基本实现了最初的想法。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 详解Spring Cloud Gateway 数据库存储路由信息的扩展方案

    动态路由背景 ​ 无论你在使用Zuul还是Spring Cloud Gateway 的时候,官方文档提供的方案总是基于配置文件配置的方式 例如: # zuul 的配置形式 routes: pig-auth: path: /auth/** serviceId: pig-auth stripPrefix: true # gateway 的配置形式 routes: - id: pigx-auth uri: lb://pigx-auth predicates: - Path=/auth/** filte

  • 详解Spring Cloud Zuul中路由配置细节

    上篇文章我们介绍了API网关的基本构建方式以及请求过滤,小伙伴们对Zuul的作用应该已经有了一个基本的认识,但是对于路由的配置我们只是做了一个简单的介绍,本文我们就来看看路由配置的其他一些细节. 首先我们来回忆一下上篇文章我们配置路由规则的那两行代码: zuul.routes.api-a.path=/api-a/** zuul.routes.api-a.serviceId=feign-consumer 我们说当我的访问地址符合/api-a/**规则的时候,会被自动定位到feign-consume

  • 利用Spring Cloud Zuul实现动态路由示例代码

    前言 本文主要给大家介绍了关于Spring Cloud Zuul实现动态路由的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. Zuul 是提供动态路由,监控,弹性,安全等的边缘服务.Zuul 相当于是设备和 Netflix 流应用的 Web 网站后端所有请求的前门. Zuul 可以适当的对多个 Amazon Auto Scaling Groups 进行路由请求. 首先新建maven项目,加入如下依赖 <dependencyManagement> <depend

  • SpringCloud Zuul实现动态路由

    前言 Zuul 是在Spring Cloud Netflix平台上提供动态路由,监控,弹性,安全等边缘服务的框架,是Netflix基于jvm的路由器和服务器端负载均衡器,相当于是设备和 Netflix 流应用的 Web 网站后端所有请求的前门.本文基于上篇(SpringCloud系列--Ribbon 负载均衡)实现Zuul动态路由 GitHub地址:https://github.com/Netflix/zuul 官方文档:https://cloud.spring.io/spring-cloud-

  • Spring Cloud GateWay 路由转发规则介绍详解

    Spring在因Netflix开源流产事件后,在不断的更换Netflix相关的组件,比如:Eureka.Zuul.Feign.Ribbon等,Zuul的替代产品就是SpringCloud Gateway,这是Spring团队研发的网关组件,可以实现限流.安全认证.支持长连接等新特性. Spring Cloud Gateway Spring Cloud Gateway是SpringCloud的全新子项目,该项目基于Spring5.x.SpringBoot2.x技术版本进行编写,意在提供简单方便.可

  • springcloud Zuul动态路由的实现

    前言 Zuul 是Netflix 提供的一个开源组件,致力于在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架.也有很多公司使用它来作为网关的重要组成部分,碰巧今年公司的架构组决定自研一个网关产品,集动态路由,动态权限,限流配额等功能为一体,为其他部门的项目提供统一的外网调用管理,最终形成产品(这方面阿里其实已经有成熟的网关产品了,但是不太适用于个性化的配置,也没有集成权限和限流降级). 不过这里并不想介绍整个网关的架构,而是想着重于讨论其中的一个关键点,并且也是经常在交流群中听人说起的:

  • Spring Cloud体系实现标签路由的方法示例

    如果你正在使用Spring Cloud体系,在实际使用过程中正遇到以下问题,可以阅读本文章的内容作为后续你解决这些问题的参考,文章内容不保证无错,请务必仔细思考之后再进行实践. 问题: 1,本地连上开发或测试环境的集群连调,正常测试请求可能会请求到本地,被自己的debug阻塞. 2,测试环境维护时,多项目并发提测,维护多个相同的集群进行测试是否必要,是否有更好的方案. 一般,我们在使用Spring Cloud全家桶的时候,会选择zuul作为网关,Ribbon作为负载均衡器,Feign作为远程服务

  • 基于Nacos实现Spring Cloud Gateway实现动态路由的方法

    简介 该文档主要介绍以Nacos为配置中心,实现Spring Cloud GateWay 实现动态路由的功能.Spring Cloud Gateway启动时候,就将路由配置和规则加载到内存里,无法做到不重启网关就可以动态的对应路由的配置和规则进行增加,修改和删除.通过nacos的配置下发的功能可以实现在不重启网关的情况下,实现动态路由. 集成 Spring Cloud GateWay集成 spring-cloud-starter-gateway:路由转发.请求过滤(权限校验.限流以及监控等) s

  • Spring Cloud zuul自定义统一异常处理实现方法

    Zuul在springcloud微服务体系中提供filer和router功能,是微服务不可或缺的部分.filer处理默认实现的外还可以自定义进行授权.限流.安全校验等,router完全可以替代Nginx反向代理.Zuul异常处理就是由SendErrorFilter完成. 在我们应用过程我们发现使用默认的异常filter有两个问题不是很友好: 1.无法快速识别出是否是请求路由的服务超时还是没有任何可用节点,发生错误只能查看日志通过堆栈去定位: 2.无法兼容自定义的譬如{code:500,msg:"

  • spring cloud中启动Eureka Server的方法

    本文介绍了spring cloud中启动Eureka Server的方法,分享给大家,具体如下: 一.新建工程 二.工程结构 三.修改配置文件 # eureka.client.registerWithEureka :表示是否将自己注册到Eureka Server,默认为true.由于当前这个应用就是Eureka Server,故而设为false # eureka.client.fetchRegistry :表示是否从Eureka Server获取注册信息,默认为true.因为这是一个单点的Eur

  • Spring根据URL参数进行路由的方法详解

    前言 本文主要介绍了关于Spring根据URL参数进行路由的相关内容,分享出来供大家参考学习价值,下面来一起看看详细的介绍吧. 发现问题 最近在写接口的时候发现一个问题,就是两个REST接口的URL的path部分是一样的,根据query传入不同的参数来区分. 比如S3普通上传接口是是: PUT /{bucketname}/{ objectname} 分块上传的接口是: PUT /{bucketname}/{objectname}?partNumber={partNumber}&uploadId=

  • Spring cloud Eureka注册中心搭建的方法

    前提  系统安装jdk1.8及以上,配置好maven的ide(这里用idea进行演示,maven版本3.5,配置阿里云源) 项目搭建 新建一个maven项目,创建最简单的那种就好,项目名这里为EurekaServerDemo,包名什么的随意,项目打包方式为jar, 也可以使用spring官方的生成器,官方的生成器会创建基础的springboot项目结构.这里为了演示,都可以 修改pom文件,参考如下,版本推荐和本文相同,springboot和cloud版本的坑很多 <?xml version=&qu

  • Spring Cloud微服务使用webSocket的方法

    webSocket webSocket长连接是一种在单个tcp连接上进行全双工通信的协议,允许双向数据推送.一般微服务提供的restful API只是对前端请求做出相应.使用webSocket可以实现后端主动向前端推送消息. 网关配置 spring cloud 的网关组件有zuul和getway getway base: config: nacos: nacoshost: localhost port: 8848 spring: application: name: gateway main:

  • Spring Cloud Stream消息驱动组件使用方法介绍

    目录 1.Stream解决的痛点问题 2.Stream重要概念 3.传统MQ模型与Stream消息驱动模型 4.Stream消息通信方式及编程模型 4.1.Stream消息通信方式 4.2.Stream编程注解 4.3.Stream消息驱动之开发生产者端 4.4.Stream消息驱动之开发消费者端 5.Stream高级之自定义消息通道 6.Stream高级之消息分组 MQ:消息队列/消息中间件/消息代理,产品有很多,ActiveMQ RabbitMQ RocketMQ Kafka 1.Strea

随机推荐