Spring Cloud(六):服务网关zuul
通过前面几篇文章的介绍,Spring Cloud微服务架构可通过Eureka实现服务注册与发现,通过Ribbon或Feign来实现服务间的负载均衡调用,通过Hystrix来为服务调用提供服务降级、熔断机制避免雪崩效应,通过Spring Cloud Config实现服务配置的集中化管理。微服务架构内部管理的基本组件差不多都已涵盖了,但是我们的服务最终是需要提供给客户端访问的,客户端如何来访问这些微服务,就需要引入一个叫服务网关的组件了。
zuul
zuul是netflix提供的一个基于JVM的路由与服务端负载均衡器。它在客户端与后端服务之间建立了一道关卡,客户端所有请求必须经过zuul转发到后端对应的微服务,返回结果再经由zuul返回给客户端。zuul与Eureka,Config组合的基本结构如图

zuul作为Eureka Client从Eureka Server获取其它微服务的配置信息,从而可以将客户端请求通过Service ID来负载均衡地转发到后端的服务实例,同时也作为Config Client从Config Server获取自身所需的配置信息。
在netflix内部,zuul被用来实现安全认证、动态路由、反向代理、服务迁移、服务削峰、压力测试、金丝雀测试(灰度发布测试)等功能。本文介绍zuul的基本使用与路由规则。
基本使用
创建maven项目 springcloud-zuul
1.pom.xml中引入依赖 spring-cloud-starter-netflix-zuul
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
2.application.yml配置文件中添加必要的配置,主要是eureka客户端配置
spring:
application:
name: zuul-server
server:
port: 8765
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
3.启动类添加注解 @EnableZuulProxy
@SpringBootApplication
@EnableZuulProxy
public class ZuulApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulApplication.class, args);
}
}
一如既往的简单,Spring Cloud之所以流行就是因为它基于Spring Boot将一些通用的功能进行了开箱即用的封装,使得开发者简单几步就能快速集成一个微服务框架。
依次启动前文所创建的springcloud-eureka, springcloud-config, springcloud-eureka-client, springcloud-zuul,http://localhost:8765/hello-service/hello 返回 Hello, welcome to spring cloud. env: hello-service-dev, value: hello-service-dev 可见通过zuul的请求转发到了hello-service。
为了验证zuul转发请求具备负载均衡的能力,可以将springcloud-eureka-client 中的hello接口返回值做一些调整,并改变端口重启一个实例,再次请求http://localhost:8765/hello-service/hello 将能看到返回结果在两者之间切换。
以上配置文件中并没有加任何路由配置,zuul是怎么将请求正确转发到对应的微服务的呢? 请看下面的路由规则。
路由规则
1.默认路由规则
zuul提供了默认的路由规则,不需要任何配置就会默认将注册的服务进行路径映射。我们可以通过actuator提供的接口来查看,在application.yml中添加配置
management:
endpoints:
web:
exposure:
include: "*"
放开actuator的其它接口访问(默认只放开了/info 与/health接口), 浏览器中访问 http://localhost:8765/actuator/routes, 可以看到返回的zuul默认的路由映射关系

zuul默认将 /service-id/** 的请求路由到Service ID(即spring.application.name的值)为 service-id的服务,如 /hello-service/hello,将转发到hello-service服务的/hello接口。
2.自定义路由规则
我们看到zuul的默认路由规则将config-server也映射出来了,对于这类内部服务我们不希望暴露,则可以通过 zuul.ignoredServices 来进行屏蔽,在application.yml配置文件中添加
zuul:
ignored-services: "config-server"
重启,再次查看http://localhost:8765/actuator/routes , config-server已经被屏蔽了。
通过zuul.routes可添加自定义路由,可以有 zuul.routes.{route-name}.path + zuul.routes.{route-name}.serviceId或url 或 zuul.routes.{service-id}: path 两个格式, 如下
zuul:
ignored-services: "config-server"
routes:
hello:
path: /hi/**
serviceId: hello-service
hello-service: /hi2/**
jboost:
path: /jboost/**
url: http://blog.jboost.cn
访问 http://localhost:8765/hi/hello 或 http://localhost:8765/hi2/hello 都将路由到 hello-service的hello接口,访问 http://localhost:8765/jboost/ 将访问到jboost博客首页。添加自定义路由后,默认路由仍然存在, 你仍然可以通过 http://localhost:8765/hello-service/hello 来访问 hello-service的hello接口。
默认的路由规则将Service ID作为匹配路径,看起来有点长,我们想将匹配路径缩短一点,比如hello-service的匹配路径想改为 /hello/**, 而不是/hello-service/**, 如果像上面配置,一个微服务系统可能涉及几十甚至上百个服务,那配置起来将是一场噩梦。别急, zuul提供了 ServiceRouteMapper 接口来解决这一问题,其中 PatternServiceRouteMapper 可以基于正则表达式来进行路由抽取。
创建一个配置类,注入一个 PatternServiceRouteMapper 的bean,如下
@Configuration
public class ZuulConfiguration {
@Bean
public PatternServiceRouteMapper serviceRouteMapper() {
return new PatternServiceRouteMapper(
"(?<name>^.+)-(?<postfix>.+$)",
"${name}");
}
}
该实现将会对所有服务的路由进行调整,service id 形如 name-postfix的匹配路径为 /name/**, 如hello-service 匹配 /hello/**。 如果正则表达式匹配失败,则还是以默认规则进行路由,如果匹配成功,则默认规则失效,但在配置文件中定义的路由仍然有效。上述验证中,你都可以通过 http://localhost:8765/actuator/routes 来查看当前生效的路由。
其它配置
zuul使用Ribbon来定位服务实例,所有请求都在hystrix command里执行,所以在zuul中可以添加Ribbon, Hystrix相关配置(具体参考前面Ribbon、Hystrix相关文章)
- zuul.ignoredPatterns 对某些路径进行屏蔽,如
/**/admin/**将会屏蔽所有路径中包含admin的接口访问 - zuul.sensitiveHeaders 对一些header进行过滤,不传递给后端服务,默认包括Cookie,Set-Cookie,Authorization, 如果要让zuul发送所有header,则需要显式地将sensitiveHeaders置空值
- zuul.prefix 为所有映射添加前缀,如/api, 这样route里配的
/myusers/**就能匹配客户端请求的/api/myusers/**。默认zuul代理在转发时,前缀会被移除,通过设置zuul.stripPrefix=false可不移除
总结
本文简单介绍了zuul的基本使用与路由规则,更高阶的应用我们后面继续。
认真生活,快乐分享
欢迎关注微信公众号:空山新雨的技术空间
获取Spring Boot,Spring Cloud,Docker等系列技术文章

Spring Cloud(六):服务网关zuul的更多相关文章
- Spring Cloud Gateway 服务网关快速上手
Spring Cloud Gateway 服务网关 API 主流网关有NGINX.ZUUL.Spring Cloud Gateway.Linkerd等:Spring Cloud Gateway构建于 ...
- Spring Cloud (13) 服务网关-路由配置
传统路由配置 所谓传统路由配置方式就是在不依赖于服务发现机制情况下,通过在配置文件中具体制定每个路由表达式与服务实例的映射关系来实现API网关对外部请求的路由.没有Eureka服务治理框架帮助的时候, ...
- Spring Cloud (12) 服务网关-基础
通过前几篇介绍,已经可以构建一个简单的微服务架构了,如下图: 通过eureka实现服务注册中心以及服务注册发现,通过ribbon或feign实现服务的消费以及负载均衡,通过spring cloud c ...
- Spring Cloud Gateway服务网关
原文:https://www.cnblogs.com/ityouknow/p/10141740.html Spring 官方最终还是按捺不住推出了自己的网关组件:Spring Cloud Gatewa ...
- Spring Cloud (14) 服务网关-过滤器
Spring Cloud Zuul作为网关所具备的最基本的功能:路由,还具备另外一个核心的功能:过滤器. 过滤器 通过Spring Cloud Zuul实现的路由功能,我们的微服务可以通过统一的API ...
- Spring Cloud 之 服务网关
在微服务架构体系中,使用API 服务网关后的系统架构图如下: API服务网关的主要作用如下: 服务访问的统一入口 服务访问的负载均衡功能 服务访问的路由功能 在SpringCloud中,基于Netfl ...
- spring cloud:服务网关 Spring Cloud GateWay 入门
Spring 官方最终还是按捺不住推出了自己的网关组件:Spring Cloud Gateway ,相比之前我们使用的 Zuul(1.x) 它有哪些优势呢?Zuul(1.x) 基于 Servlet,使 ...
- Spring Cloud 微服务:Eureka+Zuul+Ribbon+Hystrix+SpringConfig实现流程图
相信现在已经有很多小伙伴已经或者准备使用springcloud微服务了,接下来为大家搭建一个微服务框架,后期可以自己进行扩展.会提供一个小案例: 服务提供者和服务消费者 ,消费者会调用提供者的服务,新 ...
- Spring Cloud微服务笔记(二)Spring Cloud 简介
Spring Cloud 简介 Spring Cloud的设计理念是Integrate Everything,即充分利用现有的开源组件, 在它们之上设计一套统一的规范/接口使它们能够接入Spring ...
- Spring Cloud实战之初级入门(六)— 服务网关zuul
目录 1.环境介绍 2.api网关服务 2.1 创建工程 2.3 api网关中使用token机制 2.4 测试 2.5 小结 3.一点点重要的事情 1.环境介绍 好了,不知不觉中我们已经来到了最后一篇 ...
随机推荐
- K8s 实践 | 如何解决多租户集群的安全隔离问题?
作者 | 匡大虎 阿里巴巴技术专家 导读:如何解决多租户集群的安全隔离问题是企业上云的一个关键问题,本文主要介绍 Kubernetes 多租户集群的基本概念和常见应用形态,以及在企业内部共享集群的业 ...
- matlab数组相除
%数组的除法 clear all %清空MATLAB中的数据 a=[ ] b=[ ] c=a./b %a/b 对应位置相除 d=a.\b %b/a e=a./ %数组与常数相除 f=a/ 运行结果如下
- ffmpeg参数编码大全
ffmpeg version N-49044-g89afa63 Copyright (c) 2000-2013 the FFmpeg developers built on Jan 19 2013 2 ...
- java架构之路(多线程)JMM和volatile关键字(二)
貌似两个多月没写博客,不知道年前这段时间都去忙了什么. 好久以前写过一次和volatile相关的博客,感觉没写的那么深入吧,这次我们继续说我们的volatile关键字. 复习: 先来简单的复习一遍以前 ...
- 微信小程序--百度地图坐标转换成腾讯地图坐标
最近开发小程序时出现一个问题,后台程序坐标采用的时百度地图的坐标,因为小程序地图时采用的腾讯地图的坐标系,两种坐标有一定的误差,导致位置信息显示不正确.现在需要一个可以转换两种坐标的方法,经过查询发现 ...
- STM321的SPI驱动遇到的一个坑!!
最近在做项目要用到FATFS文件驱动和SD卡驱动,SD卡驱动我用的是SPI的通信方式,在挂载文件系统是总是挂在失败了,花了一天时间反复检查,才发现SPI在接收时候卡死: 为了寻找问题的原因,整个人都快 ...
- 20191014Java课堂记录
1. Java字段初始化的规律 首先执行类成员定义时指定的默认值或类的初始化块,到底执行哪一个要看哪一个“排在前面”. 其次执行类的构造函数. 类的初始化块不接收任何的参数,而且只要一创建类的对象,它 ...
- java面试题-spring篇
这次是关于spring的面试题,和上次一样依旧挑了几个具有代表性的. 一. 谈谈你对 Spring 的理解 Spring 是一个开源框架,为简化企业级应用开发而生.Spring 可以是使简单的 Ja ...
- SEVERE: Unable to process Jar entry [avassist xxxx.class]
<bean id="sqlSessionTemplate2" class="org.mybatis.spring.SqlSessionTemplate" ...
- [bzoj2115] [洛谷P4151] [Wc2011] Xor
Description Input 第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目. 接下来M 行描述 M 条边,每行三个整数Si,Ti ,Di,表示 Si 与Ti之间存在 一条权值为 ...