2021-10-07-----springcloud网关组件ZUUL

介绍

网关组件zuul是springcloud对外访问时的唯一入口程序,提供路由功能,让不同的请求调用不同的后端微服务,也可以实现过滤的功能,进行鉴权工作
zuul也是netflix的组件,停更了。
zuul2netflix在zuul停更之后,开启的新项目,流产了。
springcloud:退出了替代品Gateway

网关功能

  • 路由:网络中端到端,点到点的路径选择
    根据请求的url地址判断匹配这个请求对应的调用微服务是谁,调用该服务
  • 过滤
    非法的,没有满足身份沿着在哪个的请求(鉴权工作),可以拒绝请求后拦截(拦截)
    确实必要的条件,可以在请求来了之后网关给她添加,或者去掉一些请求内容,允许通过调用后端服务(过滤)

搭建网关系统(掌握网关路由规则)

pom文件

<dependencies>
        <!--web应用依赖 starter-web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--eureka-client依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!--zuul网关组件-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
    </dependencies>

application,properties

server.port=8100
#网关组件工程,基本上不需要注册,开启注册,要通过注册的成功失败,初步判断网关启动是否正常
spring.application.name=zuul-service
#抓取是必须的,因为网关的路由,底层本质是调用微服务
#eureka.client.fetch-registry=false
#eureka.client.register-with-eureka=true
eureka.client.service-url.zone=http://localhost:8761/eureka

#zuul的路由相关内容 http://localhost:8100/zuul-major/tedu/aise/v1.0/major/manage/list
#将请求中,所有到达网关的地址 以/zuul-major开始,转发调用major-service
#对网关来讲,cookie头 请求和响应中的,默认是敏感头,请求带不过去,后续认证登录做不了的
zuul.sensitive-headers=
#路由规则
zuul.routes.major.path=/zuul-major/**
zuul.routes.major.service-id=major-service
zuul.routes.teacher.path=/zuul-teacher/**
zuul.routes.teacher.service-id=teacher-service
zuul.routes.class.path=/zuul-class/**
zuul.routes.class.service-id=class-service
zuul.routes.course.path=/zuul-course/**
zuul.routes.course.service-id=course-service
zuul.routes.student.path=/zuul-student/**
zuul.routes.student.service-id=student-service
#class course student
#测试负载均衡 hi-service
zuul.routes.hi.path=/zuul-hi/**
zuul.routes.hi.service-id=hi-service

路由配置规则,是一对key-value表示一个路由规则

  • zuul.routes:表示开始配置zuul路由规则
  • major:自定义的字符串,表示路由规则名称,一对key中的名字必须是保持一致
  • path:路由匹配规则,会将到达网关url地址,匹配这个路径,用到的匹配符号**属于ANT规范
    -
    在这里插入图片描述
    在这里插入图片描述
    请求url一旦匹配到path的值,将会判断当前路由处理
    service-id:后端注册的服务名称,如果path匹配成功,将会把路径中匹配到的值过滤掉(localhost字符串匹配类似)剩余地址拼接到服务名称,底层调用ribbon拦截逻辑,最终访问微服务
    在这里插入图片描述
    进入网关请求,经过匹配,路由之后,最终服务提供者,而且ribbon负载均衡

启动类中

在这里插入图片描述

请求地址,如何到达最后服务提供者

  • 进入网关
  • 匹配path,找到路由规则
  • 过滤path中字符串,拼接service-id服务
  • ribbon负载均衡,替换服务名称
  • 到达服务提供者的某个实例,如果是集群,多次访问会负载均衡

自定义Filter

/*
package cn.tedu.filter;
*/
/**
 * 作为自定义的第一个网关过滤器,
 * 实现需求功能,判断session中是否有teacherId这个域属性
 * 针对请求路径访问/zuul-teacher/
 * 有测通过,允许访问,无则拒绝
 */
/*
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
*/
/**
 * 如果想要让自己的类成为网关过滤器,生效使用,配置2点
 * 1.MyFilter继承网关过滤器抽象类 规范方法开发
 * 2.MyFilter要成为当前springboot容器的一个bean对象
 *//*

@Component
public class MyFilter extends ZuulFilter {
    */
/**
     * 定义当前过滤器的类型,在网关中有4种类型,名字是固定的,四种类型,过滤拦截的时间点条件不同
     * pre
     * route
     * post
     * error
     * 参数是空的
     * @return String类型
     *//*

    @Override
    public String filterType() {
        return "pre";
    }
    @Override
    public int filterOrder() {
        return 0;//Integer.MIN_VALUE--Integer.MAX_VALUE
    }
    @Override
    public boolean shouldFilter() {
        */
/*
           shouldFilter用来判断当前请求是否要进入过滤逻辑
           当前需求定义的判断条件,是请求路径,以/zuul-teacher开始。
           拿到每个请求的uri路径,先有request对象 
           zuul网关中,没有通过方法传递request,我们需要通过容器的上下文对象获取请求响应
         *//*

        //请求上下文,包含了请求和响应的所有内容
        RequestContext currentContext = RequestContext.getCurrentContext();
        HttpServletRequest request = currentContext.getRequest();//把请求参数,详情获取
        HttpServletResponse response = currentContext.getResponse();//设置响应的头,比如乱码
        //直接从请求request中获取uri路径
        String uri = request.getRequestURI();//teacher-zuul/tedu/aise/v1.o/haha
        request.getRequestURL();//http://localhost:8100/teacher/zuul/tedu/aise/v1.o/haha
        return uri.startsWith("/zuul-teacher");
    }
    @Override
    public Object run() throws ZuulException {
        */
/*          1 拿到request response对象
            2 拿到session 获取域属性teacherId
            3 判断是否位空 
                3.1 如果不为空,允许通过,什么都不做
                3.2 为空,说明当前客户端请求没有身份的,拒绝向后调用,返回响应数据
         *//*

        RequestContext currentContext = RequestContext.getCurrentContext();
        HttpServletRequest request = currentContext.getRequest();//把请求参数,详情获取
        HttpServletResponse response = currentContext.getResponse();//设置响应的头,比如乱码
        HttpSession session = request.getSession();
        String teacherId= (String) session.getAttribute("teacherId");
        if(StringUtils.isEmpty(teacherId)){
            //当前身份验证失败 teacherId为空
            currentContext.setSendZuulResponse(false);//当前请求就拦在了这个过滤器
            //返回过滤的响应 使用response
            response.setContentType("application/json;charset=utf-8");
            currentContext.setResponseBody("{\"status\":201,\"msg\":\"当前请求身份验证失败,拒绝访问\"}");
            currentContext.setResponseStatusCode(401);//401表示未认证登录
        }
        return null;//自定义过滤器中,run方法的返回值,没有任何作用
    }
}
*/


版权声明:本文为qq_44494957原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。