微服务实战——Spring Cloud + Zuul Gateway + Eureka集成

上一篇简单说了SpringCloud与Eureka的集成。主要解决了微服务间的服务注册及调用的问题。这一篇集成Zuul,然后结合SpringCloud、Eureka、Zuul环境下进行真实系统联调,帮助更好的对这些组件的理解。毕竟,实战才是学习最快的方法。前端

1、聊聊网关

上篇也提到过,微服务下,各个业务模块都被拆分红相互独立的微服务。虽然注册中心(如Eureka)解决了服务内部的注册发现、健康检查等问题。可是如何与外部服务进行通讯又是一个新的问题了。git

举个栗子

某初创公司,刚刚经历了一次大的架构改革。将原有的单体架构分解成了不少的微服务进行独立部署。这些微服务包括用户鉴权系统、订单系统、定时任务系统等等。而原有的JSP也被改形成基于HTML下的静态页面进行先后端分离部署。github

那么问题来了,由于先后端是分开的,前端同窗在调用后端不一样服务时要定义各类不一样的URI进行调用,管理起来太麻烦,并且,这种状况下一旦后端服务邮编,有须要从新对域名进行解析,这也侧面增长了运维同窗的工做量。而更可怕的是这又与如今你们都在提倡的DevOps彻底相悖了。web

2、说了这么多我用Nginx不就好了么

是的,用Nginx的确是能帮助解决服务统一入口的问题。可是由于Nginx比较偏运维性质,并且其路由配置所有都是基于配置文件的硬编码方式进行处理。一旦后台服务发生变化,配置也须要及时更改。这样也没有彻底解决上述问题。spring

这时候,网关的出现让我看到了曙光。经过服务名就能够进行路由转发,熔断限流,日志监控,最主要的是能够开发人员本身经过配置就能轻松实现,不用每次都求运维人员去作解析。这样岂不是也是更符合DevOps了呢。segmentfault

3、Zuul

Zuul简单介绍

Zuul在英文中是怪兽的意思,寓意看门神兽。由大名鼎鼎的Netflix开源。并被Pivotal集成入Spring Cloud体系。当前流行的为1.X与2.X系列。主要区别为Zuul从2.X系列开始采用非阻塞异步模式,大大提高了其性能。他是基于filter机制进行工做。有统一入口、健康检查、蓝绿部署、金丝雀发布、日志监控、路由转发等功能。也可集成Ribbon、Hystrix增长负载均衡、熔断的功能。后端

Zuul架构

20200119214049

Spring Cloud Zuul

实际开发中能够根据选择去集成Zuul网关。也可直接选择Spring集成好的Spring Cloud Zuul方便更快的使用起来。本篇重点是集成Spring Cloud Zuul。api

关于Spring Cloud Zuul与Netflix Zuul相比仍是有些许不同的。他是基于SpringBoot + Netflix Zuul内核而成,去掉了原有的动态过滤器加载。因此生产环境中仍是根据须要本身选择。浏览器

4、话很少说请看代码

老规矩,附上源码地址SpingCloud+Zuul+Eureka

操做步骤

  • 仍是在原来的spring-cloud-demo(上一篇地址SpringCloud+Eureka)项目上,右键建立一个新的model.具体步骤再也不赘述。建立完成后项目结构以下:
    20200119215800
  • 引入Zuul依赖
    主要依赖以下:架构

    <!-- 引入Zuul starter -->
    <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
      </dependency>
      <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter</artifactId>
      </dependency>
      <!-- 链接Eureka -->
      <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
      </dependency>
  • 建立业务模块provider、consumer,方法跟上一步同样。建立后项目结构以下:
    20200119220736

    • 其中provider为服务提供者,提供基础服务的微服务
    • consumer为服务的主要调用者。下一章会讲服务之间基于接口(Feign)的调用
  • 配置Zuul路由转发以及ribbon、hystrix

    spring.application.name = zuul-gateway
      logging.level.org.spring.framework.security = INFO
      #hystrix设置 时间要大于Ribbon时间总和
      hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds = 90000
      eureka.instance.instance-id = ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
      eureka.client.serviceUrl.defaultZone = http://localhost:8761/eureka/
      #经过eureka发现的服务。使用ribbon
      ribbon.ReadTimeout = 20000
      ribbon.ConnectTimeout = 20000
      zuul.ignoredServices = '*'
      #设置不走ribbon的time-out时间
      zuul.host.connect-timeout-millis = 20000
      zuul.host.socket-timeout-millis = 20000
      #只要访问以/api/开头的多层目录均可以路由到服务名为kxtop-provider的服务上.
      zuul.routes.kxtop-provider.path = /api/**
      zuul.routes.kxtop-provider.service-id= kxtop-provider
      zuul.routes.kxtop-provider.stripPrefix = false
      #kxtop-consumer配置
      zuul.routes.kxtop-consumer.path = /consumer/**
      zuul.routes.kxtop-consumer.service-id = kxtop-consumer
      zuul.routes.kxtop-consumer.stripPrefix = false
      server.port = 4000
      management.endpoints.web.exposure.include = *
  • 建立Zuul启动类

    @EnableDiscoveryClient  //做为Eureka发现者
      @EnableZuulProxy        //开启Zuul
      @SpringBootApplication
      public class ZuulGatewayApplication {
    
          public static void main(String[] args) {
              SpringApplication.run(ZuulGatewayApplication.class);
          }
      }
  • 分别配置provider、consumer配置文件及启动类

    provider

    spring.application.name = kxtop-provider
    server.port = 5000
    eureka.instance.instance-id = ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}eureka.client.serviceUrl.defaultZone = http://localhost:8761/eureka/
    logging.level.org.spring.framework.security = INFO
    server.servlet.context-path = /api
    management.endpoints.web.exposure.include = *
    -------------------------
    
    @EnableDiscoveryClient
    @SpringBootApplication
    public class ProviderApplication {
        public static void main(String[] args) {
            SpringApplication.run(ProviderApplication.class);
        }
    }

    consumer

    spring.application.name = kxtop-consumer
    server.port = 6000
    eureka.instance.instance-id = ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}eureka.client.serviceUrl.defaultZone = http://localhost:8761/eureka/
    
    logging.level.org.spring.framework.security = INFO
    server.servlet.context-path = /consumer
    management.endpoints.web.exposure.include = *
    --------------------------
    
    @EnableDiscoveryClient
    @SpringBootApplication
    public class ConsumerApplication {
        public static void main(String[] args) {
            SpringApplication.run(ConsumerApplication.class);
        }
    }
  • 总体测试

    1. 启动Eureka并浏览器打开localhost:8761
      20200119222937
    2. 分别启动项目Zuul、provider、consumer
      20200119223556

      • 保证每一个服务都正常运行
      • 服务端口对照

        服务名 端口号
        zuul-gateway 4000
        provider 5000
        consumer 6000
    3. 刷新浏览器查看效果(能够看到,服务都已经注册成功且处于UP状态)
      20200119224623
    4. postman测试网关调用

      • provider模块新建TestGatewayController,并重启provider

        @RestController
          @RequestMapping("/test-gateway")
            public class TestGatewayController {
                @GetMapping
                public String testGateway() {
                    return "Hi! 我是Consumer服务中的TestGatewayController.";
                }
            }
      • 访问localhost:4000/api/test-gateway

        20200119225241

      • 出现上面这句话,访问成功。请注意:咱们访问的是localhost的4000 端口,也就是配置的Zuul的端口哦,而输出【Hi! 我是Consumer服务中的TestGatewayController】这句话的方法则是在端口为5000的consumer模块中定义的。这就就证实咱们以配置的网关和服务注册发现是正确的。固然你也能够作更多的测试。

5、后续

下一篇会针对以上的整合作更加详细的配置,咱们会基于ZuulGateway去作更丰富测试(好比provider、consumer模块若是是部署集群网关该怎样处理?他们之间的负载均衡策略又是怎样的?链接超时、恶意访问怎样作熔断限流?服务之间如何调用?),进行接近生产级项目的配置。敬请关注!

持续学习,记录点滴。更多请点击查看原文

相关文章
相关标签/搜索