路由网关 Zuul
1,什么是路由网关?
- Spring Cloud Zuul 是整合Netflix公司的 Zuul开源项目(官方:https://github.com/Netflix/zuul)
- Zuul 包含了对请求路由和校验过滤两个最主要的功能:
- 其中路由功能负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础,
(一)客户端请求网关/api/product,通过路由转发到 product 服务
(二)客户端请求网关/api/order,通过路由转发到 order 服务
- 而过滤功能则负责对请求的处理过程进行干预,是实现请求校验等功能的基础.
- Zuul 和 Eureka 进行整合,将 Zuul 自身注册为 Eureka 服务治理中的服务,同时从 Eureka 中获得其他微服 务的消息,也即以后的访问微服务都是通过Zuul跳转后获得。
注意:Zuul服务最终还是会注册进Eureka
2,Zuul功能实例
2.1 ,studentservice-cloud-10-zuul-gateway-7001
2.2,配置 pom.xml文件
<dependencies>
<!-- 引入zuul路由网关依赖-->
<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>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
2.3,配置 application.yml 文件
server:
port: 7001 #服务端口
spring:
application:
name: microservice-zuul-gateway
eureka:
client:
register-with-eureka: true # 服务注册开关
fetch-registry: true # 服务发现开关
service-url: # 客户端(服务提供者)注册到哪一个Eureka Server服务注册中心,多个服务用逗号隔开
defaultZone: http://eureka6001.com:6001/eureka,http://eureka6002.com:6002/eureka
instance:
instance-id: ${spring.application.name}:${server.port} # 指定实例ID,就不会显示主机名了
preferIpAddress: true # 访问路径可以显示IP地址
2.4,创建启动类 ZuulServer_7001,添加 @EnableZuulProxy //开启Zuul
package com.asyt.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@EnableZuulProxy // 开启Zuul功能
@SpringBootApplication
public class ZuulServer_7001 {
public static void main(String[] args){
SpringApplication.run(ZuulServer_7001.class,args);
}
}
2.5,测试Zuul是否已被注册
1,启动2 个 Eureka 服务
2,启动服务提供者: studentservice-cloud-08-provider-product-hystrix-8001
3, 启动路由: studentservice-cloud-10-zuul-gateway-7001
4, 效果如下: http://eureka6001.com:6001
5,不用路由直接访问:http://localhost:8001/student/get/1
6,使用路由访问 (注意是 7001 端口), 当前要加上服务名
访问:http://localhost:7001/microservice-product/student/get/1
2.6,路由转发映射配置
- application.yml 追加配置
zuul:
routes:
provider-product: #路由名称,名称任意,路由名唯一
path: /student/** #访问路径
serviceId: microservice-product # 指定服务名称ID,会自动从Eureka中找到此服务的ip和端口
stripPrefix: false # 代理转发时去掉前缀,false:代理转发时不去掉前缀 例如:为true时 请求 /product/get/1,代理转发到/get/1
2.7,测试路由配置功能
- 重启路由:studentservice-cloud-10-zuul-gateway-7001
- 未配置路由转发映射, 通过路由请求方式 :
- http://localhost:7001/microservice-product/student/get/1
- 已配置路由转发映射, 通过路由请求方式 :
- http://localhost:7001/student/get/1
只要接收到/student开头的路径,就会转发到 studentservice-cloud-08-provider-product-hystrix-8001 服务。
3, Zuul过滤器
Zuul核心就是过虑器,通过过虑器实现请求过虑,身份校验等。
3.1自定义过滤器
- 自定义过虑器需要继承 ZuulFilter,ZuulFilter是一个抽象类,需要覆盖它的4个方法,如下:
- filterType:返回字符串代表过滤器的类型,返回值有:
(一) pre:在请求路由之前执行:
(二) route: 在请求路由时调用
(三) post: 请求路由之后调用,也就时route和error过滤之后调用
(四) error: 处理请求发生异常时调用
- filterOrder:此方法返回整型数值,通过此数值来定义过滤器的执行顺序,数字越小优先级越高。
- shouldFilter:返回Boolean值,判断该过滤器是否执行。返回true表示要执行此过虑器,false不执行。
- run:过滤器的业务逻辑。
3.2,自定义过滤器 LoginFilter
package com.asyt.springcloud.filter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
@Component
public class LoginFilter extends ZuulFilter {
Logger logger = LoggerFactory.getLogger(getClass());
@Override
public String filterType() {
return "pre"; //请求路由前调用
}
@Override
public int filterOrder() {
return 1; //int值来定义过滤器的执行顺序,数值越小优先级越高
}
@Override
public boolean shouldFilter() {
return true; //该过滤器是否执行,true执行,false不执行
}
@Override
public Object run() throws ZuulException {
RequestContext context = RequestContext.getCurrentContext();
HttpServletRequest request = context.getRequest();
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;
}
}
3.3 ,测试功能
- 启动2个 eureka
- 启动服务提供者:studentservice-cloud-08-provider-product-hystrix-8001
- 启动路由:studentservice-cloud-10-zuul-gateway-7001
- 通过路由(7001)访问服务提供者:
(一) 不带 token参数访问:http://localhost:7001/student/get/1
(二) 带 token参数访问:http://localhost:7001/student/get/1?token=1
所有spring cloud基础案例都在Git地址