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版权协议,转载请附上原文出处链接和本声明。