热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

springcloud使用Zuul实现API网关服务问题

这篇文章主要介绍了springcloud使用Zuul实现API网关服务问题,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下

通过前面几次的分享,我们了解了微服务架构的几个核心设施,通过这些组件我们可以搭建简单的微服务架构系统。比如通过Spring Cloud Eureka搭建高可用的服务注册中心并实现服务的注册和发现;

通过Spring Cloud Ribbon或Feign进行负载均衡;通过Spring Cloud Hystrix进行服务容错保护以避免故障蔓延。微服务搭建好了之后我们肯定会提供给外部系统一些统一的RESTFul API服务接口进行调用,

但是当外部系统调用我们的RESTful API的时候,怎么确定它需要的功能具体是哪个服务提供的呢?这个就涉及到一个路由规则和服务实例列表的维护问题。

这就引入了我们今天的主角--Spring Cloud Zuul,它是基于Netflix Zuul实现的API网关组件。它可以解决两个大问题:

  • 就是我们上面提到的路由规则和服务实例的维护问题
  • 对于一些校验(比如登录校验等)冗余问题。 按照我们的习惯的做法,是在每个服务中都需要加入这些校验,但是这样会导致代码冗余并且维护也比较麻烦,有了Spring Cloud Zuul这个网关服务之后,我们可以将这些共通的校验放到网关里面统一维护。

好,接下来我们就来看下怎么实现这个网关服务。

一、构建网关,配置路由

 这里我们还是需要使用到前面的hello-service和feign-consumer服务。我们之前把feign-consumer作为服务消费者,但是别忘了在eureka体系里面,每个服务既是服务提供者又是服务消费者,所以feign-consumer也是一个服务提供者,并且http://localhost:9001/feign-consumer等接口就是它提供的服务。

接下来我们构建一个网关服务,代码结构如下:

代码实现步骤:

新建maven工程api-gateway

修改POM文件


 4.0.0
 com.sam
 api-gateway
 0.0.1-SNAPSHOT
 
  org.springframework.boot
  spring-boot-starter-parent
  1.5.1.RELEASE
 
 
  1.8
 
 
 
  
   
    org.springframework.cloud
    spring-cloud-dependencies
    Camden.SR6
    pom
    import
   
  
 
 
  
  
   org.springframework.cloud
   spring-cloud-starter-zuul
  
 

新建启动类

/**
 * @EnableZuulProxy 开启Zuul 的API网关服务功能
 *
 */
@EnableZuulProxy
@SpringCloudApplication
public class GateWayApp {

 public static void main(String[] args) {
  SpringApplication.run(GateWayApp.class, args);
 }
}

新建application.properties

server.port=5555
spring.application.name=api-gateway
#增加路由规则的配置
#通过zuul.routes..path和zuul.routes..url进行配置,为路由的名字,可以任意指定,但是一组path和url的路由名要相同
#如下面的例子:所有满足/api-a/** 规则的访问都会被路由转发到//localhost:9001的地址
#也就是说,我们访问http://localhost:5555/api-a/hello的时候,API网关服务就会将该请#求路由到 http://localhost:9001/hello提供的微服务接口上
zuul.routes.api-a.path=/api-a/**
zuul.routes.api-a.url=http://localhost:9001
zuul.routes.api-b.path=/api-b/**
zuul.routes.api-b.url=http://localhost:9090

测试,启动eureka、hello-service、feign-consumer以及本次新加的api-gateway服务,然后访问http://localhost:5555/api-a/feign-consumer

成功访问到了feign-consumer的服务接口--feign-consonsumer。

以上步骤实现了传统路由的配置,这种配置有个大的缺点,就是需要手工在application.properties文件中进行路由规则的配置,当服务很多的时候,维护工作量就会很大。为了减小维护成本,还有另外一种路由--面向服务的路由。

二、面向服务的路由

Spring Cloud Zuul和Eureka进行整合,我们可以让路由的path不是映射具体的url,而是具体的某个服务,而服务的url则交给Eureka服务发现机制自动维护,这类路由就是面向服务的路由。具体代码配置如下:

修改POM文件,引入Eureka依赖


  
   org.springframework.cloud
   spring-cloud-starter-eureka
  

修改application.properties配置文件

server.port=5555
spring.application.name=api-gateway
zuul.routes.api-a.path=/api-a/**
#这里用serviceId代替url,用服务名代替ip+端口号
zuul.routes.api-a.serviceId=hello-service
eureka.client.service-url.defaultZOne=http://localhost:1111/eureka

注意:zuul.routes.api-a.url=hello-service也能实现功能,但是它不能进行正常的负载均衡和容错保护。

测试,访问http://localhost:5555/api-a/hello

访问成功。

 三、服务路由的默认规则

在面向服务的路由中,由于名字是随意起的,那么是不是可以这样:

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

名字就是服务名,其实在实际的应用中,我们往往就是这样命名的。如果有这样的规则的话,那Zuul就可以帮我们默认实现这样的功能,进一步省去了配置的麻烦。

我们来做个实验,将配置文件改为:

server.port=5555
spring.application.name=api-gateway
eureka.client.service-url.defaultZOne=http://localhost:1111/eureka

然后页面访问验证

访问成功。

但是由于默认情况下,Eureka上的服务都会被Zuul创建默认的映射关系来进行路由,使得我们不想对外开放的服务也被外部访问到,这个时候可以通过配置zuul.ignored-services来进行配置不需要自动创建路由的规则。当zuul.ignored-services=*的时候,所有的服务都不会自动创建路由规则,这个时候需要通过前面的配置进行相关路由配置了。

================华丽的分割线===================

前面说了那么多都是围绕一个问题展开的:路由规则和服务实例的维护问题,那么怎么解决第二个问题(校验冗余问题)呢?

 四、请求过滤

为了在API网关中实现对客户端请求的校验,我们可以通过过滤器来实现对请求的拦截和过滤,实现方法比较简单,只需要继承ZuulFilter抽象类并实现其四个方法就行了。

修改api-gateway:

新增过滤器类

/**
 * 继承ZuulFilter,并且实现其4个接口
 *
 * 用来进行请求过滤
 *
 */
public class AccessFilter extends ZuulFilter {
 Logger logger = LoggerFactory.getLogger(AccessFilter.class);
 /* 
  * shouldFilter 判断该过滤器是否需要被执行
  * 
  * 这里直接返回true,表示该过滤器对所有请求都会生效。
  * 实际运用中我们可以利用该函数指定过滤器的有效范围
  */
 @Override
 public boolean shouldFilter() {
  return true;
 }
 /*
  * 过滤器的具体逻辑
  * 
  * 这里我们通过ctx.setSendZuulResponse(false)让zuul过来请求,不对其进行路由
  * 然后通过ctx.setResponseStatusCode(401)设置了返回的错误码
  * 
  */
 @Override
 public Object run() {
  RequestContext cOntext= RequestContext.getCurrentContext();
  HttpServletRequest request = context.getRequest();
  Object accessToken = request.getParameter("accessToken");
  logger.info("send {} request to {}", request.getMethod(),request.getRequestURL().toString());
  if(accessToken == null) {
   context.setSendZuulResponse(false);
   context.setResponseStatusCode(401);
  }
  return null;
 }
 /* filterType 返回过滤器类型
  * 他决定了过滤器在请求的哪个生命周期中执行。这里定义为pre,代表会在请求被路由前执行。
  * 
  * pre:请求执行之前filter 
  * route: 处理请求,进行路由 
  * post: 请求处理完成后执行的filter 
  * error:出现错误时执行的filter
  */
 @Override
 public String filterType() {
  return "pre";
 }
 /* 
  * filterOrder 返回过滤器的执行顺序
  * 
  * 当请求在一个阶段有多个过滤器是,需要根据该方法的返回值来一次执行
  * 
  */
 @Override
 public int filterOrder() {
  return 0;
 }
}

修改启动类

/**
 * @EnableZuulProxy 开启Zuul 的API网关服务功能
 *
 */
@EnableZuulProxy
@SpringCloudApplication
public class GateWayApp {
 //追加bean的是实现
 @Bean
 public AccessFilter accessFilter() {
  return new AccessFilter();
 }
 
 public static void main(String[] args) {
  SpringApplication.run(GateWayApp.class, args);
 }
}

测试

)访问http://localhost:5555/hello-service/hello,访问失败

)访问http://localhost:5555/hello-service/hello?accessToken=token,正常访问

修改后的代码结构:

 五、拓展延伸

其实路由功能在真正运行时,他的路由映射和请求转发都是由几个不同的过滤器完成的。

路由映射主要通过pre类型的过滤器完成,他将请求路径与配置的路由规则进行匹配,找到需要转发的目标地址。

而请求转发的部分则是由route类型的过滤器完成的,对pre类型过滤器获取的路由地址进行转发。

所以,过滤器可以说是Zuul实现API网关功能最为核心的部件,每一个进入Zuul的HTTP请求都会经过一系列的过滤器处理链得到请求响应并返回给客户端。

总结

以上所述是小编给大家介绍的spring cloud 使用Zuul 实现API网关服务问题,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!


推荐阅读
  • 华为云openEuler环境下的Web应用部署实践
    本文详细记录了在华为云openEuler系统上进行Web应用部署的具体步骤,包括配置yum源、安装Apache、MariaDB、PHP及其相关组件,并完成WordPress的安装与配置过程。 ... [详细]
  • 本文深入解析了Spring Cloud路由网关Zuul的核心功能及其典型应用场景。通过对方志朋老师教材的学习和实践,详细探讨了Zuul在微服务架构中的重要作用,包括请求路由、过滤器链管理以及服务动态扩展等关键特性。同时,结合实际案例,展示了Zuul在高并发和复杂业务场景下的应用优势,为读者提供了全面的技术参考。 ... [详细]
  • REST API 时代落幕,GraphQL 持续引领未来
    尽管REST API已广泛使用多年,但在深入了解GraphQL及其解决的核心问题后,我深感其将引领未来的API设计趋势。GraphQL不仅提高了数据查询的效率,还增强了灵活性和性能,有望成为API开发的新标准。 ... [详细]
  • 本文深入探讨了ASP.NET Web API与RESTful架构的设计与实现。ASP.NET Web API 是一个强大的框架,能够简化HTTP服务的开发,使其能够广泛支持各种客户端设备。通过详细分析其核心原理和最佳实践,本文为开发者提供了构建高效、可扩展且易于维护的Web服务的指导。此外,还讨论了如何利用RESTful原则优化API设计,确保系统的灵活性和互操作性。 ... [详细]
  • 一键LNMP配置SSL证书实现全站HTTPS访问
    许多网站搭建者选择了便捷的一键LNMP安装包,但在网站部署完成后,配置SSL证书以支持HTTPS访问是一个不可或缺的步骤。本文将详细介绍如何通过简单的步骤完成这一过程。 ... [详细]
  • SpringBoot底层注解用法及原理
    2.1、组件添加1、Configuration基本使用Full模式与Lite模式示例最佳实战配置类组件之间无依赖关系用Lite模式加速容器启动过程,减少判断配置类组 ... [详细]
  • 本文详细介绍了在PHP中如何获取和处理HTTP头部信息,包括通过cURL获取请求头信息、使用header函数发送响应头以及获取客户端HTTP头部的方法。同时,还探讨了PHP中$_SERVER变量的使用,以获取客户端和服务器的相关信息。 ... [详细]
  • 使用 ModelAttribute 实现页面数据自动填充
    本文介绍了如何利用 Spring MVC 中的 ModelAttribute 注解,在页面跳转后自动填充表单数据。主要探讨了两种实现方法及其背后的原理。 ... [详细]
  • 本文档提供了在Windows 10操作系统中安装Python 3及Scrapy框架的完整指南,包括必要的依赖库如wheel、lxml、pyOpenSSL、Twisted和pywin32的安装方法。 ... [详细]
  • Maven快照版本管理及更新策略详解
    本文深入探讨了Maven中的快照版本管理和更新策略,解释了快照版本与正式版本的区别,并提供了如何配置快照更新策略的方法,以确保项目依赖始终保持最新。 ... [详细]
  • 如何使用Maven将依赖插件一并打包进JAR文件
    本文详细介绍了在使用Maven构建项目时,如何将所需的依赖插件一同打包进最终的JAR文件中,以避免手动部署依赖库的麻烦。 ... [详细]
  • 将XML数据迁移至Oracle Autonomous Data Warehouse (ADW)
    随着Oracle ADW的推出,数据迁移至ADW成为业界关注的焦点。特别是XML和JSON这类结构化数据的迁移需求日益增长。本文将通过一个实际案例,探讨如何高效地将XML数据迁移至ADW。 ... [详细]
  • SpringBoot非官方教程|终章:文章汇总springboot非官方教程,可能最接近于官方的一个教程,大多数案例都来自于官方文档,为了更好的理解,加入了个人的改造。码云下载:htt ... [详细]
  • 洞见RSAC|点击获取企业安全策略“工具包”
    为用户提供安全智 ... [详细]
  • spring cloud微服务实战 pdf_springcloud微服务架构开发实战:常见微服务的消费者
    常见微服务的消费者本节就常见的微服务的消费者进行介绍。在Java领域比较常用的消费者框架主要有HttpClient、Ribbon、Feign等。ApacheHttpClientAp ... [详细]
author-avatar
守护琳的心
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有