SpringCloud学习之Zuul路由转发、拦截和熔断处理(七)

Spring Cloud Zuul

服务网关是微服务架构中一个不可或缺的部分。通过服务网关统一向外系统提供REST API的过程中,除了具备服务路由、均衡负载功能之外,它还具备了权限控制等功能。

Spring Cloud Netflix中的Zuul就担任了这样的一个角色,为微服务架构提供了前门保护的作用,同时将权限控制这些较重的非业务逻辑内容迁移到服务路由层面,使得服务集群主体能够具备更高的可复用性和可测试性。

在Spring Cloud体系中, Spring Cloud Zuul 封装了Zuul组件,作为一个API网关,负责提供负载均衡、反向代理和权限认证。

Zuul工作机制

过滤器机制

Zuul的核心是一系列的filters, 其作用类似Servlet框架的Filter,Zuul把客户端请求路由到业务处理逻辑的过程中,这些filter在路由的特定时期参与了一些过滤处理,比如实现鉴权、流量转发、请求统计等功能。Zuul的整个运行机制,可以用下图来描述。

?

过滤器的生命周期

Filter的生命周期有4个,分别是“PRE”、“ROUTING”、“POST”、“ERROR”,整个生命周期可以用下图来表示。

?

基于Zuul的这些过滤器,可以实现各种丰富的功能,而这些过滤器类型则对应于请求的典型生命周期。

PRE: 这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息等。

ROUTING:这种过滤器将请求路由到微服务。这种过滤器用于构建发送给微服务的请求,并使用Apache HttpClient或Netfilx Ribbon请求微服务。

POST:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等。

ERROR:在其他阶段发生错误时执行该过滤器。

除了默认的过滤器类型,Zuul还允许我们创建自定义的过滤器类型。例如,我们可以定制一种STATIC类型的过滤器,直接在Zuul中生成响应,而不将请求转发到后端的微服务。

Zuul中默认实现的Filter

Zuul默认实现了很多Filter,这些Filter如下面表格所示。

类型 顺序 过滤器 功能
pre -3 ServletDetectionFilter 标记处理Servlet的类型
pre -2 Servlet30WrapperFilter 包装HttpServletRequest请求
pre -1 FormBodyWrapperFilter 包装请求体
route 1 DebugFilter 标记调试标志
route 5 PreDecorationFilter 处理请求上下文供后续使用
route 10 RibbonRoutingFilter serviceId请求转发
route 100 SimpleHostRoutingFilter url请求转发
route 500 SendForwardFilter forward请求转发
post 0 SendErrorFilter 处理有错误的请求响应
post 1000 SendResponseFilter 处理正常的请求响应

我们先看看Zuul的工作原理,Zuul是主要起路由转发和路由拦截作用的,这里直接说Zuul和Feign集成的工作流程如下:

?

新建一个Consumer服务消费模块,他的pom.xml添加如下依赖:

?

看看他的主程序:

?

再看看application.yml里的配置文件:

?

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
  instance:
      prefer-ip-address: true
server:
  port: 8768
spring:
  application:
    name: service-ribbon
zuul:
  routes:
    #标识你服务的名字,这里可以自己定义,一般方便和规范来讲还是跟自己服务的名字一样
    service-feign:
      #服务映射的路径,通过这路径就可以从外部访问你的服务了,目的是为了不爆露你机器的IP,面向服务的路由了,给你选一个可用的出来,
      path: /service-feign/**
      serviceId: service-feign

启动我们的注册中心服务、至少一个服务提供者、启动Feign服务消费者、启动我们的Zuul服务消费者,启动正常:

?

打开浏览器器,输入http://localhost:8768/service-feign/hello?name=111这是我们基于Feign的请求转发

?

打开浏览器器,输入http://localhost:8768/service-feign/hi?name=111这是我们基于RestTemplate的请求转发

?

可以看到,我们成功将我们的路由请求转发到Feign服务消费者模块上了,接下来我们要实现以下Zuul对请求的拦截和熔断处理,

拦截就是在转发之前或者之后当请求到达Feign之前做拦截处理,这个是很重要的功能,熔断是当我们路由转发请求的服务不可用该怎么处理响应呢?

一、路由请求拦截

package com.xu.serviceconsumer.component;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

@Component
public class MyTokenFilter extends ZuulFilter {

    private Logger logger = LoggerFactory.getLogger(MyTokenFilter.class);

    //四种类型:pre,routing,error,post
    //pre:主要用在路由映射的阶段是寻找路由映射表的
    //routing:具体的路由转发过滤器是在routing路由器,具体的请求转发的时候会调用
    //error:一旦前面的过滤器出错了,会调用error过滤器。
    //post:当routing,error运行完后才会调用该过滤器,是在最后阶段的
    @Override
    public String filterType() {
        return "pre";
    }

    //自定义过滤器执行的顺序,数值越大越靠后执行,越小就越先执行
    @Override
    public int filterOrder() {
        return 1;
    }

    //控制过滤器生效不生效,可以在里面写一串逻辑来控制
    @Override
    public boolean shouldFilter() {
        return true;
    }

    //执行过滤逻辑
    @Override
    public Object run() {

        RequestContext context = RequestContext.getCurrentContext();
        HttpServletRequest request = context.getRequest();
        String url = request.getRequestURL().toString();
        logger.info("请求URL:"+url);
        String token = request.getParameter("name");
        if (token == null){
            context.setSendZuulResponse(false);
            context.setResponseStatusCode(401);
            context.setResponseBody("there is no request parameter name");

            return null;
        }
        return null;
    }
}

简单看一下代码知道这个过滤器继承了ZuulFilter,在run()方法里日志输出了请求的URL路径和对参数是否有name做了简单的拦截过滤,请求http://localhost:8768/service-feign/hello?

?

可以看到这个Zuul的路由过滤器成功的对这个请求拦截过滤了,最后看一下控制台信息也可以看到成功输出打印了请求的URL

?

二、路由熔断

package com.xu.serviceconsumer.component;

import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

@Component
public class MyFallbackProvider implements FallbackProvider {

    @Override
    public String getRoute() {
        return "service-feign";
    }

    @Override
    public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
        System.out.println("route:"+route);
        System.out.println("exception:"+cause.getMessage());
        return new ClientHttpResponse() {
            @Override
            public HttpStatus getStatusCode() throws IOException {
                return HttpStatus.OK;
            }

            @Override
            public int getRawStatusCode() throws IOException {
                return 200;
            }

            @Override
            public String getStatusText() throws IOException {
                return "ok";
            }

            @Override
            public void close() {

            }

            @Override
            public InputStream getBody() throws IOException {
                return new ByteArrayInputStream(("Sorry, the service "+getRoute()+" is unavailable now.").getBytes());
            }

            @Override
            public HttpHeaders getHeaders() {
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_JSON);
                return headers;
            }
        };
    }
}

注意这里的一段代码

?

我们的熔断路由器配置的是service-feign(就是我们zuul请求路由的这个这个服务),我们关闭这个服务,保留其他之前开启的服务,请求http://localhost:8768/service-feign/hi?name=111

自此,我们可以?

自此,说明我们自定义的熔断器已经起作用了,这课的内容到此为止,下回再见!

原文地址:https://www.cnblogs.com/xulijun137/p/12209745.html

时间: 2024-07-31 05:05:24

SpringCloud学习之Zuul路由转发、拦截和熔断处理(七)的相关文章

SpringCloud学习系列-zuul路由网关

zuul路由网关   1.是什么 Zuul包含了对请求的路由和过滤两个最主要的功能:    其中路由功能负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础而过滤器功能则负责对请求的处理过程进行干预,是实现请求校验.服务聚合等功能的基础. Zuul和Eureka进行整合,将Zuul自身注册为Eureka服务治理下的应用,同时从Eureka中获得其他微服务的消息,也即以后的访问微服务都是通过Zuul跳转后获得. 注意:Zuul服务最终还是会注册进Eureka 提供=代理+路由+过滤

Zuul路由转发规则

定制的路由规则的主要功能: 1.路由表中包含源路径,微服务名称,目标路径 2.Endpoint粒度配置支持 3.路由支持1对1精确路由 4.源路径可以前缀/**格式来模糊路由 5.目标路径可以使用前缀/**格式来装配目标路径 6.保留默认动态路由规则:服务名称/** --> 是否截去前缀 --> 目标路径 7.保留默认动态路由规则是否支持截去前缀的配置参数stripPrefix特性 8.路由规则可以在不重启服务动态更新,这个功能通过外化配置来支持 9.匹配股则采取谁先匹配路由谁,也就是说在路由

SpringCloud 学习(5) --- Zuul(一)基本概念、配置

[TOC] Spring Cloud eureka:注册中心 服务端:提供注册 客户端:进行注册 ribbon:负载均衡(集群) Hystrix:熔断器,执行备选方案 Feign:远程调用 Zuul:网关,统一入口. 1.1.一夫当关,万夫莫开---Zuul网关 网关:程序统一入口.主要功能:服务分发(动态路由),服务鉴权等 Zuul是Netflix孵化的一个致力于"网关"的解决方案的开源组件 Zuul在动态路由.监控.弹性.服务治理.安全等方面有着重要作用. Zuul底层是Servl

SpringCloud学习系列之七 ----- Zuul路由网关的过滤器和异常处理

前言 在上篇中介绍了SpringCloud Zuul路由网关的基本使用版本,本篇则介绍基于SpringCloud(基于SpringBoot2.x,.SpringCloud Finchley版)中的路由网关的过滤器Filter以及异常处理的教程. SpringCloud Zuul Filter 介绍 过滤器概述 Zuul的中心是一系列过滤器,能够在HTTP请求和响应的路由过程中执行一系列操作. 以下是Zuul过滤器的主要特征: 类型:通常在应用过滤器时在路由流程中定义阶段(尽管它可以是任何自定义字

springCloud学习05之api网关服务zuul过滤器filter

前面学习了zuul的反向代理.负载均衡.fallback回退.这张学习写过滤器filter,做java web开发的对filter都不陌生,那就是客户端(如浏览器)发起请求的时候,都先经过过滤器filter做一些相关的校验或业务判断(如登录.权限等),zuul也同样提供了过滤器功能.只要继承ZuulFilter类即可. 通过前文的介绍,我们对于Zuul的第一印象通常是这样的:它包含了对请求的路由和过滤两个功能,其中路由功能负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础:而过

SpringCloud学习记录——网关(Zuul)

在微服务中网关的作用: 1.接收请求——与一般访问相同 2.转发请求 3.请求过滤 网关作用图示: 从上图可以看出,网关的作用实际上是对原始的请求方式插入了一层:在请求中间加入了一层网关,这样使得外部的所有请求都导向网关,再由网关来转发给具体服务处理. 加入网关的优势: 1.请求统一:原本的请求方式可能会因为访问的服务不同,出现访问地址也不同的问题,插入网关之后,访问地址统一指向网关:对于请求方而言,只需要记住一个访问地址就可以了,省事了: 2.通用功能的统一处理:与请求相关的各种操作都可以在网

Idea下SpringCloud2实验(四、Zuul网关实现路由转发和过滤)

一.创建springBoot项目springcloud-zuul-server项目 二.配置文件 1.pom.xml文件 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" x

企业级 SpringCloud (五)路由网关(zuul)

在微服务架构中,需要几个基础的服务治理组件,包括服务注册与发现.服务消费.负载均衡.断路器.智能路由.配置管理等,由这几个基础组件相互协作,共同组建了一个简单的微服务系统.一个简答的微服务系统如下图: Azure (1).png 注意:A服务和B服务是可以相互调用的,作图的时候忘记了.并且配置服务也是注册到服务注册中心的. 在Spring Cloud微服务系统中,一种常见的负载均衡方式是,客户端的请求首先经过负载均衡(zuul.Ngnix),再到达服务网关(zuul集群),然后再到具体的服.,服

SpringCloud系列八:Zuul 路由访问(Zuul 的基本使用、Zuul 路由功能、zuul 过滤访问、Zuul 服务降级)

1.概念:Zuul 路由访问 2.具体内容 在现在为止所有的微服务都是通过 Eureka 找到的,但是在很多的开发之中为了规范微服务的使用,提供有一个路由的处理控制组件:Zuul,也就是说 Zuul 就作为中间的一个代理层出现. 2.1.Zuul 的基本使用 本次使用 Zuul 将访问无安全认证的微服务信息,例如:公司信息就属于无安全认证的微服务: 1. 为了突出 zuul 的功能,建立一个新的主机映射: 127.0.0.1 gateway-9501.com 以后所有的微服务的访问不再直接进行处