Spring Cloud之微服务网关Zuul
服务网关概述
Spring Cloud的网关组件可以使用Zuul与Gateway,早期使用Zuul,后来spring出了自己的网关组件Gateway。
微服务网关Zuul、Gateway是介于客户端和服务器端之间的中间层,所有的外部请求都会先经过网关这一层。API的实现方面更多的考虑业务逻辑,而安全、性能、监控交由网关来做。所以,微服务网关就是一个系统,通过暴露该微服务网关系统,提供相关功能。
微服务网关Zuul
Spring Cloud Zuul是整合Netflix公司的Zuul开源项目实现的微服务网关,它实现了请求路由、负载均衡、校验过虑等功能。
使用场景
请求鉴权:一般在pre类型,如果发现没有权限,直接拦截
异常处理:一般会在error类型和post类型过滤器中结合来处理
服务调用时长统计:pre和post结合使用
Zuul的基本使用
引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
标识Zuul网关
在启动类上使用@EnableZuulProxy注解标识此工程为Zuul网关
@SpringBootApplication
@EnableZuulProxy
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
路由配置
server:
port: 8888
zuul:
routes:
zull-service: #路由名称,名称任意,保持所有路由名称唯一
path: /zull/** #匹配访问路径
#serviceId: zull-service #指定服务id,网关会从Eureka中找到服务的ip和端口,服务有多个实例时,进行动态路由
url: http://localhost:9999 #指定url,映射路径对应的实际url地址
strip-prefix: false #true:代理转发时去掉前缀,false:代理转发时不去掉前缀 如:请求zull/test true则代理转发到:/test false:则代理转发到:zull/test
sensitiveHeaders: #敏感头设置,默认会过虑掉cookie,设置为空表示不过虑 默认zuul会屏蔽cookie,cookie不会传到下游服务,设置为空则取消默认的黑名单,如果设置了具体的头信息则不会传到下游服务
ignoredHeaders: #可以设置过虑的头信息,默认为空表示不过虑任何头
路由配置简化
大多数情况下, 路由名称和服务名会写成一样的。因此Zuul提供了一种简化的配置语法: zuul.routes.<serviceId>=<path>
zuul:
routes:
zull-service: #路由名称,名称任意,保持所有路由名称唯一
path: /zull/** #匹配访问路径
url: http://localhost:9999 #指定url,映射路径对应的实际url地址
# 简化
zuul:
routes:
zull-service: /zull/**
Zuul的默认路由规则:
默认情况下,所有服务的映射路径就是服务名本身。如服务:zull-service,则默认映射路径就是: /zull-service/**
网关路由转发测试
新建一个工程项目,用于测试。
server:
port: 9999
servlet:
context-path: /
@RestController
@RequestMapping("/zull")
public class TestController {
@RequestMapping("/test")
public String zullTest(){
return "Hello Zull";
}
}
直接访问服务
通过网关路由转发访问
过虑器
Zuul的核心就是过虑器,通过过虑器实现请求过虑,身份校验等。自定义过虑器需要继承 ZuulFilter,ZuulFilter是一个抽象类,需要覆盖它的四个方法
1、 shouldFilter:返回一个Boolean值,判断该过滤器是否需要执行。返回true表示要执行此过虑器,否则不执行。
2、 run:过滤器的业务逻辑。
3、 filterType:返回字符串代表过滤器的类型,如下 pre:请求在被路由之前执行 routing:在路由请求时调用 post:在routing和errror过滤器之后调用 error:处理请求时发生错误调用
4、 filterOrder:此方法返回整型数值,通过此数值来定义过滤器的执行顺序,数字越小优先级越高。
自定义过滤器
测试过虑所有请求,判断是否有某头信息
@Component
public class ZullFilterTest extends ZuulFilter {
/**
* 指定过虑器的类型
*
* 四种类型:
* pre:请求在被路由之前执行
* routing:在路由请求时调用
* post:在routing和errror过滤器之后调用
* error:处理请求时发生错误调用
*
* @return
*/
@Override
public String filterType() {
return "pre";
}
/**
* 过虑器序号,越小越被优先执行
* int值定义过滤器的执行顺序,数值越小优先级越高
*
* @return
*/
@Override
public int filterOrder() {
return 0;
}
/**
* 返回true表示要执行此过虑器
*
* @return
*/
@Override
public boolean shouldFilter() {
return true;
}
/**
* 过虑器的内容
* <p>
* 过虑所有请求,判断头部信息是否有SSO-COOKIE,如果没有则拒绝访问,否则转发
*
* @return
* @throws ZuulException
*/
@Override
public Object run() throws ZuulException {
// RequestContext用于在过滤器之间传递消息, 数据保存在每个请求的ThreadLocal中,是线程安全的
RequestContext requestContext = RequestContext.getCurrentContext();
//得到request
HttpServletRequest request = requestContext.getRequest();
//得到response
HttpServletResponse response = requestContext.getResponse();
//得到SSO-COOKIE头
String authorization = request.getHeader("SSO-COOKIE");
if (StringUtils.isEmpty(authorization)) {
//拒绝访问
requestContext.setSendZuulResponse(false);
//设置响应代码
requestContext.setResponseStatusCode(200);
//构建响应的信息
JSONObject responseResult = new JSONObject();
responseResult.put("code", 0);
responseResult.put("msg", "拒绝访问");
//转成json
String jsonString = JSON.toJSONString(responseResult);
requestContext.setResponseBody(jsonString);
//转成json,设置contentType
response.setContentType("application/json;charset=utf-8");
return null;
}
return null;
}
}
过滤器执行生命周期
正常流程
请求先经过pre类型过滤器,然后到达routing类型进行路由,请求就到达真正的服务提供者,执行请求返回结果后,会到达post过滤器,最后返回响应。
异常流程
如果error过滤器出现异常,最终也会进入POST过滤器,而后返回响应。
如果POST过滤器出现异常,会跳转到error过滤器,但是与pre和routing不同的是,请求不会再到POST过滤器了
执行测试
未加入头:SSO-COOKIE
加入头:SSO-COOKIE
Zuul进行请求转发的时候,会把header清空,为了传递原始的header信息到最终的微服务,需要另外配置
zuul.routes.xxx.sentiviteHeaders: #将指定路由的敏感头设置为空
zuul.routes.xxx.customSensitiveHeaders: true #对指定路由开启自定义敏感头
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/137042.html