Zuul
第一章 Zuul介绍
智能路由网关组件Zuul作为微服务系统的网关组件,用于构建边界服务,致力于动态路由、过滤、监控、弹性伸缩和安全。
Zuul的核心是一系列过滤器:
PRE过滤器:在请求路由到具体服务之前执行,可以做安全验证,如身份验证、参数验证等。
ROUTING过滤器:用于将请求路由到具体的微服务实例。
POST过滤器:在请求已被路由到微服务后执行,可以用于收集统计信息、指标、及将响应传输到客户端。
ERROR过滤器:在其他过滤器发生错误时执行。
Zuul采取了动态读取、编译和运行这些过滤器,过滤器之间不能直接通信,而是通过RequestContext对象来共享数据,每一个请求都会创建一个RequestContext对象。
第二章 Zuul
2.1. 引入依赖
<dependencies> <!-- web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- eureka 客户端 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!-- zuul --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> </dependency> </dependencies>
2.2. 启动器
@EnableZuulProxy @EnableEurekaClient @SpringBootApplication public class Zuul_StartSpringCloudApp { public static void main(String[] args) throws Exception { SpringApplication.run(Zuul_StartSpringCloudApp.class, args); } }
2.3. Yml配置
2.3.1. 路由同时做ribbon负载均衡
#路由同时做ribbon负载均衡 zuul: routes: consumer: path: /consumer/** serviceId: consumer-80 provider: path: /provider/** serviceId: eureka-provider
2.3.2. 指定服务实例url,不要ribbon负载均衡
#指定服务实例url,不要ribbon负载均衡,这时不需配serviceId了,一旦指定了url,zuul就不能做负载均衡了 zuul: routes: Provider1: path: /provider1/** url: http://localhost:9001
2.3.3. 既要指定url,也要ribbon负载均衡
#既要指定url,也要做负载均衡 zuul: routes: provider: path: /provider2/** serviceId: provider_v1 #自己维护负载均衡服务注册列表,不向eureka获取列表 ribbon: eureka: enabled: false #列出serviceId所需的服务注册列表 provider_v1: ribbon: listOfServers: http://localhost:9001,http://localhost:9002,http://localhost:9003
第三章 Zuul配置熔断器
在zuul工程中创建组件并继承ZuulFallbackProvider/FallbackProvider
@Component public class SelfFallbackProvider implements FallbackProvider{ @Override public String getRoute() { //return "consumer-80"; return "*"; } @Override public ClientHttpResponse fallbackResponse(String route, Throwable cause) { return new ClientHttpResponse() { @Override public InputStream getBody() throws IOException { return new ByteArrayInputStream("sorry, i am the zuul fallback for hystrix.".getBytes()); } @Override public HttpHeaders getHeaders() { HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.setContentType(MediaType.APPLICATION_JSON); return httpHeaders; } @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() { } }; } }
第四章 Zuul中使用过滤器
@Component public class SelfFilter extends ZuulFilter{ /* * Zuul过滤器类型,这个类型决定了过滤器在请求的哪个阶段起作用 * "pre" - pre-routing filtering,请求路由到服务之前执行 * "route" - routing to an origin,请求路由到具体的微服务执行 * "post" - post-routing filters,请求已被路由到微服务后执行 * "error" - for error handling,其他过滤器发生错误执行 * "static" - for static responses */ @Override public String filterType() { return "pre"; } /* * 过滤器的执行顺序,值越小,越先执行 */ @Override public int filterOrder() { return 0; } /** * filter执行所需条件 */ @Override public boolean shouldFilter() { return true; } /* * 逻辑代码 */ @Override public Object run() throws ZuulException { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); Object accesstoken = request.getParameter("token"); if (accesstoken == null) { ctx.setSendZuulResponse(false); ctx.setResponseStatusCode(401); try { ctx.getResponse().getWriter().write("zuul selfFilter response token is null"); } catch (IOException e) { e.printStackTrace(); } } return null; }
汇总: