Spring Cloud入门之Zuul

2024-06-10 02:18
文章标签 java 入门 spring cloud zuul

本文主要是介绍Spring Cloud入门之Zuul,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原文链接:http://www.dubby.cn/detail.html?id=9009

网关(Gateway)

首先需要考虑,为什么会有网关这个东西呢?他是个什么东西?

经过之前的学习,我们脑海中复现的整个Spring Cloud大概是有服务注册中心(Eureka Server),服务(Eureka Client,Ribbon,Feign,Hystrix等),其中服务之间互相调用,呈网状结构,大致如下图所示:

我们先考虑一下负载均衡这一层,一般这一层都会是一些硬件负载均衡或者软件负载均衡组成,常见的有F5、Nginx(或者Openresty,支持Lua扩展)等。这有一个缺点,就是路由需要手动配置,或者是写个扩展,提供一个管理后台来配置路由关系,其实本质是一样的。这个到后期往往比较难以维护(并不是不可维护,其实这种方式我所知道的很多公司都是这么做的)。

再考虑一个问题,如果你的系统需要用户登录才可以访问某些服务,那么用户的登录状态解析该由谁来负责呢?你的请求希望加密,这种逻辑该由谁来做呢?我们可以在每个服务里做,用户登录态解析,做请求加密。不过,缺点很明显,不统一以后逻辑改变,或者升级难度太大,需要每个服务来配合(这点笔者深有体会)。

为了解决上述问题,API网关应运而生。这是一个景点的Facade模式,是整个微服务系统的门面。他是怎么解决的这些问题的呢?

  • 和Eureka结合,自动维护服务信息,减少手工配置
  • 对于签名,安全校验等,可以使用Zuul提供的Filter机制实现

快速入门

搭建项目

前提是你已经在本地运行起来eureka-server,demo-service,ribbon-consumer或者feign-consumer。

名字就叫Zuul吧,依赖如下:

    <dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-zuul</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka</artifactId></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>Brixton.SR5</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>

在启动类上修饰:

@EnableZuulProxy
@SpringCloudApplication
public class Application {public static void main(String[] args) {new SpringApplicationBuilder(Application.class).web(true).run(args);}
}

创建application.properties:

spring.application.name=api-gateway
server.port=5555zuul.routes.a.path=/a/**
zuul.routes.a.url=ribbon-consumerzuul.routes.b.path=/b/**
zuul.routes.b.url=feign-consumereureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/

然后启动。

面向服务的路由

你访问http:localhost:5555/a/hello的时候,这个URL符合/a/**的规则,所以被转发给ribbon-consumer,这个服务实例的信息会从eureka-server上获取,不需要自己配置服务信息。

通过这种方式,我们极大的减少配置信息,让维护变得简单。

请求过滤

@Component
public class AccessFilter extends ZuulFilter {private static final Logger logger = LoggerFactory.getLogger(AccessFilter.class);@Overridepublic String filterType() {return "pre";}@Overridepublic int filterOrder() {return 0;}@Overridepublic boolean shouldFilter() {return true;}@Overridepublic Object run() {logger.info("AccessFilter run");RequestContext requestContext = RequestContext.getCurrentContext();HttpServletRequest httpServletRequest = requestContext.getRequest();logger.info(httpServletRequest.getRequestURI());Object accessToken = httpServletRequest.getParameter("accessToken");if (accessToken == null) {requestContext.setSendZuulResponse(false);requestContext.setResponseStatusCode(401);return null;} else {}logger.info("access token ok");return null;}
}

简单解释一下上面的代码:

  • filterType:过滤器的类型,pre代表请求在被路由之前执行
  • filterOrder:过滤器的执行顺序,根据这个返回值来依次执行
  • shouldFilter:判断是否需要被过滤
  • run:过滤的具体逻辑,这里通过requestContext.setSendZuulResponse(false);来过滤请求,不对骑进行路由,通过requestContext.setResponseStatusCode(401);设置返回状态码,也可以通过requestContext.setResponseBody(body);来设置内容

这样的话,你需要访问http:localhost:5555/a/hello?token=abc才能正确返回,不然的话,只能得到一个401的错误码。

再谈服务路由

忽略服务

上文提过的,面向服务的路由可以这么配置:

zuul.routes.a.path=/a/**
zuul.routes.a.url=ribbon-consumerzuul.routes.b.path=/b/**
zuul.routes.b.url=feign-consumer

但是,其实服务的serviceId,Zuul是可以通过eureka-server拿到的,服务信息也是可以拿到的,所以Zuul提供了另一种更为方便的路由规则,也就是path的前缀使用serviceId,假设serviceId为hello-service:

zuul.routes.hello-service.path=/hello-service/**
zuul.routes.hello-service.url=hello-service

对于这样的配置,其实就是Zuul默认的路由规则,也就是说我们根本不需要配置这一条,Zuul也可以帮我们实现。

这样会有个问题,有部分服务不希望对外开放,也就是不希望被路由到,那么我们可以选择忽略他,zuul.ignored-services=*的意思是忽略所有的路由,也就是禁用了Zuul帮你自动路由,也可以配置serviceId,多个用逗号隔开。

服务路径匹配

上面用的一直都是zuul.routes.hello-service.path=/hello-service/**这种形式的路径,那么这个代表什么意思呢?

通配符说明
?匹配任意单个字符
*匹配任意数量的字符
**匹配任意数量的字符,支持多及目录

忽略表达式

还可以设置一个被路由忽略的表达式,也就是不被路由,那就是zuul.ignored-patterns

如果你不希望/hello被路由,你可以这么设置:

zuul.ignored-patterns=/**/hello/**

这个配置是会对所有的路由生效的,所以不要忽略了不该忽略的URL。

这篇关于Spring Cloud入门之Zuul的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1046958

相关文章

SpringBoot中六种批量更新Mysql的方式效率对比分析

《SpringBoot中六种批量更新Mysql的方式效率对比分析》文章比较了MySQL大数据量批量更新的多种方法,指出REPLACEINTO和ONDUPLICATEKEY效率最高但存在数据风险,MyB... 目录效率比较测试结构数据库初始化测试数据批量修改方案第一种 for第二种 case when第三种

Java docx4j高效处理Word文档的实战指南

《Javadocx4j高效处理Word文档的实战指南》对于需要在Java应用程序中生成、修改或处理Word文档的开发者来说,docx4j是一个强大而专业的选择,下面我们就来看看docx4j的具体使用... 目录引言一、环境准备与基础配置1.1 Maven依赖配置1.2 初始化测试类二、增强版文档操作示例2.

一文详解如何使用Java获取PDF页面信息

《一文详解如何使用Java获取PDF页面信息》了解PDF页面属性是我们在处理文档、内容提取、打印设置或页面重组等任务时不可或缺的一环,下面我们就来看看如何使用Java语言获取这些信息吧... 目录引言一、安装和引入PDF处理库引入依赖二、获取 PDF 页数三、获取页面尺寸(宽高)四、获取页面旋转角度五、判断

Spring Boot中的路径变量示例详解

《SpringBoot中的路径变量示例详解》SpringBoot中PathVariable通过@PathVariable注解实现URL参数与方法参数绑定,支持多参数接收、类型转换、可选参数、默认值及... 目录一. 基本用法与参数映射1.路径定义2.参数绑定&nhttp://www.chinasem.cnbs

JAVA中安装多个JDK的方法

《JAVA中安装多个JDK的方法》文章介绍了在Windows系统上安装多个JDK版本的方法,包括下载、安装路径修改、环境变量配置(JAVA_HOME和Path),并说明如何通过调整JAVA_HOME在... 首先去oracle官网下载好两个版本不同的jdk(需要登录Oracle账号,没有可以免费注册)下载完

Spring StateMachine实现状态机使用示例详解

《SpringStateMachine实现状态机使用示例详解》本文介绍SpringStateMachine实现状态机的步骤,包括依赖导入、枚举定义、状态转移规则配置、上下文管理及服务调用示例,重点解... 目录什么是状态机使用示例什么是状态机状态机是计算机科学中的​​核心建模工具​​,用于描述对象在其生命

Spring Boot 结合 WxJava 实现文章上传微信公众号草稿箱与群发

《SpringBoot结合WxJava实现文章上传微信公众号草稿箱与群发》本文将详细介绍如何使用SpringBoot框架结合WxJava开发工具包,实现文章上传到微信公众号草稿箱以及群发功能,... 目录一、项目环境准备1.1 开发环境1.2 微信公众号准备二、Spring Boot 项目搭建2.1 创建

Java中Integer128陷阱

《Java中Integer128陷阱》本文主要介绍了Java中Integer与int的区别及装箱拆箱机制,重点指出-128至127范围内的Integer值会复用缓存对象,导致==比较结果为true,下... 目录一、Integer和int的联系1.1 Integer和int的区别1.2 Integer和in

SpringSecurity整合redission序列化问题小结(最新整理)

《SpringSecurity整合redission序列化问题小结(最新整理)》文章详解SpringSecurity整合Redisson时的序列化问题,指出需排除官方Jackson依赖,通过自定义反序... 目录1. 前言2. Redission配置2.1 RedissonProperties2.2 Red

IntelliJ IDEA2025创建SpringBoot项目的实现步骤

《IntelliJIDEA2025创建SpringBoot项目的实现步骤》本文主要介绍了IntelliJIDEA2025创建SpringBoot项目的实现步骤,文中通过示例代码介绍的非常详细,对大家... 目录一、创建 Spring Boot 项目1. 新建项目2. 基础配置3. 选择依赖4. 生成项目5.