详解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错误,同时我们也可以看到后台打印如下日志:

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

此外,我们也可以统一的为路由规则增加前缀,设置方式如下:


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结果如下:

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

我们在使用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,Cloud,Zuul
0
投稿

猜你喜欢

  • Android Studio连接SQLite数据库的登录注册实现

    2023-08-14 11:27:49
  • android获取手机唯一标识的方法

    2022-09-16 15:55:39
  • C#中委托的基础入门与实现方法

    2022-05-24 22:04:24
  • Android图片处理实例分析

    2022-09-10 20:34:50
  • Android触摸及手势操作GestureDetector

    2023-07-31 14:13:42
  • Java Socket编程详解及示例代码

    2022-06-29 07:05:27
  • SpringSecurity构建基于JWT的登录认证实现

    2023-06-14 10:49:02
  • SpringCloud:feign对象传参和普通传参及遇到的坑解决

    2023-02-17 11:18:58
  • android命令行模拟输入事件(文字、按键、触摸等)

    2021-10-30 04:48:06
  • 面试官:java ThreadLocal真的会造成内存泄露吗

    2023-11-18 13:04:56
  • Android usb设备权限查询及自动获取详解流程

    2022-01-12 08:40:39
  • 在Android中使用WebSocket实现消息通信的方法详解

    2022-06-10 06:26:18
  • JAVA对象和字节数组互转操作

    2022-05-06 22:57:28
  • 深入第K大数问题以及算法概要的详解

    2022-05-22 16:52:29
  • Spring MVC4.1服务器端推送实现过程解析

    2021-07-24 14:53:16
  • Java中的InputStreamReader和OutputStreamWriter源码分析_动力节点Java学院整理

    2022-10-13 10:46:53
  • C# 9 新特性——record的相关总结

    2022-01-25 07:33:35
  • 用Java实现简单ATM机功能

    2023-05-10 13:36:03
  • Android 4.4.2 横屏应用隐藏状态栏和底部虚拟键的方法

    2022-07-14 13:19:41
  • Android中使用Toast.cancel()方法优化toast内容显示的解决方法

    2021-12-14 05:17:03
  • asp之家 软件编程 m.aspxhome.com