博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring Cloud 学习 (五) Zuul
阅读量:6251 次
发布时间:2019-06-22

本文共 4978 字,大约阅读时间需要 16 分钟。

Zuul 作为路由网关组件,在微服务架构中有着非常重要的作用,主要体现在以下 6 个方面:

  1. Zuul, Ribbon 以及 Eureka 相结合,可以实现智能路由和负载均衡的功能,Zuul 能够将请求流量按某种策略分发到集群状态的多个服务实例
  2. 网关将所有服务的 API 接口统一聚合,并统一对外暴露。外界系统调用 API 接口时,都是由网关对外暴露的 API 接口,外界系统不需要知道微服务系统中各服务相互调用的复杂性。微服务系统也保护了其内部微服务单元的 API 接口 , 防止其被外界直 接调用,导致服务的敏感信息对外暴露
  3. 网关服务可以做用户身份认证和权限认证,防止非法请求操作 API 接口,对服务器起到保护作用
  4. 网关可以实现监控功能,实时日志输出,对请求进行记录
  5. 网关可以用来实现流量监控,在高流量的情况下,对服务进行降级
  6. API 接口从内部服务分离出来,方便做测试

Zuul 的核心是一系列过滤器,可以在 Http 请求的发起和响应返回期间执行一系列的过滤器:

  1. PRE 过滤器:在请求路由到具体的服务之前执行,这种类型的过滤器可以做安全验证,例如身份验证、 参数验证等
  2. ROUTING 过滤器:用于将请求路由到具体的微服务实例。在默认情况下,它使用 Http Client 进行网络请求
  3. POST 过滤器:在请求己被路由到微服务后执行。 一般情况下,用作收集统计 信息、指标,以及将响应传输到客户端
  4. ERROR 过滤器:在其他过滤器发生错误时执行

Zuul 采取了动态读取、编译和运行这些过滤器。过滤器之间不能直接相互通信,而是通过 RequestContext 对象来共享数据,每个请求都会创建一个 RequestContext 对象。Zuul 过滤器具有以下关键特性:

  1. Type (类型): Zuul 过滤器的类型,这个类型决定了过滤器在请求的哪个阶段起作用,例如 Pre、Post 阶段等
  2. Execution Order (执行顺序): 规定了过滤器的执行顺序,Order 的值越小越先执行
  3. Criteria (标准): Filter 执行所需的条件
  4. Action (行动): 如果符合执行条件,则执行 Action (即逻辑代码)

使用 Zuul

新建 spring-cloud-eureka-zuul-client

pom

spring-cloud-parent
com.karonda
1.0.0
4.0.0
spring-cloud-eureka-zuul-client
org.springframework.boot
spring-boot-starter-data-rest
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
org.springframework.cloud
spring-cloud-starter-netflix-zuul
org.springframework.boot
spring-boot-maven-plugin

application.yml

server:  port: 8051eureka:  client:    service-url:      defaultZone: http://localhost:8001/eureka/spring:  application:    name: zuul-clientzuul:  routes:    hiapi:      path: /hiapi/**      serviceId: eureka-client    ribbonapi:      path: /ribbonapi/**      serviceId: ribbon-client    feignapi:      path: /feignapi/**      serviceId: feign-client

启动类

@EnableZuulProxy // 开启 Zuul@SpringBootApplicationpublic class EurekaZuulClientApp {    public static void main(String[] args){        SpringApplication.run(EurekaZuulClientApp.class, args);    }}

测试

  1. 启动 eureka-server
  2. 启动 eureka-client (两个实例:一个 8011 端口,一个 8012 端口)
  3. 启动 eureka-ribbon-client
  4. 启动 eureka-feign-client
  5. 启动 eureka-zuul-client

多次访问 可以看到 8011 和 8012 端口交替出现 (Zuul 默认 与 Ribbon 结合实现了负载均衡)

多次访问 可以看到 8011 和 8012 端口交替出现

多次访问 可以看到 8011 和 8012 端口交替出现

在 Zuul 上配置熔断器

实现 FallbackProvider 接口

@Componentpublic class MyFallbackProvider implements FallbackProvider {    @Override    public String getRoute() {        return "eureka-client"; // 如果所有的路由服务都加熔断功能,返回 "*"    }    @Override    public ClientHttpResponse fallbackResponse(String route, Throwable cause) {        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("error, fallback".getBytes());            }            @Override            public HttpHeaders getHeaders() {                HttpHeaders headers = new HttpHeaders();                headers.setContentType(MediaType.APPLICATION_JSON);                return headers;            }        };    }}

测试

  1. 关闭所有的 eureka-client
  2. 重启 eureka-zuul-client

在 Zuul 中使用过滤器

继承 ZuulFilter

@Componentpublic class MyFilter extends ZuulFilter {    private static Logger logger = LoggerFactory.getLogger(MyFilter.class);    @Override    public String filterType() {        return PRE_TYPE;    }    @Override    public int filterOrder() {        return 0;    }    @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){            logger.warn("token is empty");            ctx.setSendZuulResponse(false);            ctx.setResponseStatusCode(401);            try {                ctx.getResponse().getWriter().write("token is empty");            } catch (IOException e) {                return null;            }        }        logger.info("ok");        return null;    }}

测试

  1. 重启 eureka-zuul-client

访问

访问

完整代码:

本人 C# 转 Java 的 newbie, 如有错误或不足欢迎指正,谢谢

转载于:https://www.cnblogs.com/victorbu/p/11017272.html

你可能感兴趣的文章
PL/SQL查看表结构
查看>>
升级fedora 18到fedora 19
查看>>
easyui combobox两种不同的数据加载方式
查看>>
javascript 深拷贝
查看>>
【代码小记】无
查看>>
BarTender 2016表单中的“秤显示”控件
查看>>
11月20日学习内容整理:jquery插件
查看>>
Arduino入门之前
查看>>
zoj 1904 Beavergnaw 计算圆柱和圆台的体积
查看>>
darknet源码学习
查看>>
移动端头部meta
查看>>
Redis客户端集群
查看>>
javascript基础篇:函数
查看>>
[CI] 使用Jenkins自动编译部署web应用
查看>>
SVN与TortoiseSVN实战:补丁详解
查看>>
java一些面试题
查看>>
干货型up主
查看>>
获取页面中所有dropdownlist类型控件
查看>>
stark组件(2):提取公共视图函数、URL分发和设置别名
查看>>
android——使用Interceptor设置缓存来给服务器减负
查看>>