SpringCloud(Zuul)

主要收集、整理Zuul相关的知识点,并加以自己的实践理解

目录结构

  • 1 什么是API网关
  • 2 什么是Zuul
  • 3 Zuul的核心
  • 4 Zuul中默认实现的Filter
  • 5 搭建SpringCloud Zuul
    • 5.1 maven依赖
    • 5.2 启动类中开启Zuul服务
    • 5.3 配置文件
    • 5.4 自定义Filter
    • 5.5 Zuul的路由规则
    • 5.6 忽略某个不想对外提供的服务
    • 5.7 路由通配符含义
  • 6 Zuul和Nginx哪家强

1 什么是API网关

  • 网关这种东西,是伴随着微服务风生水起的,微服务可以没有api网关,但是最好有,也并不是绝对的。因为有这个东西是合理的,没有的话,你的微服务会很难受。

  • 首先网关最基础的作用就是对外包括ios、android、webapp、website、h5、微信小程序甚至是第三方提供一个统一服务接入入口。聚合内网众多微服务,为端上提供统一的api入口。对外统一使-用http协议,网关屏蔽了后端协议的差异性,后端可以专注于提供服务,无需考虑协议的转换。

  • 其次,网关应该具备API防刷以及限流的功能。防刷可以保护你的API不会被恶意调用,限流可以保护你的后端不会被冲垮。网关应该还具备权鉴功能,是否具备对某个api的访问功能,应该做在api网关层会好很多。保护后端服务,提供完善的流控、服务降级、ACL、鉴权机制。

  • 提供API管理平台,包括API的配置、沙箱测试、发布、修改、下线。

  • 提供API层面的监控与报表,做到对业务自身的掌控,以及对用户行为等进行分析。为开放平台的持续完善提供基础服务。

  • 它可以为不同类型的客户端定义不同的api:

2 什么是Zuul

  • Zuul是Spring Cloud全家桶中的微服务API网关。所有从设备或网站来的请求都会经过Zuul到达后端的Netflix应用程序。作为一个边界性质的应用程序,Zuul提供了动态路由、监控、弹性负载和安全功能。Zuul底层利用各种filter实现如下功能:

      1) 认证和安全 识别每个需要认证的资源,拒绝不符合要求的请求。
      2) 性能监测 在服务边界追踪并统计数据,提供精确的生产视图。
      3) 动态路由 根据需要将请求动态路由到后端集群。
      4) 压力测试 逐渐增加对集群的流量以了解其性能。
      5) 负载卸载 预先为每种类型的请求分配容量,当请求超过容量时自动丢弃。
      6) 静态资源处理 直接在边界返回某些响应。
    

3 Zuul的核心

Filter是Zuul的核心,用来实现对外服务的控制。Filter的生命周期有4个,分别是“PRE”、“ROUTING”、“POST”、“ERROR”,整个生命周期可以用下图来表示。
SpringCloud(Zuul)_第1张图片
Zuul大部分功能都是通过过滤器来实现的,这些过滤器类型对应于请求的典型生命周期。

  • PRE: 这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息等。这个阶段后如果有自定义的过滤器,则会执行自定义的过滤器。
  • ROUTING:这种过滤器将请求路由到微服务。这种过滤器用于构建发送给微服务的请求,并使用Apache HttpClient或Netfilx Ribbon请求微服务。
  • ERROR:在其他阶段发生错误时执行该过滤器。 除了默认的过滤器类型,Zuul还允许我们创建自定义的过滤器类型。例如,我们可以定制一种STATIC类型的过滤器,直接在Zuul中生成响应,而不将请求转发到后端的微服务。
  • POST:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等。

4 Zuul中默认实现的Filter

类型 顺序 过滤器 功能
pre -3 ServletDetectionFilter 标记处理Servlet的类型
pre -2 Servlet30WrapperFilter 包装HttpServletRequest请求
pre -1 FormBodyWrapperFilter 包装请求体
route 1 DebugFilter 标记调试标志
route 5 PreDecorationFilter 处理请求上下文供后续使用
route 10 RibbonRoutingFilter serviceId请求转发
route 100 SimpleHostRoutingFilter url请求转发
route 500 SendForwardFilter forward请求转发
post 0 SendErrorFilter 处理有错误的请求响应
post 1000 SendResponseFilter 处理正常的请求响应

5 搭建SpringCloud Zuul

5.1 maven依赖


    org.springframework.cloud
    spring-cloud-starter-netflix-zuul
    2.1.2.RELEASE


    org.springframework.cloud
    spring-cloud-starter-netflix-eureka-client
    2.1.2.RELEASE

5.2 启动类中开启Zuul服务

package com.kinglong.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

@SpringBootApplication
@EnableZuulProxy//开启zuul
public class Application {

	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}

}

5.3 配置文件

server.port=8091
#服务名
spring.application.name=06-springcloud-api-gateway

#自定义路由
zuul.routes.api-kinglong.path=/api-kinglong/**
#负载均衡的服务名
zuul.routes.api-kinglong.service-id=05-springcloud-service-feign
#eureka服务注册地址
eureka.client.service-url.defaultZone=http://eureka8085:8085/eureka/,http://eureka8086:8086/eureka/

以上就可以直接启动了,这就是最简版的Zuul,他只是起到了对请求的转发作用。

5.4 自定义Filter

实现自定义Filter,需要继承ZuulFilter的类,并覆盖其中的4个方法。

package com.kinglong.springcloud.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

/**
 * 自定义Filter
 * 
 * @author haojinlong
 */
@Component //加了注解后可以让这个过滤器注入到spring中,变为一个bean
public class AuthFilter extends ZuulFilter {

	/**
	 * 返回值为过滤器的类型,过滤器的类型决定了过滤器在哪个生命周期执行,
	 * pre标识在任意路由之前执行过滤器,其他值还有post,error,route和static,也可以自定义
	 *
	 * @return
	 */
	@Override
	public String filterType() {
		return "pre";
	}

	/**
	 * 表示过滤器的执行顺序,当过滤器很多时,可以通过该方法返回值指定过滤器的执行顺序
	 *
	 * @return
	 */
	@Override
	public int filterOrder() {
		return 0;
	}

	/**
	 * 判断过滤器是否执行,true表示执行,false表示不执行
	 *
	 * @return
	 */
	@Override
	public boolean shouldFilter() {
		return true;
	}

	/**
	 * 具体逻辑
	 * 如果请求地址中携带了token参数,则认为是合法的请求,如果不是则为非法请求。当然还是要根据具体业务场景做相应的处理。
	 * 这里只是实验功能
	 * @return
	 * @throws ZuulException
	 */
	@Override
	public Object run() throws ZuulException {
		RequestContext context = RequestContext.getCurrentContext();
		HttpServletRequest request = context.getRequest();
		String token = request.getParameter("token");
		if(null == token){
			context.setSendZuulResponse(false);
			context.setResponseStatusCode(401);
			context.addZuulResponseHeader("content-type", "text/html;charset=utf-8");
			context.setResponseBody("无权限访问");
		}

		return null;
	}
}

有了第四步之后,再如第三步一样不带token访问就无法访问了,会被拦截出去。
SpringCloud(Zuul)_第2张图片

5.5 Zuul的路由规则

配置文件中的两个路由配置其实是可以简写,合并成一个配置,如下:

  • 原先的路由配置
#自定义路由
zuul.routes.api-kinglong.path=/api-kinglong/**
#负载均衡的服务名
zuul.routes.api-kinglong.service-id=05-springcloud-service-feign
  • 简写后的
zuul.routes.05-springcloud-service-feign=/api-kinglong/**

5.6 忽略某个不想对外提供的服务

默认情况下,eureka上所有注册的服务都会被Zuul创建映射关系来进行路由,但是业务场景可能只需要让feign来集中提供服务,而那些底层的服务提供者的服务是不想对外开放的。这时就需要采用一些配置,使其忽略那些不想对外提供服务的路由

#忽略掉服务提供者,如果有多个,可以用逗号隔开即可
zuul.ignored-services=01-springcloud-service-provider

也可以更加精确地具体到某个接口

#忽略掉某个接口
zuul.ignored-patterns=/**/hello/**

还可以统一的为路由增加前缀

zuul.prefix=/myapi

5.7 路由通配符含义

通配符 含义 举例 说明
匹配任意单个字符 /05-springcloud-service-feign 匹配:/05-springcloud-service-feign/a,/05-springcloud-service-feign/b等
* 匹配任意数量的字符 /05-springcloud-service-feign/* 匹配:/05-springcloud-service-feign/aaaa,/05-springcloud-service-feign/bbbb等,但是不可以匹配:/05-springcloud-service-feign/bb/oo/hhh
** 匹配任意单个字符 /05-springcloud-service-feign/** 匹配:/05-springcloud-service-feign/a/r/ddd,/05-springcloud-service-feign/b/d/f等

6 Zuul和Nginx哪家强

有人已经做了相关测试

https://blog.csdn.net/zhangbijun1230/article/details/81660834
(基于zuul1测试)最后的结论:因为zuul是java开发的,所以服务器硬件配置对性能影响很大,在8核32G的配置上,Zuul才跑赢了Nginx。
https://www.2cto.com/kf/201805/746203.html
(基于zuul2测试,zuul2采用的是netty开发)性能和nginx相差不大,基本一致。

Zuul的原始性能接近Nginx。事实上,在启动预热之后,显示测试结果更好一些。但Nginx看上去会稳定一下,Zuul出现了2次的请求错误。
如果你想使用Zuul的其他功能,或者希望通过它与其他的Netflix服务集成(比如Eureka),Zuul可以作为其他简单反向代理的替代品。

文献参考来源:

https://blog.csdn.net/u011820505/article/details/79373594
https://microservices.io/patterns/apigateway.html
https://blog.csdn.net/qq_27384769/article/details/82991261

你可能感兴趣的:(后端)