apollo集群部署_ribbon+apollo实现灰度发布
一、前言
在一般情况下,升级服务器端应用,需要将应用源码或程序包上传到服务器,然后停止掉老版本服务,再启动新版本。但是这种简单的发布方式存在两个问题,一方面,在新版本升级过程中,服务是暂时中断的,另一方面,如果新版本有BUG,升级失败,回滚起来也非常麻烦,容易造成更长时间的服务不可用。
二、Apollo简介
Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。
三、场景介绍
大致的场景如下,消费端通过gateway访问提供端,提供端为集群部署(A1、A2),我们部署新应用时让所有流量都切换到A1,我们部署A2。当A2部署完成后我们切换部分流量到A2无异常后我们再切换部署A1,这样我们就能实现不停机发布。
四、实现过程
1.配置提供端eureka元数据:
需要实现灰度发布我们需要用到Eureka注册中心的特性,Eureka的元数据有两种:标准元数据和自定义元数据,这里我们用到了自定义元数据,自定义元数据可以使用eureka.instance.metadata-map配置,这些元数据可以在远程客户端中访问,但一般不会改变客户端的行为,除非客户端知道该元数据的含义,例如将提供端集群(A1、A2)分别添加如下配置:
A1:
eureka.instance.metadata-map.group-name=server01
A2:
eureka.instance.metadata-map.group-name=server02
2.Apollo配置中心新增灰度配置:
apollo如何搭建及配置灰度这里就不做介绍官网有详细的文档说明,配置完成后如下图:
将灰度配置和主配置分别指定集群的不同主机,这样我们的eureka自定义元数据就推送到了相应的服务端。
3.自定义Ribbon规则
在spring cloud Gateway网关中我们自定义Ribbon负载均衡的规则,利用eureka自定义元数据的特性,我们可以在ribbon中获取远程服务的元数据配置,在网关gateway中我们增加如下两项配置:
# 指定当前流量引流的集群名称eureka.instance.metadata-map.group-name=server01#将规则应用到哪些服务eureka.instance.metadata-map.gray-server-name=wxt-k3-provider、wxt-act-provider
通过在apollo上我们可以实现动态的切换,将请求流量转发到group-name指定的集群。
Ribbon自定义配置相关代码如下,主要实现了如下两点:
1.获取远程服务的自定义元数据配置。
2.获取网关自定义灰度规则。
2.远端服务配置与gateway配置比较如果一致将流量发送到对应服务。
public class RibbonFilter extends AbstractLoadBalancerRule {/**服务分组[all,server01,server02]*/@Value("${eureka.instance.metadata-map.group-name}")private String appGroupName;/**灰度服务[all:所有服务,none:不进行灰度,uaf-k3-provider,uaf-intellicredit-provider:指定服务]*/@Value("${eureka.instance.metadata-map.gray-server-name}")private String grayServerName;/**初始随机规则*/Random rand = new Random();@Overridepublic void initWithNiwsConfig(IClientConfig iClientConfig) {}@Overridepublic Server choose(Object o) {/**可用服务*/List upList = getLoadBalancer().getReachableServers();/**所有服务*/List allList = getLoadBalancer().getAllServers();/**服务数*/int serverCount = allList.size();if (serverCount == 0) {return null;}/**服务名称*/String serverName = ((DiscoveryEnabledServer) upList.get(0)).getInstanceInfo().getAppName();/**判定是否进入灰度流程*/if ("all".equalsIgnoreCase(grayServerName) && !appGroupName.equalsIgnoreCase("all")) {return grayStrategy(upList);} else if (grayServerName.toUpperCase().contains(serverName) && !appGroupName.equalsIgnoreCase("all")) {return grayStrategy(upList);} else {int index = this.rand.nextInt(serverCount);return upList.get(index);}}/** * 灰度调用规则 * @param upList eureka可用服务列表 */public Server grayStrategy(List upList) {for (Server server : upList) {/**服务分组*/String upAppGroupName = ((DiscoveryEnabledServer) server).getInstanceInfo().getMetadata().get("group-name");if (appGroupName.equals(upAppGroupName)) {MySlf4j.textInfo("进入灰度规则,服务地址:{0},集群组:{1}", server.getHost(), upAppGroupName);return server;}}return null;}}
自此我们完成了灰度部署相关的配置,通过分布式配置中心apollo,我们可以实现不停机维护。
apollo集群部署_ribbon+apollo实现灰度发布相关推荐
- apollo集群部署_egg框架对接Apollo
Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境.不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限.流程治理等特性,适用于微服务配置管理场景.具有 ...
- ASP.NET Core应用程序容器化、持续集成与Kubernetes集群部署(二)
在上文中我介绍了ASP.NET Core应用程序容器化时需要注意的几个问题,并给出了一个案例应用程序:tasklist.今天接着上文的内容,继续了解一下如何使用Azure DevOps进行ASP.NE ...
- Docker 进阶,Docker 集群部署
Docker 集群 Docker Compose 简介 DockerFile build run 手动操作,单个容器! 如果是微服务,100个微服务!各种依赖关系 Docker Compose 可以轻 ...
- Kylin集群部署和cube使用
Kylin集群部署和cube使用 安装集群环境 节点 Kylin节点模式 Ip 内存 磁盘 Node1 All 192.167.71.11 2G 80G Node2 query 192.168.71. ...
- 堡垒机jumpserver集群部署
本文参考老广二次开发后的堡垒机部署方案,在此基础上进行集群部署,提高其可靠性.尽管国外已经有类似的功能的堡垒机的发布,但是还是要感谢老广在百忙之中开发出更加实用的堡垒机. 本文内容虽然亲测,但内容难免 ...
- 百度开源联邦学习框架 PaddleFL:简化大规模分布式集群部署
百度开源联邦学习框架 PaddleFL:简化大规模分布式集群部署 作者 | 钰莹近两年,联邦学习技术发展迅速.作为分布式的机器学习范式,联邦学习能够有效解决数据孤岛问题,让参与方在不共享数据的基础上联 ...
- 手动安装K8s第三节:etcd集群部署
手动安装K8s第三节:etcd集群部署 准备安装包 https://github.com/coreos/etcd 版本:3.2.18 wget https://github.com/coreos/et ...
- zookeeper+kafka集群部署+storm集群
zookeeper+kafka集群部署+storm集群 一.环境安装前准备: 准备三台机器 操作系统:centos6.8 jdk:jdk-8u111-linux-x64.gz zookeeper:zo ...
- Linux集群部署和ipvsadm命令的使用
在日常的使用中,一台服务器足够胜任很多的工作,但是当很多人同时访问的时候就会显得稍有些无力,这个时候.可以有两种解决的方法,第一种是不断的改善这台服务器的性能,但是总是会有一个上限存在,而且提升的效果 ...
最新文章
- 肠菌亦“醉”人 | 中国团队登Cell子刊,发现60%的非酒精性脂肪肝与肠道菌有关,携带者体内酒精可达健康人4-6倍...
- 小白入门:大型网站技术架构负载均衡技术介绍及学习资源推荐
- Installing python 2.7 on centos 6.3.
- 动态代理之: com.sun.proxy.$Proxy0 cannot be cast to 问题
- thinkphp中如何使用PHP函数,如何在ThinkPHP中使用函数进行回调
- Java Float类详解
- C++11 override 和 final 关键字
- 一份招聘需求的分析 (转载)
- 装载list的时候 一定要把每一个实体放到for里面
- 2022泰迪杯数据挖掘挑战赛C题思路及赛后总结
- 软件项目管理总结(全)
- C语言--- 什么是位域?
- iOS开发之Crash分析,以及收集
- / 和 /* 的区别
- Android 悬浮窗口(及解决6.0以上无法显示问题)
- 我的世界java版如何装mod_我的世界MOD安装详解教程 全方位介绍MOD
- c语言 python java css,从零起步学编程 Python篇 Java篇 C#篇 CSS篇 全4册
- Mixly 触摸开关的使用
- ES6 语法糖(一)
- 大学物理第一章 质点运动学详解
热门文章
- StackExchange.Redis通用封装类分享(转)
- 解决Git中fatal: refusing to merge unrelated histories(亲测)
- Maven环境配置及IntelliJ IDEA中的Maven部署(亲自测试)
- 【php】使用gdb调试php程序
- redis报错(error) LOADING Redis is loading the dataset in memory
- 为VMware虚拟机中的Linux系统设置固定IP的方法
- ELK:kibana使用的lucene查询语法
- 从数据结构角度分析foreach效率比for循环高的原因
- Go的sync.Mutex(七):互斥锁锁定一个资源 只有一个协程操作其他等待
- PHP的引用传值值传递