Zuul是spring cloud中的微服务网关。
网关作用
1. 统一入口:未全部为服务提供一个唯一的入口,网关起到外部和内部隔离的作用,保障了后台服务的安全性。
2 .鉴权校验:识别每个请求的权限,拒绝不符合要求的请求。
3. 动态路由:动态的将请求路由到不同的后端集群中。
4. 减少客户端与服务端的耦合:服务可以独立发展,通过网关层来做映射。
5.流量控制
网关: 是一个网络整体系统中的前置门户入口。请求首先通过网关,进行路径的路由,定位到具体的服务节点上。
一、网关实现统一入口转发请求
1、pom 注意添加eureka客户端的依赖
<?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"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>zuil</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>zuil</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR8</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
启动类上加注解
package com.example.zuil;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.cloud.netflix.zuul.EnableZuulServer;
@EnableZuulProxy
//@EnableZuulServer不用/这个,因为它的功能单一
@SpringBootApplication
public class ZuilApplication {
public static void main(String[] args) {
SpringApplication.run(ZuilApplication.class, args);
}
}
关键在于配置文件
server.port=10086
spring.application.name=gateway
eureka.client.service-url.defaultZone=http://127.0.0.1:10010/eureka
zuul.routes.USER-SERVER.path=/USER-SERVER/**
#通配符,匹配到你输入的路径,USER-SERVER为路径识别,识别成功后拉取eureka中对应的service,之后根据/**来匹配
zuul.routes.USER-SERVER.serviceId=USER-SERVER
#zuul.routes.USER-SERVER.stripPrefix=false//前缀去除,没搞懂
zuul.routes.CONSUME-SERVICE.path=/CONSUME-SERVICE/**
#zuul.ignored-services=加上服务名,只能服务间调用访问,不可以直接访问
具体的路径,请求路径为http://localhost:10086/USER-SERVER/hello/1
#zuul.routes.USER-SERVER.serviceId=USER-SERVER
二、过滤器ZuulFilter
作用:
对请求进行权限的鉴定,过滤请求。
四个主要的方法
请求流程:
其中在前置过滤器(pre)做限流和权限管理.
利用前置过滤器 实现简单登录逻辑
1、创建一个过滤器类,实现四种方法,注意添加注解Component
package com.example.zuil.filter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpStatus;
import org.apache.http.protocol.RequestContent;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
@Component
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的作用域是请求获取zuul到返回
RequestContext ctx= RequestContext.getCurrentContext();
//获取request
HttpServletRequest request=ctx.getRequest();
//获取请求参数,判断请求里面是否带有access-token
String token=request.getParameter("access-token");
if (token==null||token.trim().isEmpty()){
//设置拦截
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(HttpStatus.SC_FORBIDDEN);//403拒绝访问
}
return null;
}
}
这样发起请求的时候他就会判断是否有access字段,若没有拒绝访问,
有的话就会允访问。