SpringCloud-微服务网关ZUUL(六)

前言:前面说过,由于微服务过多,可能某一个小业务就需要调各种微服务的接口,不可避免的就会需要负载均衡和反向代理了,以确保ui不直接与所有的微服务接口接触,所以我们需要使用一个组件来做分发,跨域等各种请求。

一、微服务网关ZUUL

  ZUUL是Netflix开源的微服务网关,它可以和Eureka、Ribbon、Hystrix等组件配合使用,它主要用作反向代理、Filter扩展、动态加载、动态路由、压力测试、弹性扩展、审查监控、安全检查等。

二、ZUUL与SpringCloud各组件的整合使用

  1、创建一个Maven工程,gateway-zuul,添加依赖:

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.13.RELEASE</version>
  </parent>

  <dependencies>

    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-eureka</artifactId>
    </dependency>

    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-zuul</artifactId>
    </dependency>

  </dependencies>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>Edgware.SR3</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <!-- 添加spring-boot的maven插件 -->
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>

  2、在启动类上添加注解@EnableZuulProxy,声明ZUUL代理,通过观察Zuul的类库发现,zuul的依赖库中除了有它本身的核心包外还有actuator、hystrix的整合包,默认实现了监控和熔断机制,所有经过zuul的请求都会在hystrix命令中执行:

@SpringBootApplication
@EnableZuulProxy
public class ZuulApplication {

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

}

  3、编写配置文件application.properties:

server.port=8000
spring.application.name=zuul-8000
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
#由于zuul中的actuator默认的安全权限为ture,需改为false,若不修改则会导致无法访问路由管理(localhost:8000/routes)
management.security.enabled=false

(注:下面的测试,是基于之前做的几个关于Ribbon、Hystrix的demo来做的,若感兴趣可以看一下我之前的文章:SpringCloud-客户端的负载均衡Ribbon(三)SpringCloud-容错处理Hystrix熔断器(五)

  4、测试路由网关是否启动:

  分别启动 eureka-ribbon-servereureka-ribbon-clienteureka-ribbon-client2 和 gateway-zuul,打开服务配置中心,并访问http://localhost:8000/client-8762/getUser:

  通过网关访问成功!

  5、测试负载均衡是否可用:

  分别启动 eureka-ribbon-servereureka-feign-hystrix-client、修改 eureka-ribbon-client2 端口为8763、修改 eureka-ribbon-client2 端口为8764 和 gateway-zuul,打开服务配置中心,并多次访问http://localhost:8000/client-8762/loadInstance,观察返回结果:

   根据观察结果知,通过网关实现负载均衡!

  6、测试熔断与路由端点是否可用:

  熔断:

    分别启动 eureka-ribbon-server eureka-feign-hystrix-client eureka-ribbon-client2 gateway-zuul,打开服务配置中心,并多次访问http://localhost:8000/client-8762/loadInstance,观察返回结果:

    将CLIENT-87实例关闭,再次调用:

注:由于client-87的实例关闭后要等eureka将实例移除后,然后eureka通知zuul,zuul再将client-87从网关列表中移除,最后访问,才可以看到熔断,走回调函数了!

  启动项目与上面 测试5相同,注意网关中的application.properties一定要将安全权限打开或者以其他方式,才可访问localhost:8000/routes/

#由于zuul中的actuator默认的安全权限为ture,需改为false,若不修改则会导致无法访问路由管理(localhost:8000/routes)
management.security.enabled=false

三、ZUUL过滤器的实践

  Zuul提供一个框架,可以对Groovy写的过滤器进行动态的加载、编译、运行。过滤器之间没有直接的相互通信,通过一个RequestContext的静态类中ThreadLocal变量来进行数据传递,过滤器类型:

PRE:这种过滤器在请求到达Origin Server之前调用。比如身份验证,在集群中选择请求的Origin Server,记log等;

ROUTING:在这种过滤器中把用户请求发送给Origin Server。发送给Origin Server的用户请求在这类过滤器中build。并使用Apache HttpClient或者NetfilxRibbon发送给Origin Server;

POST:这种过滤器在用户请求从Origin Server返回以后执行。比如在返回的response上面加response header,做各种统计等。并在该过滤器中把response返回给客户;

ERROR:在其他阶段发生错误时执行该过滤器;

客户定制:比如我们可以定制一种STATIC类型的过滤器,用来模拟生成返回给客户的response;

  1、创建过滤器类,继承ZuulFilter抽象类,实现该方法:

/**
 * @program: springcloud-example
 * @description:
 * @author:
 * @create: 2018-06-20 16:53
 **/
public class RequestLogFilter extends ZuulFilter {

    private Logger logger = LoggerFactory.getLogger(RequestLogFilter.class);

    /**
     * @Description: 返回过滤器类型,就是上面介绍的那几种类型
     * @Param:
     * @return:
     * @Author:
     * @Date: 2018/6/20
     */
    @Override
    public String filterType() {
        return "pre";
    }

    /**
     * @Description:指定过滤器执行的顺序
     * @Param:
     * @return:
     * @Author:
     * @Date: 2018/6/20
     */
    @Override
    public int filterOrder() {
        return 1;
    }

    /**
     * @Description:指定该过滤器是否执行
     * @Param:
     * @return:
     * @Author:
     * @Date: 2018/6/20
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }

    /** 
     * @Description: 过滤器的具体方法逻辑 
     * @Param:
     * @return:  
     * @Author:
     * @Date: 2018/6/20 
     */ 
    @Override
    public Object run() {
        RequestContext currentContext = RequestContext.getCurrentContext();
        HttpServletRequest request = currentContext.getRequest();
        String url = request.getRequestURL().toString();
        logger.info("请求URL:"+url);
        return null;
    }
}

  2、在启动类,将该过滤器注入到Spring容器中:

    @Bean
    public RequestLogFilter getRequestLogFilter() {
        return new RequestLogFilter();
    }

  3、分别启动 eureka-ribbon-servereureka-ribbon-clienteureka-ribbon-client2gateway-zuul测试:

参考书籍:《SpringCloud与Docker微服务架构实战》周力著

代码示例:https://gitee.com/lfalex/springcloud-exampleeureka-feign-hystrix-clienteureka-hystrix-clienteureka-ribbon-clienteureka-ribbon-client2eureka-ribbon-servergateway-zuul

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏AILearning

Apache Zeppelin 中 Hive 解释器

重要的提醒 Hive Interpreter将被弃用并合并到JDBC Interpreter中。您可以使用具有相同功能的JDBC解释器使用Hive Inte...

24810
来自专栏Hadoop实操

Redhat7.4安装CDH6.0_beta1时分发Parcel异常分析

Fayson在之前的文章中介绍过《如何在Redhat7.4安装CDH6.0.0_beta1》,但当安装CDH并分发Parcel时,浏览器端会报错Parcel的h...

1572
来自专栏数据之美

Hive 常见问题与技巧【Updating】

1Q: 是否有像类似于phpmyadmin一样的hive查询客户端,能以界面的方式查询hive语句和导出数据 A: 有的,客户端的话可以使用squirre...

1957
来自专栏Hadoop实操

Azkaban的使用及Command作业创建

温馨提示:要看高清无码套图,请使用手机打开并单击图片放大查看。 Fayson的github:https://github.com/fayson/cdhproje...

58610
来自专栏恰同学骚年

Hadoop学习笔记—13.分布式集群中节点的动态添加与下架

开篇:在本笔记系列的第一篇中,我们介绍了如何搭建伪分布与分布模式的Hadoop集群。现在,我们来了解一下在一个Hadoop分布式集群中,如何动态(不关机且正在运...

521
来自专栏小白鼠

HDFS基本特性常见命令工作机制

HDFS是一个分布式文件系统,采用分而治之的设计思想,将大文件、大批量文件,分布式存放在大量服务器上,为各类分布式运算框架(MapReduce,spark,te...

683
来自专栏MasiMaro 的技术博文

数据更新接口与延迟更新

title: 数据更新接口与延迟更新 tags: [OLEDB, 数据库编程, VC++, 数据库] date: 2018-02-12 14:29:35 ...

912
来自专栏简单聊聊Spark

Hadoop HA及Failover搭建

在Hadoop1.X版本中使用单个NameNode来管理所有的DataNode的元数据,一旦NameNode节点发生故障将导致整个集群不可用,而且必须手动恢复N...

672
来自专栏匠心独运的博客

消息中间件—Kafka数据存储(一)

摘要:消息存储对于每一款消息队列都非常重要,那么Kafka在这方面是如何来设计做到高效的呢? Kafka这款分布式消息队列使用文件系统和操作系统的页缓存(pa...

832
来自专栏Hadoop实操

如何实现CDH元数据库MySQL的主主互备

在前面Fayson讲过《如何实现CDH元数据库MySQL的主备》,而本篇文章介绍如何实现MySQL的双活方式,为后面基于Keepalived实现MySQL高可用...

4137

扫码关注云+社区