当前位置: 首页 > 科技观察

SpringCloud系列的Zuul网关和Zuul过滤器

时间:2023-03-14 10:03:46 科技观察

Zuul网关什么是Zuul网关?Zuul是SpringCloud全家桶的微服务网关。来自应用程序或网站(第三方)的所有请求都将通过Zuul到达后端Netflix应用程序。作为边界应用程序,Zuul提供动态路由、监控、弹性负载和安全功能。Zuul底层使用filter实现如下功能:认证和安全,识别每一个需要认证的资源,拒绝不符合要求的请求。服务边界的性能检测、跟踪和统计数据,提供准确的生产视图。动态路由,根据需要动态地将请求路由到后端集群。压力测试,逐渐增加集群的流量并了解其性能。减载,为每种类型的请求预先分配容量,并在超过流量时自动丢弃请求。静态资源处理,直接在边界返回某种响应。静态资源处理,直接在Zuul中处理静态资源并响应,而不是将这些请求转发到集群内部。多区域弹性,跨AWS区域路由请求,旨在多样化ELB的使用,并确保边缘位置尽可能靠近用户。ZuulGatewayDemo引入jar包:org.springframework.cloudspring-cloud-starter-eureka1.3.5.RELEASEorg.springframework.cloudspring-cloud-starter-zuul1.3.5.RELEASE配置文件:应用程序.yml。server:port:7004#端口spring:application:name:zuul-getway#服务名称eureka:client:service-url:defaultZone:http://jack:666@loc??alhost:8764/eureka/#需要注册到eureka实例:instance-id:${spring.application.name}:${server.port}zuul:routes:order-service:/od/**#自定义一个服务的路由规则serviceId:order-service#这个配置可以实现负载均衡,默认是轮询#设置部分服务不进行反向代理路由,多个服务用逗号分隔ignored-services:order-service,user-serviceprefix:/api#请求路径的前缀是否检查注册尤里卡。Eureka注册中心访问路径:localhost:7004/api/od/getOrder?token=1235。(后面的token是因为我配置了prefilter,下面会介绍)。Zuul过滤器Zuul有四种过滤器类型,对应于请求生命周期预(pre):在请求被路由之前调用。这个过滤器可以用来实现鉴权,在集群中选择请求的微服务,记录调试等。路由(routing):将请求路由到微服务。用于构建发送到微服务的请求,并使用apachehttpclient或netflixribbon来请求微服务。post(发布):路由到微服务后执行。可用于将标准http标头添加到响应、收集统计信息和指标,以及从微服务向客户端发送响应。error(错误):当其他阶段发送错误时执行此过滤器。注意:除了默认过滤器类型外,Zuul还允许创建自定义过滤器类型。如何禁用过滤器?很简单,只要设置zuul.ClassName.filterType.disable=true就可以禁用SimpleClassName对应的filter。例如:zuul.TokenFilter.pre.disable=true;TokenFilter过滤器可以被禁用。前置过滤器示例:authentication认证。如果参数带有令牌,则允许访问。/***前置过滤器*@AuthorBig.Hu*/@ComponentpublicclassTokenFilterextendsZuulFilter{@OverridepublicObjectrun(){System.err.println("执行前置前置过滤器......");RequestContextcurrentContext=RequestContext.getCurrentContext();HttpServletRequestrequest=currentContext.getRequest();StringBufferrequestURL=request.getRequestURL();System.out.println("requestURL:"+requestURL);//获取参数请求Stringtoken=request.getParameter("token");if(StringUtils.isEmpty(token)){//如果参数为空,过滤请求而不路由它currentContext.setSendZuulResponse(false);//设置errorcode:401currentContext.setResponseStatusCode(HttpStatus.SC_UNAUTHORIZED);currentContext.set("SUCCESS",false);}else{//不过滤请求,路由它currentContext.setSendZuulResponse(true);//设置成功代码:200currentContext.setResponseStatusCode(HttpStatus.SC_OK);currentContext.set("SUCCESS",true);}System.out.println("token:"+token);returnnull;}/***当前过滤器类型:pre,发布,溃败e.错误*/@OverridepublicStringfilterType(){returnFilterConstants.PRE_TYPE;}/***表示当前过滤器优先级*/@OverridepublicintfilterOrder(){returnFilterConstants.PRE_DECORATION_FILTER_ORDER-1;}/***你想强制执行这个过滤器吗?**/@OverridepublicbooleanshouldFilter(){返回真;}}POST过滤器示例:返回时设置一个cookie/***Post过滤器*@AuthorBig.Hu*/@ComponentpublicclassPostFilterextendsZuulFilter{/***POST过滤器:在路由和错误过滤器之后执行*/@OverridepublicStringfilterType(){returnFilterConstants.POST_TYPE;}@OverridepublicintfilterOrder(){returnFilterConstants.SEND_RESPONSE_FILTER_ORDER-1;}@OverridepublicbooleanshouldFilter(){返回真;}@OverridepublicObjectrun(){System.err.println("执行后置过滤器......");RequestContextcurrentContext=RequestContext.getCurrentContext();HttpServletResponseresponse=currentContext.getResponse();Cookiecookie=newCookie("name","Jack.Hu");cookie.setMaxAge(60*60*24);response.addCookie(cookie);returnnull;}}访问路径:localhost:7004/api/od/getOrder.(不带token参数)请求被前置过滤器过滤掉,不带token且带token参数请求成功!requestwithtoken按f12可以看到postfilter设置的cookie,查看cookie控制台:console