什么是zuul?
Zuul是从设备和网站到Netflix流应用的后端的所有请求的网关。作为边缘服务应用程序,Zuul旨在实现动态路由,监控,弹性和安全性。它还可以根据需要将请求路由到多个Amazon Auto Scaling Groups。
为什么我们建立Zuul?
路由是微服务体系结构不可或缺的一部分。例如,/api/users映射到用户服务,/api/shop映射到商店服务。zuul是Netflix基于JVM的路由器和服务器端负载均衡器。
Netflix API流量的数量和多样性有时会导致线上生产环境问题迅速出现,而且没有任何警告。我们需要一个能够快速改变行为的系统,以便来应对这些情况。
Zuul使用一系列不同类型的过滤器,使我们能够快速灵活地将功能应用于我们的边缘服务。 这些过滤器可帮助我们执行以下功能:
身份验证和安全 - 识别每个资源的身份验证要求,并拒绝不满足的请求。
洞察和监测 - 跟踪边缘的有意义的数据和统计数据,以便我们准确地了解线上生产环境情况。
动态路由 - 根据需要将请求动态路由到不同的后端集群。
压力测试 - 逐渐增加到集群的流量,以衡量性能。
负载分配 - 为每种类型的请求分配容量并删除超出限制的请求。
静态响应处理 - 直接在边缘构建一些响应,而不是将它们转发到内部集群
多区域弹性 - 跨AWS地区的路由请求,以使我们的ELB使用多样化,并使我们的边缘更接近我们的成员
Zuul包含多个组件:
zuul-core - 库,其中包含编译和执行过滤器的核心功能。
zuul-simple-webapp-webapp-其中显示了如何使用zuul-core构建应用程序的简单示例
zuul-netflix - 库将其他NetflixOSS组件添加到Zuul中,例如使用功能区进行路由请求。
zuul-netflix-webapp - webapp-它将zuul-core和zuul-netflix一起包装成一个易于使用的包
Zuul通过使用其他Netflix OSS组件,为我们提供了对我们系统的深入了解:
Hystrix被用来包装呼叫到我们的来源,这使我们能够在发生问题时减少流量并划分优先级。
Ribbon是我们的客户端,它提供来自Zuul的所有出站请求,它提供了有关网络性能和错误的详细信息,并处理负载均衡。
Turbine实时聚合细粒度的度量标准,以便我们可以快速观察并对问题做出反应。
Archaius处理配置并提供动态更改属性的功能。
我们可以创建一个过滤器,将特定的客户或设备路由到单独的API集群进行调试。在使用zuul之前,我们使用Hadoop查询数十亿个记录的请求,以查找我们感兴趣的数千个请求。
我们有一个自动化的过程,在zuul过滤器中使用动态Archaius配置来稳定地增加路由到一个小型源服务器集群的流量。当实例接收到更多的流量时,我们会测量它们的性能特征和容量。
SpringCloud已经创建了一个嵌入的zuul代理,来简化一个非常常见的用例的开发。此功能对于代理所需后端服务的用户界面很有用,避免了对所有后端独立管理CORS和身份验证问题的需要。
要启用它,请使用@enablezuulproxy注释Spring Boot主类,然后将本地调用转发到相应的服务。按照惯例,ID为“users”的服务将从位于/users的代理接收请求。
代理使用路径定位通过发现服务转发到相应的实例,并且所有请求都在hystrix命令中执行,因此故障将显示在hystrix度量中。
zuul请求生命周期
在这张图片中,可以检查在访问源服务器之前,Zuul提供了一些功能,可以在请求中添加或在请求(响应)之后添加,如过滤,路由,聚合,错误处理等。
在我的示例中,我使用zuul实现了过滤器/路由。在这个示例中,我有两个组件:service和zuul。
服务将提供一些操作:
@RestController
@SpringBootApplicationpublic class BookApplication {
@RequestMapping(value = "/available")
public String available() {
return "Spring in Action";
}
@RequestMapping(value = "/checked-out")
public String checkedOut() {
return "Spring Boot in Action";
}
public static void main(String[] args) {
SpringApplication.run(BookApplication.class, args);
}
}
spring.application.name=book
server.port=8090
Zuul服务
@EnableZuulProxy
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
@Bean
public SimpleFilter simpleFilter() {
return new SimpleFilter();
}
}
public class SimpleFilter extends ZuulFilter {
private static Logger log = LoggerFactory.getLogger(SimpleFilter.class);
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 1;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
log.info(String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString()));
return null;
}
}
zuul.routes.books.url=http://localhost:8090
ribbon.eureka.enabled=false
server.port=8080
通过zuul和book服务的协同工作,我们可以访问http://localhost:8080/books查看这些操作。
长按订阅更多精彩▼