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

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

一、聊聊网关

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

举个栗子

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

那么问题来了,因为前后端是分开的,前端同学在调用后端不同服务时要定义各种不同的URI进行调用,管理起来太麻烦,而且,这种情况下一旦后端服务邮编,有需要重新对域名进行解析,这也侧面增加了运维同学的工作量。而更可怕的是这又与现在大家都在提倡的DevOps完全相悖了。

二、说了这么多我用Nginx不就行了么

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

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

三、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。

关于Spring Cloud Zuul与Netflix Zuul相比还是有些许不一样的。他是基于SpringBoot + Netflix Zuul内核而成,去掉了原有的动态过滤器加载。所以生产环境中还是根据需要自己选择。

四、话不多说请看代码

老规矩,附上源码地址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模块中定义的。这就就证明我们以配置的网关和服务注册发现是正确的。当然你也可以做更多的测试。

五、后续

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

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,718评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,683评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,207评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,755评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,862评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,050评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,136评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,882评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,330评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,651评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,789评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,477评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,135评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,864评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,099评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,598评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,697评论 2 351

推荐阅读更多精彩内容