什么是Zuul
Spring Cloud Zuul 是整合Netflix公司的Zuul开源项目,Zuul包含了对请求路由和校验过滤两个最主要的功能:
1. 路由功能负责将外部请求准发到具体的微服务实例上,是实现外部访问统一入口的基础。
客户端请求网关/api/product,通过路由转发到product服务
客户端请求/api/order,通过路由转发到order服务
2.过滤功能则负责对请求的处理过程进行干预,是实现请求校验等功能的基础。
Zuul和Eureka进行整合,将Zuul自身注册为Eureka服务治理中的服务,同时从Eureka中获得其他微服务的消息,也即以后的访问微服务都是通过Zuul跳转后获得。
Zuul路由功能的实现
1. 新建springcloud-zuul-7001
2. 配置pom.xml
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.dsx</groupId>
<artifactId>springcloud-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../springcloud-parent/pom.xml</relativePath>
</parent>
<artifactId>springcloud-zuul-7001</artifactId>
<dependencies>
<!-- 导入Eureka客户端的依赖,将 微服务提供者 注册进 Eureka -->
<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>
<!--springboot web启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
3. 配置application.xml文件
server:
port: 7001
spring:
application:
name: springcloud-zuul-gateway
eureka:
client:
registerWithEureka: true
fetchRegistry: true
serviceUrl:
defaultZone: http://eureka6001.com:6001/eureka,http://eureka6002.com:6002/eureka
instance:
instnceId:${spring.appliction.name}:${server.port}
preferIpAddress: true
4. 编写启动类
package com.dsx;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@SpringBootApplication
@EnableZuulProxy //开启Zuul的功能
public class Zuul_7001App {
public static void main(String[] args) {
SpringApplication.run(Zuul_7001App.class, args);
}
}
5. 测试Zuul是否已被注册
测试Zuul路由服务是否注册进Eureka注册中心
不用路由直接访问http://localhost:8001/product/get/1
使用路由访问(7001端口),当前要加上服务名http://localhost:7001/microservice-product/product/get/1
可以看到两个地址均可以正常访问。
6. 路由转发映射配置
在application.yml配置文件中追加配置
zuul:
routes:
# 路由名称,名称任意,路由名称唯一
provider-product:
#访问路径
path: /product/**
# 指定服务ID,会自动从Eureka中找到此服务的ip和端 口
serviceId: microservice-product
# 代理转发时去掉前缀,false:代理转发时不去掉前缀 例如:为true时 请求 /product/get/1,代理转发到/get/1
stripPrefix: false
# 如果多个服务需要经过路由,则同povider-product方式继续添加,例如:
#provider-order:
#path: /order/**
#serviceId: microservice-order
#stripPrefix: false
7. 测试zuul路由功能
全部启动后,用过路由请求方式进行请求:http://localhost:7001/product/get/1
只要接受到/product开头的路径,就会转发到springcloud-hystrix-provider-8001服务。
Zuul过滤器实例
Zuul核心就是过滤器,通过过滤器实现请求过滤,身份校验等。
自定义过滤器需要继承ZuulFilter,ZuulFilter是一个抽象类,需要覆盖其四个方法。
filterType:返回字符串代表过滤器的类型,
返回值有:
pre: 在请求路由之前执行
route:在请求路由时执行
post:请求路由之后调用,即在route和error过滤器之后调用
error:处理请求发生错误时调用
filterOrder:此方法返回整型数值,通过此数值来定义过滤器的执行顺序,数字越小优先级越高。
shouldFilter:返回Boolean值,判断该过滤器是否执行。true表示要执行此过滤器,false不执行。
run:过滤器的业务逻辑。
1. 自定义过滤器(注意:在类上加@Component注解)
package com.dsx.filter;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
//一定不能忘记
@Component
public class LoginFilter extends ZuulFilter{
Logger logger = LoggerFactory.getLogger(getClass());
@Override
public Object run() throws ZuulException {
RequestContext context = RequestContext.getCurrentContext();
HttpServletRequest request = context.getRequest();
//获取请求参数token的值
String token = request.getParameter("token");
if (token == null) {
logger.warn("此操作需要先登录系统...");
context.setSendZuulResponse(false);// 拒绝访问
context.setResponseStatusCode(200);// 设置响应状态码
try {
//响应结果
context.getResponse().getWriter().write("token is empty");
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
logger.info("ok");
return null;
}
@Override
public boolean shouldFilter() {
System.out.println("该过滤器是否执行,true执行,false不执行====此处返回true");
return true;
}
@Override
public int filterOrder() {
System.out.println("int值来定义过滤器的执行顺序,数值越小优先级越高");
return 1;
}
@Override
public String filterType() {
System.out.println("请求路由前调用---filterType");
return "pre";
}
}
2. 测试功能
启动Eureka服务注册中心,服务提供者springcloud-hystrix-provider-8001,路由springcloud-zuul-7001。通过路由访问服务提供者。
2.1 不带token参数访问:http://localhost:7001/product/get/1
2.2 带token参数访问:http://localhost:7001/product/get/1?token=666
至此,Zuul的简单应用得以实现,如有不足,欢迎指正留言。望不吝赐教!!!