详解Spring Cloud Zuul中路由配置细节
作者:_江南一点雨 发布时间:2022-07-31 06:55:45
上篇文章我们介绍了API网关的基本构建方式以及请求过滤,小伙伴们对Zuul的作用应该已经有了一个基本的认识,但是对于路由的配置我们只是做了一个简单的介绍,本文我们就来看看路由配置的其他一些细节。
首先我们来回忆一下上篇文章我们配置路由规则的那两行代码:
zuul.routes.api-a.path=/api-a/**
zuul.routes.api-a.serviceId=feign-consumer
我们说当我的访问地址符合/api-a/**规则的时候,会被自动定位到feign-consumer服务上去,不过两行代码有点麻烦,我们可以用下面一行代码来代替,如下:
zuul.routes.feign-consumer=/api-a/**
zuul.routes后面跟着的是服务名,服务名后面跟着的是路径规则,这种配置方式显然更简单。
如果映射规则我们什么都不写,系统也给我们提供了一套默认的配置规则,默认的配置规则如下:
zuul.routes.feign-consumer.path=/feign-consumer/**
zuul.routes.feign-consumer.serviceId=feign-consumer
默认情况下,Eureka上所有注册的服务都会被Zuul创建映射关系来进行路由,但是对于我这里的例子来说,我希望提供服务的是feign-consumer,hello-service作为服务提供者只对服务消费者提供服务,不对外提供服务,如果使用默认的路由规则,则Zuul也会自动为hello-service创建映射规则,这个时候我们可以采用如下方式来让Zuul跳过hello-service服务,不为其创建路由规则:
zuul.ignored-services=hello-service
有的小伙伴可能为有疑问,我们定义路由规则/api-a/**的时候,为什么最后面是两个*,一个可不可以呢?当然可以,不过意义可就不一样了,Zuul中的路由匹配规则使用了Ant风格定义,一共有三种不同的通配符:
通配符 | 含义 | 举例 | 解释 |
---|---|---|---|
? | 匹配任意单个字符 | /feign-consumer/? | 匹配/feign-consumer/a,/feign-consumer/b,/feign-consumer/c等 |
* | 匹配任意数量的字符 | /feign-consumer/* | 匹配/feign-consumer/aaa,feign-consumer/bbb,/feign-consumer/ccc等,无法匹配/feign-consumer/a/b/c |
** | 匹配任意数量的字符 | /feign-consumer/* | 匹配/feign-consumer/aaa,feign-consumer/bbb,/feign-consumer/ccc等,也可以匹配/feign-consumer/a/b/c |
有的时候我们还会遇到这样一个问题,比如我有两个服务,一个叫做feign-consumer,还有一个叫做feign-consumer-hello,此时我的路由配置规则可能这样来写:
zuul.routes.feign-consumer.path=/feign-consumer/**
zuul.routes.feign-consumer.serviceId=feign-consumer
zuul.routes.feign-consumer-hello.path=/feign-consumer/hello/**
zuul.routes.feign-consumer-hello.serviceId=feign-consumer-hello
此时我访问feign-consumer-hello的路径会同时被这两条规则所匹配,Zuul中的路径匹配方式是一种线性匹配方式,即按照路由匹配规则的存储顺序依次匹配,因此我们只需要确保feign-consumer-hello的匹配规则被先定义feign-consumer的匹配规则被后定义即可,但是在properties文件中我们不能保证这个先后顺序,此时我们需要用YAML来配置,这个时候我们可以删掉resources文件夹下的application.properties,然后新建一个application.yml,内容如下:
spring:
application:
name: api-gateway
server:
port: 2006
zuul:
routes:
feign-consumer-hello:
path: /feign-consumer/hello/**
serviceId: feign-consumer-hello
feign-consumer:
path: /feign-consumer/**
serviceId: feign-consumer
eureka:
client:
service-url:
defaultZone: http://localhost:1111/eureka/
这个时候我们就可以确保先加载feign-consumer-hello的匹配规则,后加载feign-consumer的匹配规则。
上文我们说了一个zuul.ignored-services=hello-service属性可以忽略掉一个服务,不给某个服务设置映射规则,这个配置我们可以进一步细化,比如说我不想给/hello接口路由,那我们可以按如下方式配置(后面我都用yaml配置):
zuul:
ignored-patterns: /**/hello/**
此时访问/hello接口就会报404错误,同时我们也可以看到后台打印如下日志:
此外,我们也可以统一的为路由规则增加前缀,设置方式如下:
zuul:
prefix: /myapi
此时我们的访问路径就变成了http://localhost:2006/myapi/feign-consumer/hello1。
一般情况下API网关只是作为系统的统一入口,但是有的时候我们可能也需要在API网关上做一点业务逻辑操作,比如我现在在api-gateway项目中新建如下Controller:
@RestController
public class HelloController {
@RequestMapping("/local")
public String hello() {
return "hello api gateway";
}
}
我希望用户在访问/local时能够自动跳转到这个方法上来处理,那么此时我们需要用到Zuul的本地跳转,配置方式如下:
zuul:
prefix: /myapi
ignored-patterns: /**/hello/**
routes:
local:
path: /local/**
url: forward:/local
此时访问http://localhost:2006/myapi/local结果如下:
我们在使用Nginx的时候,会涉及到一个请求头信息的配置,防止页面重定向后跳转到上游服务器上去,这个问题在Zuul中一样存在,假设我的feign-consumer中提供了一个接口/hello4,当访问/hello4接口的时候,页面重定向到/hello,默认情况下,重定向的地址是具体的服务实例的地址,而不是API网关的跳转地址,这种做法会暴露真实的服务地址,所以需要在Zuul中配置,配置方式很简单,如下:
zuul:
add-host-header: true
表示API网关在进行请求路由转发前为请求设置Host头信息。
默认情况下,敏感的头信息无法经过API网关进行传递,我们可以通过如下配置使之可以传递:
zuul:
routes:
feign-consumer:
sensitiveHeaders:
在Zuul中,Ribbon和Hystrix的配置还是和之前的配置方式一致,这里我就不赘述了,如果我们想关闭Hystrix重试机制,可以通过如下方式:
关闭全局重试机制:
zuul:
retryable: false
关闭某一个服务的重试机制:
zuul:
routes:
feign-consumer:
retryable: false
关于Zuul中路由的配置细节我们就说到这里,有问题欢迎讨论。以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
来源:http://blog.csdn.net/u012702547/article/details/78399406?utm_source=tuicool&utm_medium=referral
猜你喜欢
- spring和mybatis整合整合思路需要spring通过单例方式管理SqlSessionFactory。spring和mybatis整合
- 大部分app打开pdf文件是通过intent调起手机中能打开pdf文件的工具,来查看pdf文件,如果需求是,用户在app内下载好pdf文件后
- 在写程序的时候,有时候可能需要设置小数的位数,那么java中有哪几种保留小数位数的方法呢?本文以两位小数为例给出四种方法。package C
- 1. 前言对于写Crud的老司机来说时间非常宝贵,一些样板代码写不但费时费力,而且枯燥无味。经常有小伙伴问我,胖哥你怎么天天那么有时间去搞新
- 一、什么是内存泄露?Java使用有向图机制,通过GC自动检查内存中的对象(什么时候检查由虚拟机决定),如果GC发现一个或一组对象为不可到达状
- 1.添加引用工具箱---右键---选择项--COM组件--Adobe PDF Reader2.使用方法OpenFileDialog open
- 封面图下个季度的目标是把前端监控相关的内容梳理出来,梳理出来之后可能会在公司内部做个分享~Flutter应用程序既括代码也包括一些其他的资产
- SpringAOP获取方法参数上的注解一、示例① 如下代码,自定义一个参数注解@Test,并将其使用到方法参数上,用于标注需要检验的参数/*
- 一.类与接口的区别类:描述了一个实体,包括实体的状态,也包括实体可能发出的动作。接口:定义了一个实体可能发出的动作。但是只是定义了这些动作的
- 介绍Dubbo 是一款高性能、轻量级的 Java RPC 框架,由阿里巴巴开源并贡献至 Apache 基金会。它能够提供服务的注册与发现、负
- 在Android开发中我们经常使用MediaPlayer来播放音频文件,但是MediaPlayer存在一些不足,例如:资源占用量较高、延迟时
- 1. 实现原理将key映射到 2^32 - 1 的空间中,将这个数字的首尾相连,形成一个环计算节点(使用节点名称、编号、IP地址)的hash
- 1、jdbc1) 含义:JDBC是java语言连接数据库,Java Date Base Connectivity2) jdbc的本质:在编程
- 本文实例为大家分享了Android实现可折叠式标题栏的具体代码,供大家参考,具体内容如下先看效果图:一、实现步骤:1、布局文件<?xm
- 一、基本概念C#只有两种数据类型:值类型和引用类型值类型在线程栈分配空间,引用类型在托管堆分配空间值类型转为引用类型称成为装箱,引用类型转为
- ReentrantLock锁ReentrantLock是Java中常用的锁,属于乐观锁类型,多线程并 * 况下。能保证共享数据安全性,线程间有
- 说明:当程序中出现频繁变化的数据时,如果采用认为的方式进行修改并且编译打包则会导致代码的耦合性较高,不便于维护!所以能否为属性动
- 前言我们都知道memberwiseclone 会将浅克隆。什么是浅克隆?如何深克隆呢?正文public class good{
- spring security中遇到的问题1.An Authentication object was not found in the S
- 新手当在一个类文件中进行了一些操作之后,会造成sout快捷命令无法自动生成。比如操作了import引入其它包之后。主要是对IDEA操作的不熟