简介
Zuul是所有从设备和web站点到Netflix流媒体应用程序后端的请求的前门。作为一个边缘服务应用程序,Zuul的构建是为了支持动态路由、监视、弹性和安全性。它还可以根据需要将请求路由到多个Amazon自动伸缩组。
Zuul使用了一系列不同类型的过滤器,使我们能够快速灵活地将功能应用到edge服务中。这些过滤器帮助我们执行以下功能:
- 身份验证和安全性——识别每个资源的身份验证需求并拒绝不满足这些需求的请求。
- 洞察和监控——在边缘跟踪有意义的数据和统计数据,以便为我们提供准确的生产视图。
- 动态路由——根据需要动态地将请求路由到不同的后端集群。
- 压力测试——逐步增加集群的流量,以评估性能。
- 减少负载——为每种类型的请求分配容量,并删除超过限制的请求。
- 静态响应处理——直接在边缘构建一些响应,而不是将它们转发到内部集群
- 多区域弹性——跨AWS区域路由请求,以使我们的ELB使用多样化,并使我们的优势更接近我们的成员
在高级视图中,Zuul 2.0是一个Netty服务器,它运行预过滤器(入站过滤器),然后使用Netty客户机代理请求,然后在运行后过滤器(出站过滤器)后返回响应。
过滤器是Zuul业务逻辑的核心所在。它们能够执行非常大范围的操作,并且可以在请求-响应生命周期的不同部分运行,如上图所示。
还有两种类型的过滤器:同步和异步。因为我们是在一个事件循环上运行的,所以千万不要阻塞过滤器。如果要阻塞,可以在一个异步过滤器中阻塞,在一个单独的threadpool上阻塞——否则可以使用同步过滤器。
实用过滤器
- DebugRequest——查找一个查询参数来为请求添加额外的调试日志
- Healthcheck -简单的静态端点过滤器,返回200,如果一切引导正确
- ZuulResponseFilter -添加信息头部提供额外的细节路由,请求执行,状态和错误原因
- GZipResponseFilter -可以启用gzip出站响应
- SurgicalDebugFilter ——可以将特定的请求路由到不同的主机进行调试
依赖:
org.springframework.cloud spring-cloud-starter-netflix-zuul
MyFilter 过滤器
@Component public class MyFilter extends ZuulFilter { private static Logger log = LoggerFactory.getLogger(MyFilter.class); /** * pre:路由之前 * routing:路由之时 * post: 路由之后 * error:发送错误调用 * @return */ @Override public String filterType() { return "pre"; } /** * 过滤的顺序 * @return */ @Override public int filterOrder() { return 0; } /** * 这里可以写逻辑判断,是否要过滤,本文true,永远过滤 * @return */ @Override public boolean shouldFilter() { return true; } /** * 过滤器的具体逻辑。 * 可用很复杂,包括查sql,nosql去判断该请求到底有没有权限访问。 * @return * @throws ZuulException */ @Override public Object run() throws ZuulException { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); log.info(String.format("%s >>> %s", request.getMethod(), request.getRequestURL().toString())); Object accessToken = request.getParameter("token"); if(accessToken == null) { log.warn("token is empty"); ctx.setSendZuulResponse(false); ctx.setResponseStatusCode(401); try { ctx.getResponse().getWriter().write("token is empty"); }catch (Exception e){} return null; } log.info("ok"); return null; } }
application.yml配置路由转发
eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/ server: port: 8769 spring: application: name: cloud-service-zuul zuul: routes: api-a: path: /api-a/** serviceId: cloud-service-ribbon api-b: path: /api-b/** serviceId: cloud-service-feign
启用zuul
@SpringBootApplication @EnableZuulProxy @EnableEurekaClient @EnableDiscoveryClient public class CloudServiceZuulApplication { public static void main(String[] args) { SpringApplication.run(CloudServiceZuulApplication.class, args); } }
路由熔断
/** * 路由熔断 */ @Component public class ProducerFallback implements FallbackProvider { private final Logger logger = LoggerFactory.getLogger(FallbackProvider.class); //指定要处理的 service。 @Override public String getRoute() { return "spring-cloud-producer"; } @Override public ClientHttpResponse fallbackResponse(String route, Throwable cause) { if (cause != null && cause.getCause() != null) { String reason = cause.getCause().getMessage(); logger.info("Excption {}",reason); } return fallbackResponse(); } public ClientHttpResponse fallbackResponse() { return new ClientHttpResponse() { @Override public HttpStatus getStatusCode() throws IOException { return HttpStatus.OK; } @Override public int getRawStatusCode() throws IOException { return 200; } @Override public String getStatusText() throws IOException { return "OK"; } @Override public void close() { } @Override public InputStream getBody() throws IOException { return new ByteArrayInputStream("The service is unavailable.".getBytes()); } @Override public HttpHeaders getHeaders() { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); return headers; } }; } }
Zuul网关有自动转发机制,但其实Zuul还有更多的应用场景,比如:鉴权、流量转发、请求统计等等,这些功能都可以使用Zuul来实现。
以上就是SpringCloud之zuul的原理及使用方法介绍的详细内容,更多请关注其它相关文章!