SpringCloud系列教程 | 第十七篇:服务网关Zuul基于Apollo动态路由

Springboot: 2.1.7.RELEASE

SpringCloud: Greenwich.SR2

上一篇文章我们介绍了Gateway基于Nacos动态网关路由的解决方案《Spring Cloud Alibaba | Gateway基于Nacos动态网关路由》,同为Spring Cloud服务网关组件的Spring Cloud Zuul在生产环境中使用更为广泛,那么它有没有方便的动态路由解决方案呢?答案当然是肯定的,Zuul作为一个老牌的开源服务网关组件,动态路由对它来讲是一个十分必要的功能,毕竟我们不能随便重启服务网关,服务网关是一个微服务系统的大门,今天我们介绍的Zuul动态路由的解决方案来自于携程开源的配置中心Apollo。

Apollo概述

Apollo(阿波罗)是携程框架部门研发的开源配置管理中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性。

Apollo支持4个维度管理Key-Value格式的配置:

  1. application (应用)
  2. environment (环境)
  3. cluster (集群)
  4. namespace (命名空间)

Apollo相比于Spring Cloud Config优势

前面的文章我们也介绍了Spring Cloud Config《跟我学SpringCloud | 第七篇:Spring Cloud Config 配置中心高可用和refresh》,但是它和我们今天要使用的相比,又有什么劣势呢?

Spring Cloud Config的精妙之处在于它的配置存储于Git,这就天然的把配置的修改、权限、版本等问题隔离在外。通过这个设计使得Spring Cloud Config整体很简单,不过也带来了一些不便之处。

功能点 Apollo Spring Cloud Config 备注
配置界面 一个界面管理不同环境、不同集群配置 无,需要通过git操作
配置生效时间 实时 重启生效,或手动refresh生效 Spring Cloud Config需要通过Git webhook,加上额外的消息队列才能支持实时生效
版本管理 界面上直接提供发布历史和回滚按钮 无,需要通过git操作
灰度发布 支持 不支持
授权、审核、审计 界面上直接支持,而且支持修改、发布权限分离 需要通过git仓库设置,且不支持修改、发布权限分离
实例配置监控 可以方便的看到当前哪些客户端在使用哪些配置 不支持
配置获取性能 快,通过数据库访问,还有缓存支持 较慢,需要从git clone repository,然后从文件系统读取
客户端支持 原生支持所有Java和.Net应用,提供API支持其它语言应用,同时也支持Spring annotation获取配置 支持Spring应用,提供annotation获取配置 Apollo的适用范围更广一些

工程实战

这里需要准备一个Apollo配置中心,具体如何构建Apollo配置中心我这里不多做介绍,大家可以参考Apollo的官方文档:https://github.com/ctripcorp/apollo/wiki

  1. 工程依赖pom.xml如下:

代码清单:chapter16/pom.xml


<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId>
<version>${apollo-client.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
  1. 配置文件

app.properties如下:

代码清单:chapter16/src/main/resources/META-INF/app.properties


app.id=123456789

这里配置的app.id是在Apollo中创建项目时配置的。

application.yml如下:

代码清单:chapter16/src/main/resources/application.yml


apollo:
bootstrap:
enabled: true
namespaces: zuul-config-apollo
Meta: http://localhost:8080

在Apollo上新建一个命名空间zuul-config-apollo

其余的配置都配置在Apollo中,具体如图:

  1. 启动主类Chapter16Application.java如下:

代码清单:chapter16/src/main/java/com/springcloud/chapter16/Chapter16Application.java


@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
@EnableApolloConfig
public class Chapter16Application { public static void main(String[] args) {
SpringApplication.run(Chapter16Application.class, args);
} }

其中@EnableZuulProxy表示开启Zuul网关代理,@EnableApolloConfig表示开启Apollo配置。

  1. 路由刷新

代码路径:chapter16/src/main/java/com/springcloud/chapter16/config/ZuulProxyRefresher.java


@Component
public class ZuulProxyRefresher implements ApplicationContextAware { private ApplicationContext applicationContext; @Autowired
private RouteLocator routeLocator; @ApolloConfigChangeListener(value = "zuul-config-apollo")
public void onChange(ConfigChangeEvent changeEvent) {
boolean zuulProxyChanged = false;
for (String changedKey : changeEvent.changedKeys()) {
if (changedKey.startsWith("zuul.")) {
zuulProxyChanged = true;
break;
}
}
if (zuulProxyChanged) {
refreshZuulProxy(changeEvent);
}
} private void refreshZuulProxy(ConfigChangeEvent changeEvent) {
this.applicationContext.publishEvent(new EnvironmentChangeEvent(changeEvent.changedKeys()));
this.applicationContext.publishEvent(new RoutesRefreshedEvent(routeLocator));
} @Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}

@ApolloConfigChangeListener(value = "zuul-config-apollo")中value的默认参数是application,因为这里我们自定义了namespace,所以需要指定,我们使用@ApolloConfigChangeListener监听Apollo的配置下发,有配置更新时会调用refreshZuulProxy()刷新路由信息。

  1. 测试

我们启动Client-Apollo工程和Zuul-Apollo工程,打开浏览器访问:http://localhost:9091/client/hello ,页面可以正常显示,我们在Apollo中修改路由信息,具体如图:

修改完后点击发布,待发布成功后,我们刷新浏览器,之前的路由访问已经报错404,我们使用修改过后的路由http://localhost:9091/client_new/hello ,页面可以正常显示Hello, i am dev from apollo update.,测试成功,我们通过Apollo实现了Zuul的路由信息动态刷新。

示例代码

Github-示例代码

Gitee-示例代码

跟我学SpringCloud | 第十七篇:服务网关Zuul基于Apollo动态路由的更多相关文章

  1. springcloud(十五):服务网关zuul

    前面的文章我们介绍了,Eureka用于服务的注册于发现,Feign支持服务的调用以及均衡负载,Hystrix处理服务的熔断防止故障扩散,Spring Cloud Config服务集群配置中心,似乎一个 ...

  2. springcloud(十六):服务网关zuul (2)

    Zuul的核心 Filter是Zuul的核心,用来实现对外服务的控制.Filter的生命周期有4个,分别是“PRE”.“ROUTING”.“POST”.“ERROR”,整个生命周期可以用下图来表示. ...

  3. 跟我学SpringCloud | 第三篇:服务的提供与Feign调用

    跟我学SpringCloud | 第三篇:服务的提供与Feign调用 上一篇,我们介绍了注册中心的搭建,包括集群环境吓注册中心的搭建,这篇文章介绍一下如何使用注册中心,创建一个服务的提供者,使用一个简 ...

  4. 跟我学SpringCloud | 第九篇:服务网关Zuul初

    SpringCloud系列教程 | 第九篇:服务网关Zuul初探 前面的文章我们介绍了,Eureka用于服务的注册于发现,Feign支持服务的调用以及均衡负载,Hystrix处理服务的熔断防止故障扩散 ...

  5. 跟我学SpringCloud | 第十篇:服务网关Zuul高级篇

    SpringCloud系列教程 | 第十篇:服务网关Zuul高级篇 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich.SR1 如无特殊说明,本系列教程全 ...

  6. springcloud(十一):服务网关Zuul高级篇

    时间过的很快,写springcloud(十):服务网关zuul初级篇还在半年前,现在已经是2018年了,我们继续探讨Zuul更高级的使用方式. 上篇文章主要介绍了Zuul网关使用模式,以及自动转发机制 ...

  7. 一起来学Spring Cloud | 第六章:服务网关 ( Zuul)

    本章节,我们讲解springcloud重要组件:微服务网关Zuul.如果有同学从第一章看到本章的,会发现我们已经讲解了大部分微服务常用的基本组件. 已经讲解过的: 一起来学Spring Cloud | ...

  8. 【SpringCloud构建微服务系列】微服务网关Zuul

    一.为什么要用微服务网关 在微服务架构中,一般不同的微服务有不同的网络地址,而外部客户端(如手机APP)可能需要调用多个接口才能完成一次业务需求.例如一个电影购票的手机APP,可能会调用多个微服务的接 ...

  9. Spring Cloud(十):服务网关 Zuul(路由)【Finchley 版】

    Spring Cloud(十):服务网关 Zuul(路由)[Finchley 版]  发表于 2018-04-23 |  更新于 2018-05-09 |  通过之前几篇 Spring Cloud 中 ...

随机推荐

  1. 免安装版tomcat安装成服务

    安装方式(前提已经安装好了jdk,并配置了环境量): (1) 下载非exe的tomcat zip包: (2) 解压缩,如:D:\tomcat: (3) 进入D:\tomcat\bin,修改servic ...

  2. JavaScript的event对象

    JavaScript的event对象中 event.target指代的是:触发事件的元素 event.currentTarget指代的是:事件绑定的元素 <!DOCTYPE html> & ...

  3. Java连载14-补码简介&浮点型整数

    一.补码简介 1.计算机中的符号数有三种表示方式,即为:原码.反码.补码.三种表示方法均有符号位和数值位,符号位都是0表示正数,符号位都是1表示负数. 2.计算机中的数字的存储方式:在计算机系统中,数 ...

  4. react学习(一)--JSX简介

    由于在中国银联实习的项目要用到react,所以不得不硬着头皮把react学习一下.这是要往全栈发展吗0.0 正文: 一个最简单的React例子如下, ReactDOM.render( <h1&g ...

  5. [zz] pomelo windows 环境下开发环境搭建

    原文链接:http://nodejs.netease.com/topic/515279a0b5a2705b5a000983 本文主要介绍下 windows 下跑通 pomelo 简单例子的过程 开发前 ...

  6. 通过Blazor使用C#开发SPA单页面应用程序(2)

    今天我们尝试创建一个默认的Blazor应用. 1.安装 .Net Core 3.0需要Visual Studio 2019 的支持. 安装.Net Core 3.0 预览版 SDK版本,注意预览版对应 ...

  7. 《机器学习技法》---线性SVM

    (本文内容和图片来自林轩田老师<机器学习技法>) 1. 线性SVM的推导 1.1 形象理解为什么要使用间隔最大化 容忍更多的测量误差,更加的robust.间隔越大,噪声容忍度越大: 1.2 ...

  8. 存在于文件名中的SQL手工注入

    SQL注入已经在前一章为大家介绍了个大概,本文将讲述我遇到的本以为是文件上传漏洞,却是以文件名触发的SQL注入! 本文分享的内容同样来自于一道CTF题! 1. 直接进入正题 (1) 初步探测 先看一下 ...

  9. 【KakaJSON手册】04_JSON转Model_04_值过滤

    在KakaJSON手册的第2篇文章中提过:由于JSON格式能表达的数据类型是比较有限的,所以服务器返回的JSON数据有时无法自动转换成客户端想要的数据类型 比如客户端想要的是Date类型,服务器返回的 ...

  10. Java 调用http接口(基于OkHttp的Http工具类方法示例)

    目录 Java 调用http接口(基于OkHttp的Http工具类方法示例) OkHttp3 MAVEN依赖 Http get操作示例 Http Post操作示例 Http 超时控制 工具类示例 Ja ...