文章目录
一、服务(zuul)
1. 什么是zuul?
Zuul 是 Netflix 公司开源的一款边缘服务网关(Edge Service Gateway),主要用于在微服务架构中实现动态路由、请求过滤和负载均衡等功能。它可以作为系统的前置网关,将所有外部请求导入到内部服务,并提供一系列的扩展和保护机制。
2. 为什么要zuul?
Zuul 是一个非常有用的边缘服务网关,它提供了路由和转发、负载均衡、安全控制、请求过滤、监控和统计等功能,可以帮助开发人员构建可扩展、高性能和安全的微服务架构。
二、实战
1.新建项目
在springcloud-parent
下搭建zuul工程springcloud-zuul-server
子项目:
springcloud-parent
pom.xml
springcloud-zuul-server //网关服务
springcloud-eureka-server
springcloud-order-server
springcloud-pay-server
springcloud-user-common
springcloud-user-server
2. 导入依赖
导入eureka-client和web基础依赖,和Zuul自身的基础依赖:netflix-zuul:
<dependencies>
<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-web</artifactId>
</dependency>
</dependencies>
3. 配置开开启Zuul
配置类通过 @EnableZuulProxy 注解开启zuul服务功能:
//开启zuul @EnableZuulServer 的增强版 ,一般用这个
@EnableZuulProxy
@EnableEurekaClient
@SpringBootApplication
public class ZuulApp {
public static void main(String[] args) {
SpringApplication.run(ZuulApp.class);
}
}
4. yml文件配置zuul
#注册到EurekaServer
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
instance-id: zuul-server:8765
server:
port: 8765
spring:
application:
name: zuul-server
zuul:
prefix: "/servers" #统一访问前缀
ignoredServices: "*" #禁用掉使用浏览器通过服务名的方式访问服务
routes:
pay-server: "/pay/**" #指定pay-server这个服务使用 /pay路径来访问 - 别名
order-server: "/order/**" #指定order-server这个服务使用 /order路径来访问
5. 测试zuul
浏览器访问:http://localhost:8765/servers/pay/pay/1。
三、自定义zuul的Filter
1. zuul的Filter工作流程
-
首先,请求经过 per 类型过滤器。这些过滤器可以进行一些前置操作,如校验、记录请求信息等。
-
如果前置过滤器通过,请求将继续进入 route 类型过滤器。这些过滤器负责将请求转发到目标服务,执行负载均衡、服务调用等操作。
-
当请求到达目标服务并得到响应后,响应会经过 post类型过滤器。这些过滤器可以进行一些后置操作,如修改响应、记录响应信息等。
-
如果在任何步骤中出现异常或设置了错误状态码,请求将被引导到 error类型过滤器。这个过滤器可以处理异常、记录错误信息等。
2. 自定义Filter
定义一个ZuulFeilter,实现统一的登录检查:
package top.itimmortal.feilter;
@Component
public class ZuulFeilter extends ZuulFilter {
//filter类型 : "pre"前置
@Override
public String filterType() {
return "pre";
}
//执行权重
@Override
public int filterOrder() {
return 0;
}
//返回结果决定 是否要执行run方法
@Override
public boolean shouldFilter() {
HttpServletRequest request = RequestContext.getCurrentContext().getRequest();
String requestURI = request.getRequestURI();
if (requestURI.contains("/login")){
return false;
}
return true;
}
@Override
public Object run() throws ZuulException {
RequestContext currentContext = RequestContext.getCurrentContext();
//获取请求
HttpServletRequest request = currentContext.getRequest();
//获取请求头中的token
String token = request.getHeader("token");
HttpServletResponse response = currentContext.getResponse();
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
//核心业务方法 : 登录检查 , 如果请求头中有token,就是登录成功
if (StringUtils.isBlank(token)){
currentContext.setSendZuulResponse(false);
try {
response.getWriter().println("请先登录");
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}
启动zuul,浏览器访问:http://localhost:8765/servers/pay/pay/1