本章知识:
1、Zuul 路由网关 简介 及 基本使用
2、Zuul 路由映射配置
3、Zuul 请求过滤配置
Zuul路由网关简介及基本使用
Zuul 是NetFlix开源的微服务网关,它可以结合 SpringCloud 和 Eureka 、Ribbon 、Hystrix 等组件配合使用。
(相关资料:
SpringCloud 基本入门
Eureka 集群 及 自我保护机制
Ribbon 负载均衡 及 Feign消费者调用服务
熔断器Hystrix 及 服务监控Dashboard
Hystrix 集群 及 集群监控 Turbine)
Zuul 的核心是一些列的过滤器,这些过滤器可以完成以下功能 :
-
身份认证与安全:识别每个资源的验证要求,并拒绝那些与要求不符合的请求。
-
审查与监控:在边缘位置追踪有意义的数据和统计结果,从而带来精确的生产视图。
-
动态路由:动态的将请求路由到不同的后端集群。
-
压力测试:逐渐增加指向集群的流量,以了解性能。
-
负载分配:为每一种负载类型分配对应容量,并弃用超出限定值的请求。
-
静态响应处理:在边缘位置直接建立部分响应,从而避免其转发到内部集群。
-
多区域弹性:跨越AWS Region进行请求路由,旨在实现ELB(Elastic Load Balancing)使用的多样化,以及让系统的便越更贴近系统的使用者。
Spring Cloud 对 Zuul 进行了整合与增强 !!!
使用Zuul之后的架构如图所示:
从上图中可以看出,客户端请求微服务时,先经过Zuul之后再请求,这样就可以将一些类似于校验的业务逻辑放到zuul中去完成,而微服务本身只需要关注自己的业务逻辑即可。
Zuul API 路由网关服务简介:
请看上图,这里的API 路由网关服务 由Zuul实现,主要就是 对外提供服务接口的时候,起到了请求的路由和过滤作用,也因此能够隐藏内部服务的接口细节,从来有利于保护系统的安全性;
Zuul 路由配置
我们新建一个module : microservice-zuul-3001
这里我们的zuul也注册到eureka服务里,端口 3001;
我们修改下Hosts,专门为zuul搞个本地域名映射
C:\Windows\System32\drivers\etc
hosts文件 加下:
127.0.0.1 zuul.dj.com
然后pom.xml要加上zuul的依赖:
<!--zuul网关-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
完整 pom.xml 文件
<?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>com.dj</groupId>
<artifactId>springcloud01</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>microservice-zuul-3001</artifactId>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>com.dj</groupId>
<artifactId>microservice-common</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<!-- actuator监控 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- hystrix容错 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!--zuul网关-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.yml文件:
server:
port: 3001
context-path: /
spring:
application:
name: microservice-zuul
eureka:
instance:
instance-id: microservice-zuul:3001
prefer-ip-address: true
client:
service-url:
defaultZone: http://eureka2001.dj.com:2001/eureka/,http://eureka2002.dj.com:2002/eureka/,http://eureka2003.dj.com:2003/eureka/
info:
groupId: com.dj.testSpringcloud
artifactId: microservice-zuul-3001
version: 1.0-SNAPSHOT
userName: http://dj.com
phone: 123
主启动类:ZuulApplication_3001
加下**@EnableZuulProxy**注解
package com.dj.microservicezuul3001;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class}) //不用数据库
@EnableZuulProxy //zuul注解配置
public class MicroserviceZuul3001Application {
public static void main(String[] args) {
SpringApplication.run(MicroserviceZuul3001Application.class, args);
}
}
OK啦 ♪(∇*) ,我们测试下:
启动 Eureka 服务,然后再启动 provide 服务、consumer 服务,以及 zuul网关服务;
这里有两个服务;
我们直接请求:http://localhost:1004/student/list 能获取到数据:
我们用 http://zuul.dj.com:3001/microservice-student/student/list 域名+端口+服务名称+请求地址 也能请求到数据:
说明我们的路由基本配置OK!!
Zuul 映射配置
上面是zuul的简单使用,从接口地址很轻易的就暴露了服务提供者的唯一标识名 microservice-student;
有安全风险!!,所以,我们需要 将真实请求路径隐藏 ;
ignored-services 的作用是将原来的服务提供者唯一标识名禁用;
Prefix 的作用是给服务加前缀;
yml 文件 中添加以下配置:
zuul:
routes: # 所有的路由都配置在这里
studentServer.serviceId: microservice-student
studentServer.path: /studentServer/**
ignored-services: "*"
prefix: /dj # 前缀
OK!配置完毕后可通过以下链接做测试:
http://zuul.dj.com:3001/microservice-student/student/list
http://zuul.dj.com:3001/studentServer/student/list
http://zuul.dj.com:3001/dj/microservice-student/student/list
http://zuul.dj.com:3001/dj/studentServer/student/list
注意:对应的配置会出现上面的错误页面,这是正常现象。
Zuul 请求过滤配置
比如我们登录某个系统 ,需要身份验证,用户名,密码神马的;
我们请求服务,也可以来设置身份验证,也就是过滤非法请求;
Zuul 通过 ZuulFilter 过滤器实现;
注意:ZuulFilter 是一个抽象类,其实现类需要实现4个方法
-
1、shouldFilter:返回一个Boolean值,判断该过滤器是否需要执行。返回true执行,返回false不执行。
-
2、run:过滤器的具体业务逻辑。
-
3、filterType:返回字符串代表过滤器的类型
pre:请求在被路由之前执行 routing:在路由请求时调用 post:在routing和error过滤器之后调用 error:处理请求时发生错误调用
-
4、filterOrder:通过返回的int值来定义过滤器的执行顺序,数字越小优先级越高。
一般具体实现过程:经过 Zuul 服务网关 ,对带来的 token 进行有效性验证;
我们 先定义一个 AccessFilter 类(定义规则):
AccessFilter.java
package com.dj.microservicezuul3001.filter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.apache.log4j.Logger;
;
import javax.servlet.http.HttpServletRequest;
/**
* @author dj
* @company xxx公司
* @create 2019- 11 - 26 - 19:13
*/
public class AccessFilter extends ZuulFilter {
Logger logger=Logger.getLogger(AccessFilter.class);
/**
* 判断该过滤器是否要被执行
*/
@Override
public boolean shouldFilter() {
return true;
}
/**
* 过滤器的具体执行逻辑
*/
@Override
public Object run() throws ZuulException {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
String parameter = request.getParameter("accessToken");
logger.info(request.getRequestURL().toString()+" 请求访问");
if(parameter==null){
logger.error("accessToken为空!");
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(401);
ctx.setResponseBody("{\"result\":\"accessToken is empty!\"}");
return null;
}
// token判断逻辑
logger.info(request.getRequestURL().toString()+" 请求成功");
return null;
}
/**
* 过滤器的类型 这里用pre,代表会再请求被路由之前执行
*/
@Override
public String filterType() {
return "pre";
}
/**
* 过滤器的执行顺序
*/
@Override
public int filterOrder() {
return 0;
}
}
然后再 开启 Filter 配置(使用规则):
ZuulConfig.java
package com.dj.microservicezuul3001.config;
import com.dj.microservicezuul3001.filter.AccessFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author dj
* @company xxx公司
* @create 2019- 11 - 26 - 19:17
*/
@Configuration
public class ZuulConfig {
@Bean
public AccessFilter accessFilter(){
return new AccessFilter();
}
}
浏览器输入地址,进行测试:
没有Token令牌时 :
http://zuul.dj.com:3001/dj/studentServer/student/hystrix
http://zuul.dj.com:3001/dj/studentServer/student/list
有Token令牌时 :
http://zuul.dj.com:3001/dj/studentServer/student/hystrix?accessToken=2
http://zuul.dj.com:3001/dj/studentServer/student/list?accessToken=1
本章小结 :
SpringCloud 的网关 zuul 概念
本章的内容主要是讲:思想的转换 !!!
之前的思想 | 现在的思想 |
---|---|
一个消费者A对于一个服务者B而言,消费者A就是消费者,服务者B就是服务者。 因为是相对而言(有点像相对论的意思哈),消费者在服务者那里进行了一个服务的消费,所以消费者才被称之为消费者。 但是,往往有时候一个消费者其实也可以是一个服务者。 对于另一个消费者C来说:消费者C也可以在服务者A(上述的同一消费者A)中进行一个服务的消费。 | 其实所有的消费者和服务者A,B,C都是相对于zuul 网关而言,都是一个个拥有自己功能的微服务项目。在现在所有的客户端可以通过网关来发送请求,而那个请求是:ip+端口+微服务名。 这样才能指定要访问的微服务,当然还是要通过服务注册中心来获取每一个在注册中心注册过的微服务地址。 |
注意:现在是 zuul网关 去调用每一个微服务的资源 !!!
zuul 网关基本入门
-
zuul 网关的基本配置
1、 导入 pom.xml 依赖
2、 配置 yml 文件
3、 在启动类加上zuul网关注解:@EnableZuulProxy -
zuul 网关的安全措施
1、 改变路由真实路径 - - - > yml 文件添加配置
2、 加上过滤条件认证 - - - >ZuulFilter 过滤器