Java 微服务之 SpringCloud快速入门day02 (三)Zuul网关,面向服务的路由,Zuul过滤器

Java 微服务之 SpringCloud快速入门day01 (一)系统架构的演变,服务调用方式
Java 微服务之 SpringCloud快速入门day01 (二)初始SpringCloud
Java 微服务之 SpringCloud快速入门day01 (三)Eureka注册中心快速入门
Java 微服务之 SpringCloud快速入门day01 (四)Eureka注册中心高级部分(集群)(高可用)
Java 微服务之 SpringCloud快速入门day02 (一)Hystrix 线程隔离,服务降级
Java 微服务之 SpringCloud快速入门day02 (二)Feign
Java 微服务之 SpringCloud快速入门day02 (三)Zuul网关,面向服务的路由,Zuul过滤器

Java 微服务之 SpringCloud快速入门day02 (三)Zuul网关

一、简介

1、相关概念

官网:https://github.com/Netflix/zuul

在这里插入图片描述
Zuul:维基百科:
电影《捉鬼敢死队》中的怪兽,Zuul,在纽约引发了巨大强乱。
事实上,在微服务架构中,Zuul就是守门的大Boss!一夫当关,万夫莫开!

Zuul是 Netflix开源的微服务网关,它可以和Eureka、Ribbon、Hystrix等组件配合使用。Zuul的核心是一系列的过滤器,这些过滤器可以完成以下功能。

  • 身份认证与安全:识别每个资源的验证要求,并拒绝那些与要求不符的请求。
  • 审查与监控:在边缘位置追踪有意义的数据和统计结果,从而带来精确的生产视图。
  • 动态路由:动态地将请求路由到不同的后端集群。
  • 压力测试:逐渐增加指向集群的流量,以了解性能。
  • 负载分配:为每一种负载类型分配对应容量,并弃用超出限定值的请求。
  • 静态响应处理:在边缘位置直接建立部分响应,从而避免其转发到内部集群。

Spring Cloud对Zuul进行了整合与增强。

目前,Zuul使用的默认HTTP客户端是ApacheHTTP Client,

也可以使用RestClient或者okhttp3.OkHttpClient。

如果想要使用RestClient,可以设置ribbon.restclient.enabled=true;想要使用okhttp3.0kHttpClient,
可以设置rib-bon.okhttp.enabled=true.

网管的核心功能是:过滤和路由

2、Zuul加入后的架构

在这里插入图片描述
不管是来自于客户端(PC或移动端)的请求,还是服务内部调用。

一切对服务的请求都会经过Zuul这个网关,然后再由网关来实现鉴权、动态路由等等操作。

Zuul就是我们服务的统一入口。

二、Zuul快速入门

1、新建工程

填写基本信息:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

2、引入依赖

在这里插入图片描述

<dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
            <version>2.0.1.RELEASE</version>

        </dependency>

</dependencies>
3、创建启动类

在这里插入图片描述
在这里插入图片描述

package com.itzheng;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

@EnableZuulProxy
@SpringBootApplication
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class);
    }
}

4、编写配置文件

在这里插入图片描述
在这里插入图片描述

server:
  port: 10010
zuul:
  routes:
    hehe:
      path: /user-service/**  #设置凡是路径以这个开头路径都配置到8082
      url: http://127.0.0.1:8082
5、启动测试项目

在这里插入图片描述
访问项目http://localhost:10010/user-service/user/9
在这里插入图片描述

6、引入eureka依赖

在这里插入图片描述

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

在application.yml当中配置eureka并完善zuul的请求路径
在这里插入图片描述

server:
  port: 10010
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka
zuul:
  routes:
    haha:
      path: /user-service/**  #设置凡是路径以这个开头路径都配置到8082
      serviceId: user-service

7、重新启动运行

在这里插入图片描述

8、优化application.yml配置文件
server:
  port: 10010
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka
zuul:
  routes:
    user-service: /user-service/**  #设置凡是路径以这个开头路径都配置到8082   键是user-service 值是/user-service/**

凡是访问/user-service/**这个路径的都会访问user-service这个服务
重新运行并访问
在这里插入图片描述
在这里插入图片描述

9、查看Zuul是否可以代理consumer在不配置的情况下直接访问对应的路径:可以直接访问成功( demo):Zuul默认为所有的微服务都配置了对应的映射

在这里插入图片描述

spring:
  application:
    name: gateway
zuul:
  routes:
    user-service: /user/**
  ignored-services:
    - consumer-service

重新运行并访问
在这里插入图片描述
http://localhost:10010/user/user/9

在这里插入图片描述

http://localhost:10010/consumer/consumer/9

在这里插入图片描述

10、设置路由前缀
(1)继续完善application.yml

在这里插入图片描述

zuul:
  routes:
    user-service:
      path: /user/**
      serviceId: user-service
      strip-prefix: false
(2)重新运行并访问

在这里插入图片描述
http://localhost:10010/user/9
在这里插入图片描述

(3)继续简化上述文件

在这里插入图片描述

server:
  port: 10010
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka
spring:
  application:
    name: gateway
zuul:
  routes:
    user-service: /user/**
  ignored-services:
    - consumer-service
  strip-prefix: false

三、Zuul过滤器

Zuul作为网关的其中一个重要功能,就是实现请求的鉴权,
而这个动作我们往往是通过Zuul提供的过滤器来实现的。

1、ZuulFilter

ZuulFilter是过滤器的顶级父类。在这里我们看一下其中定义的4个最重要的方法:

public abstract ZuulFilter implements IZuulFilter{
	
	abstract public String filterType();//过滤器类型
	
	abstract public int filterOrder();//过滤器顺序(值越大优先级越低,值越小优先级越高)

	boolean shouldFilter();//来自IZuulFilter,要不要过滤

	Object run() throws ZuulException;//IZuulFilter

}
  • shouldFilter:返回一个Boolean值,判断i该过滤器是否需要执行。返回true执行,返回false不执行。

  • run过滤器的具体业务逻辑。

  • filterlype:返回字符串,代表过滤器的类型。包含以下4种:

  • pre:请求在被路由之前执行

  • routing :在路由请求时调用

  • post:在routing和errror过滤器之后调用

  • error:处理请求时发生错误调用

  • filterOrder:通过返回的int值来定义过滤器的执行顺序,数字越小优先级越高。

2、过滤器执行生命周期:

这张是Zuul官网提供的请求生命周期图,清晰的表现了一次请求在各个过滤器的执行顺序。

在这里插入图片描述

  • 正常流程:
    。请求到达首先会经过pre类型过滤器,而后到达routing类型,进行路由,请求就到达真正的服务提供者,
    执行请求,返回结果后,会到达post过滤器。而后返回响应。
  • 异常流程
    。整个过程中,pre或者routingi过滤器出现异常,都会直接进入error过滤器,再error处理完毕后,会将请求
    交给POST过滤器,最后返回给用户。

。如果是error过滤器自己出现异常,最终也会进入POST过滤器,而后返回。

。如果是POST过滤器出现异常,会跳转到error过滤器,但是与pre和routing不同的时,请求不会再到达POST
过滤器了。

所有内置过滤器列表
在这里插入图片描述

使用场景

场景非常多:

  • 请求鉴权:一般放在pre类型,如果发现没有访问权限,直接就拦截了
  • 异常处理:一般会在error类型和post类型过滤器中结合来处理。
  • 服务调用时长统计: pre和post吉合使用。
3、自定义过滤器

接下来我们来自定义一个过滤器,模拟一个登录的校验。基本逻辑:如果请求中有access-token参瘦,则认为请求有效,放行。

(1)定义过滤器类

引入依赖
在这里插入图片描述

		<dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>

在这里插入图片描述
在这里插入图片描述

package com.itzheng.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

@Component  //添加该注解以后当前类会自动添加到Spring当中
public class LoginFilter extends ZuulFilter {
    //过滤类型
    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;//前置过滤器
    }
    //过滤级别
    @Override
    public int filterOrder() {
        return FilterConstants.PRE_DECORATION_FILTER_ORDER - 1;
    }
    //是否要过滤
    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() throws ZuulException {
        //获取请求上下文
        RequestContext ctx = RequestContext.getCurrentContext();
        //获取request
        HttpServletRequest request = ctx.getRequest();
        //判断请求参数access-token
        String token = request.getParameter("access-token");
        //判断是否存在
        if(StringUtils.isBlank(token)){
            //不存在,未登录,则拦截
            ctx.setSendZuulResponse(false);//拦截
            //返回状态码403
            ctx.setResponseStatusCode(HttpStatus.FORBIDDEN.value());
        }
        return null;
    }
}

(2)完善application.yml

在这里插入图片描述

server:
  port: 10010
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka
spring:
  application:
    name: gateway
zuul:
  prefix: /api
  routes:
    user-service:
      path: /user/**
      serviceId: user-service
      strip-prefix: false
  ignored-services:
    - comsumer-service


(3)运行并测试

在这里插入图片描述
访问
http://localhost:10010/api/user/9
在这里插入图片描述
访问:http://localhost:10010/api/user/9?access-token=1
在这里插入图片描述

4、负载均衡和熔断

Zuul中默认就已经集成了Ribbon负载均衡和Hystix熔断机制。
但是所有的超时策略都是走的默认值,比如熔断超时时间只有1S,很容易就触发了。
因此建议我们手动进行配置;
在这里插入图片描述

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 6000
ribbon:
  ConnectionTimeout: 500
  ReadTimeout: 2000
  MaxAutoRetriesNextServer: 0 #不重试

ribbon的超时时长,真实值是(read + connect)* 2,必须小于hystrix时长。

计算公式:

1、ribbonTimeout = (ribbonReadTimeout + ribbonConnectTimeout) * (maxAutoRetries + 1) *( maxAutoRetriesNextServer + 1 );

重新运行并测试
在这里插入图片描述
访问http://localhost:10010/api/user/9?access-token=1

在这里插入图片描述

5、Zuul的高可用性

启动多个Zwul服务,自动注册到Eureka,形成集群。如果是服务内部访问,你访问Zuul,自动负载均衡,没问题,但是,Zuul更多是外部访问,PC端、移动端等。他们无法通过Eureka进行负载均衡,那么该怎么办?
此时,我们会使用其它的服务网关,来对Zuul进行代理。比如: Nginx

Eureka、Ribbon、Hystix、Feign、Zuul

spring-cloud-config:统一配置中心,自动去Git拉取最新的配置,缓存。使用Git的Webhook钩子,去通知配置中心,说配置发生了变化,配置中心会通过消息总线去通知所有的微服务,更新配置。

在这里插入图片描述

spring-cloud-bus:消息总线

Spring-cloud-stream:消息通信

spring-cloud-hystrix-dashboard:容错统计,形成图形化界面

spring-cloud-sleuth:链路追踪结合Zipkin

Java 微服务之 SpringCloud快速入门day01 (一)系统架构的演变,服务调用方式
Java 微服务之 SpringCloud快速入门day01 (二)初始SpringCloud
Java 微服务之 SpringCloud快速入门day01 (三)Eureka注册中心快速入门
Java 微服务之 SpringCloud快速入门day01 (四)Eureka注册中心高级部分(集群)(高可用)
Java 微服务之 SpringCloud快速入门day02 (一)Hystrix 线程隔离,服务降级
Java 微服务之 SpringCloud快速入门day02 (二)Feign
Java 微服务之 SpringCloud快速入门day02 (三)Zuul网关,面向服务的路由,Zuul过滤器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员猫爪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值