Zuul是SpringCloud全家桶的微服务网关。所有从app或者网站(第三方)来的请求都会经过Zuul到达后端的Netflix应用程序。作为一个边界性质的应用程序,Zuul提供了动态路由、监控、弹性负载和安全功能。
认证和安全,识别每个需要认证的资源,拒绝不服务要求的请求。
性能检测,在服务边界追踪并统计数据,提供精确的生产视图。
动态路由,根据需要将请求动态路由到后端集群。
压力测试,逐渐增加对集群的流量以及了解其性能。
负载卸载,预先为每种类型的请求分配容量,当请求超过流量时自动丢弃。静态资源处理,直接在边界返回某种响应。
静态资源处理,直接在Zuul处理静态资源并响应,而并非转发这些请求到内部集群中。
多区域弹性,跨越AWS区域进行请求路由,旨在实现ELB使用多样化并保证边缘位置与使用者尽可能接近。
引入jar包:
复制
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> <version>1.3.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zuul</artifactId> <version>1.3.5.RELEASE</version> </dependency>
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
配置文件:application.yml。
复制
server: port: 7004 # 端口spring: application:name: zuul-getway # 服务名eureka: client:service-url: defaultZone: http://jack:666@localhost:8764/eureka/ # 需要注册到eureka instance:instance-id: ${spring.application.name}:${server.port}zuul: routes:order-service: /od/** # 对某个服务自定义路由规则 serviceId: order-service # 这个配置可以实现负载均衡,默认是轮询 # 设置某些服务不要进行反向代理 进行路由,多个服务用逗号隔开 ignored-services: order-service, user-service prefix: /api # 请求路径的前缀
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
查看是否注册到eureka。
Eureka注册中心
访问路径:
localhost:7004/api/od/getOrder?token=1235。
(后面带token是因为我配置了pre过滤器,下面会介绍)。
pre(前置):在请求被路由之前调用。可利用这种过滤器来实现身份认证、在集群中选择请求的微服务,记录调试等。
routing(路由):将请求路由到微服务。用于构建发送给微服务的请求,并使用apache httpclient或netflix ribbon请求微服务。
post(后置):在路由到微服务后执行。可用于响应添加标准的http header、收集统计信息和指标、将响应从微服务发送到客户端。
error(错误):在其他阶段发送错误时执行该过滤器。
注:除了默认的过滤器类型以外Zuul还允许创建自定义的过滤器类型。
很简单,只需设置zuul.ClassName.filterType.disable=true ,即可禁用SimpleClassName所对应的过滤器。例如:zuul.TokenFilter.pre.disable=true; 即可禁用TokenFilter过滤器。
例子: 鉴权认证。如果参数带了token就允许访问。
复制
/** * pre过滤器 * @Author Big.Hu */@Componentpublic class TokenFilter extends ZuulFilter {@Overridepublic Object run() {System.err.println("执行pre前置过滤器。。。。。。。。。");RequestContext currentContext = RequestContext.getCurrentContext();HttpServletRequest request = currentContext.getRequest();StringBuffer requestURL = request.getRequestURL();System.out.println("requestURL:" + requestURL); // 获取请求的参数String token = request.getParameter("token");if (StringUtils.isEmpty(token)) { // 如果参数为空则过滤该请求,不对其进行路由currentContext.setSendZuulResponse(false); // 设置错误码: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);return null; }/** * 当前filter类型:pre、post、route、error */@Overridepublic String filterType() {return FilterConstants.PRE_TYPE; }/** * 表示当前filter优先级 */@Overridepublic int filterOrder() {return FilterConstants.PRE_DECORATION_FILTER_ORDER - 1; }/** * 是否执行该过滤器? **/@Overridepublic boolean shouldFilter() {return true; } }
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
例: 在返回的时候设置一个cookie。
复制
/** * Post过滤器 * @Author Big.Hu */@Componentpublic class PostFilter extends ZuulFilter {/** * POST过滤器:在route和error过滤器之后执行 */@Overridepublic String filterType() {return FilterConstants.POST_TYPE; }@Overridepublic int filterOrder() {return FilterConstants.SEND_RESPONSE_FILTER_ORDER - 1; }@Overridepublic boolean shouldFilter() {return true; }@Overridepublic Object run() {System.err.println("执行Post过滤器。。。。。。。。。");RequestContext currentContext = RequestContext.getCurrentContext();HttpServletResponse response = currentContext.getResponse();Cookie cookie = new Cookie("name", "Jack.Hu");cookie.setMaxAge(60 * 60 * 24);response.addCookie(cookie);return null; } }
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
访问路径:
localhost:7004/api/od/getOrder。
(没带token参数)请求被pre过滤器过滤掉了。
不带token请求
带上token参数请求成功!
带token请求
再按f12看post过滤器设置的cookie。
查看cookie
控制台:
控制台