spring cloud 入门系列六:使用Zuul 实现API网关服务「建议收藏」

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

大家好,又见面了,我是全栈君。

 

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

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

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

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

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

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

一、构建网关,配置路由

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

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

  spring cloud 入门系列六:使用Zuul 实现API网关服务「建议收藏」

代码实现步骤:

  1. 新建maven工程api-gateway
  2. 修改POM文件
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.sam</groupId> <artifactId>api-gateway</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.1.RELEASE</version> </parent> <properties> <javaVersion>1.8</javaVersion> </properties> <!-- 使用dependencyManagement进行版本管理 --> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Camden.SR6</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- 引入zuul依赖 , 它依赖了spring-boot-starter-actuator/spring-boot-starter-hystrix/spring-boot-starter-ribbon--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zuul</artifactId> </dependency> </dependencies> </project>

  3. 新建启动类
    /** * @EnableZuulProxy 开启Zuul 的API网关服务功能 * */ @EnableZuulProxy @SpringCloudApplication public class GateWayApp { public static void main(String[] args) { SpringApplication.run(GateWayApp.class, args); } }

  4. 新建application.properties
    server.port=5555 spring.application.name=api-gateway #增加路由规则的配置 #通过zuul.routes.<route>.path和zuul.routes.<route>.url进行配置,<route>为路由的名字,可以任意指定,但是一组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

     

  5. 测试,启动eureka、hello-service、feign-consumer以及本次新加的api-gateway服务,然后访问http://localhost:5555/api-a/feign-consumerspring cloud 入门系列六:使用Zuul 实现API网关服务「建议收藏」

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

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

二、面向服务的路由

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

  1. 修改POM文件,引入Eureka依赖
    <!-- 引入eureka依赖 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency>

  2. 修改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也能实现功能,但是它不能进行正常的负载均衡和容错保护。

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

    spring cloud 入门系列六:使用Zuul 实现API网关服务「建议收藏」

    访问成功。

 三、服务路由的默认规则

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

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

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

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

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

然后页面访问验证

spring cloud 入门系列六:使用Zuul 实现API网关服务「建议收藏」

spring cloud 入门系列六:使用Zuul 实现API网关服务「建议收藏」

访问成功。

 

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

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

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

 四、请求过滤

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

修改api-gateway:

  1. 新增过滤器类
    /** * 继承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; } }

  2. 修改启动类
    /** * @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); } }

  3. 测试
    1. )访问http://localhost:5555/hello-service/hello,访问失败
      1. spring cloud 入门系列六:使用Zuul 实现API网关服务「建议收藏」

         

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

      spring cloud 入门系列六:使用Zuul 实现API网关服务「建议收藏」

       

 

修改后的代码结构:

spring cloud 入门系列六:使用Zuul 实现API网关服务「建议收藏」

 

 五、拓展延伸

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

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

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

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

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/120905.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • DirectByteBuffer_bytebuffer.get

    DirectByteBuffer_bytebuffer.getByteBuffer是NIO里用得最多的Buffer,它包含两个实现方式:HeapByteBuffer是基于Java堆的实现,而DirectByteBuffer则使用了unsafe的API进行了堆外的实现。这里只说HeapByteBuffer。在NIO中,数据的读写操作始终是与缓冲区相关联的.读取时信道(SocketChannel)将数据读入缓冲区,写入时首先要将发送的数据

  • 单片机0~10v模拟输出_单片机控制三相直流电机

    单片机0~10v模拟输出_单片机控制三相直流电机写在前面承接上文,本次主要设计就是用的是MSP430F249的主控,文末附上下载链接完成效果注意事项三个时钟都要进行设置,确保时钟为8M方可正常使用我就不多说了直接贴代码吧测频串口发送机oled.c////////////////////////////////////////////////////////////////////////////////// //———————————————-

  • JS查找数组中是否包含某个元素或对象「建议收藏」

    JS查找数组中是否包含某个元素或对象「建议收藏」做业务需求时遇到一个功能模块需要动态增删数组对象,需求本身完成不难,但是写出来的代码我总感觉很冗余,于是我在网上找了很久,看有没有现成的轮子可以使用,最终找到了es6中的一个方法将其记录在此,方便以后自己翻阅查找对数组元素进行增删//e是你要判断是否在这个数组里的元素letarr=[‘1′,’2′,’3′,’4’]letarrIndex=arr.indexOf(e)i…

    2022年10月18日
  • 基于ossec logstash es大数据安全关联分析

    基于ossec logstash es大数据安全关联分析

  • centos7安装vsftp配置虚拟用户「建议收藏」

    centos7安装vsftp配置虚拟用户「建议收藏」安装前的准备关闭防火墙或者开端口权限。一般是firewalld或者iptables。systemctlstopfirewalldsystemctldisablefirewalld关闭sellinux立即关闭setenforce0重启也关闭vi/etc/selinux/config修改SELINUX=disabled查看是否关闭get

  • pvzβ版下载_掌上生活app下载安装

    pvzβ版下载_掌上生活app下载安装环境要求HttpRunner是一个基于Python开发的测试框架,可以运行在macOS、Linux、Windows系统平台上。这里使用macOS系统进行演示对于python版本要求:py

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号