Spring Cloud Zuul中路由配置细节

上篇文章咱们介绍了API网关的基本构建方式以及请求过滤,小伙伴们对Zuul的做用应该已经有了一个基本的认识,可是对于路由的配置咱们只是作了一个简单的介绍,本文咱们就来看看路由配置的其余一些细节。spring


本文是Spring Cloud系列的第二十篇文章,了解前十九篇文章内容有助于更好的理解本文: api

1.使用Spring Cloud搭建服务注册中心
2.使用Spring Cloud搭建高可用服务注册中心
3.Spring Cloud中服务的发现与消费
4.Eureka中的核心概念
5.什么是客户端负载均衡
6.Spring RestTemplate中几种常见的请求方式
7.RestTemplate的逆袭之路,从发送请求到负载均衡
8.Spring Cloud中负载均衡器概览
9.Spring Cloud中的负载均衡策略
10.Spring Cloud中的断路器Hystrix
11.Spring Cloud自定义Hystrix请求命令
12.Spring Cloud中Hystrix的服务降级与异常处理
13.Spring Cloud中Hystrix的请求缓存
14.Spring Cloud中Hystrix的请求合并
15.Spring Cloud中Hystrix仪表盘与Turbine集群监控
16.Spring Cloud中声明式服务调用Feign
17.Spring Cloud中Feign的继承特性
18.Spring Cloud中Feign配置详解
19.Spring Cloud中的API网关服务Zuul缓存


首先咱们来回忆一下上篇文章咱们配置路由规则的那两行代码:服务器

zuul.routes.api-a.path=/api-a/**
zuul.routes.api-a.serviceId=feign-consumer

咱们说当个人访问地址符合/api-a/**规则的时候,会被自动定位到feign-consumer服务上去,不过两行代码有点麻烦,咱们能够用下面一行代码来代替,以下:app

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服务,不为其建立路由规则:url

zuul.ignored-services=hello-service

有的小伙伴可能为有疑问,咱们定义路由规则/api-a/**的时候,为何最后面是两个*,一个可不能够呢?固然能够,不过意义可就不同了,Zuul中的路由匹配规则使用了Ant风格定义,一共有三种不一样的通配符:spa

通配符 含义 举例 解释
? 匹配任意单个字符 /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,内容以下:code

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/f...

通常状况下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/l...结果以下:

图片描述

咱们在使用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中路由的配置细节咱们就说到这里,有问题欢迎留言讨论。

更多JavaEE资料请关注公众号:

图片描述

相关文章
相关标签/搜索