写点什么

Nacos 企业级落地实践

  • 2020-08-05
  • 本文字数:6852 字

    阅读完需:约 22 分钟

Nacos 企业级落地实践

前言

在高速发展的时候,公司规模越来越大,老师人数越来越多,这时候公司不能铺太多人去做运营与服务,必须提高每个人效,这就需要技术驱动。因此掌门教育转变成一家技术驱动型的公司,如果被迫成为一家靠资金驱动的公司就活不下去了。


——张翼(掌门教育创始人兼 CEO)


掌门教育自 2014 年正式转型在线教育以来,秉承“让教育共享智能,让学习高效快乐”的宗旨和愿景,经历云计算、大数据、人工智能、 AR / VR / MR 以及现今最火的 5G ,一直坚持用科技赋能教育。掌门教育的业务近几年得到了快速发展,特别是今年的疫情,使在线教育成为了新的风口,也给掌门教育新的机遇。


随着业务规模进一步扩大,流量进一步暴增,微服务数目进一步增长,使老的微服务体系所采用的注册中心 Eureka 不堪重负,同时 Spring Cloud 体系已经演进到第二代,第一代的 Eureka 注册中心已经不大适合现在的业务逻辑和规模,同时它目前被 Spring Cloud 官方置于维护模式,将不再向前发展。如何选择一个更为优秀和适用的注册中心,这个课题就摆在了掌门人的面前。经过对 Alibaba Nacos 、HashiCorp Consul 等开源注册中心做了深入的调研和比较,最终选定 Alibaba Nacos 做微服务体系 Solar 中的新注册中心。

背景故事

掌门教育微服务面临的挑战

第一次生产事故

2020 年疫情爆发后的几个月后,掌门教育的微服务实例数比去年猛增 40% ,基础架构部乐观的认为注册中心 Eureka 服务器可以抗住该数量级的实例数规模, Eureka 服务器在阿里云 PROD 环境上执行三台 8C16G 普通型机器三角结构型对等部署,运行了好几年都一直很稳定,但灾难还是在 2020 年 3 月某天晚上降临,当天晚上大概 9 点 30 分左右,其中两台 Eureka 服务器无征兆的 CPU 占用迅速上升到 100%,同时大量业务服务掉线,告警系统被触发,钉钉机器人告警和邮件告警铺天盖地而来。基础架构部和运维部紧急重启 Eureka 服务器,但没多久,CPU 依旧没抗住,而且更加来势凶猛,打开的文件描述符数瞬间达到 8000+ ,TCP 连接达到 1 万+ ,业务服务和 Eureka 服务器的通信产生大面积的 TCP CLOSE_WAIT 事件,且伴有大量 Broken pipe 异常。





org.apache.catalina.connector.ClientAbortException: java.io.IOException: Broken pipe
复制代码


运维人员尝试把机器升级成增强型 8C16G ,折腾一番后,于 23:00 左右恢复正常。



第二次生产事故

微服务实例数依旧在增长, Eureka 服务器平稳运行了大概半个月后,灾难又一次降临,CPU 再次飙升到 100%,过程就不表述了。处理方式,把机器升级成增强型 16C32G,并把 Eureka 服务器的版本升级到 Spring Cloud Hoxton 版,并优化了它的一些配置参数,尔后事件再也没出现。

掌门教育新微服务演进思考

虽然 Eureka 服务器目前运行平稳,但我们依旧担心此类事故在未来会再次发生,于是痛定思痛,经过深入的调研和比较一段时间后,通过由基础架构部牵头,各大业务线负责人和架构师参与的专项注册中心架构评审会上,CTO 拍板,做出决议:选择落地 Alibaba Nacos 作为掌门教育的新注册中心。


Talk is cheap,show me the solution。基础架构部说干就干,Nacos 部署到 FAT 环境后,打头阵的是测试组的同学,对 Nacos 做全方位的功能和性能测试,毕竟 Nacos 是阿里巴巴拳头开源产品,迭代了 2 年多,在不少互联网型和传统型公司都已经落地,我们选择了稳定的 1.2.1 版本,得出结论是功能稳定,性能上佳,关于功能和性能方面的相关数据,具体参考后续:《掌门教育微服务体系 Solar | 阿里巴巴 Nacos 企业级落地下篇》。




但是,如何迁移 Eureka 上的业务服务到 Nacos 上?业务服务实例数目众多,迁移工作量巨大,需要全公司业务部门配合,同时 Eureka 对注册的业务服务名大小写不敏感,而 Nacos 对注册的业务服务名大小写敏感,那么对于业务服务名不规范的业务部门需要改造。而对于基础架构部来说, Nacos Eureka Sync 方案如同一座大山横亘在我们面前,是首先需要迈过去的坎,纵观整个过程,该方案选型还是折腾了一番,具体参考后续:《掌门教育微服务体系 Solar | 阿里巴巴 Nacos 企业级落地中篇》。


阿里巴巴 Nacos 企业级落地的优化代码,在不久的将来会通过开源的方式回馈给业界。

官方介绍

Nacos 简介

阿里巴巴中间件部门开发的新一代集服务注册发现中心和配置中心为一体的中间件。它是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施,支持几乎所有主流类型的“服务”的发现、配置和管理,更敏捷和容易地构建、交付和管理微服务平台。


Spring Cloud Alibaba 简介

阿里巴巴中间件部门开发的 Spring Cloud 增强套件,致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。依托 Spring Cloud Alibaba ,您只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接入阿里微服务解决方案,通过阿里中间件来迅速搭建分布式应用系统。



摘自官网 Spring Cloud Alibaba Introduction:


https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-docs/src/main/asciidoc-zh/introduction.adoc


关于 Nacos 和 Spring Cloud Alibaba 如何使用,它的技术实现原理怎样等,官方文档或者民间博客、公众号文章等可以提供非常详尽且有价值的材料,这些不在本文的讨论范围内,就不一一赘述。笔者尝试结合掌门教育现有的技术栈以及中间件一体化的战略,并着眼于强大的 Nacos 和 Spring Cloud Alibaba 技术生态圈展开阐释。

Nacos 开发篇

Nacos Server 落地

Nacos Server

  • Nacos Server 环境和域名

  • 掌门的应用环境分为 4 套,DEV | FAT | UAT | PROD 分别对应开发、测试、准生产环境、生产环境,因此 Nacos Server 也分为 4 套独立环境。除了 DEV 环境是单机部署外,其他是集群方式部署。对外均以域名方式访问,包括 SDK 方式连接 Nacos Server 和访问 Nacos Server Dashboard 控制台页面。

  • Nacos Server 环境隔离和调用隔离

  • Nacos Server 可以创建不同的命名空间,做到同一个应用环境的基础上更细粒度的划分,隔离服务注册和发现。在某些场景下,开发本地有需要连接测试环境的 Nacos Server ,但其他测试服务不能调用到开发本地,这时候可以将 NacosDiscoveryProperties 的 enabled 属性设置为 false 。

  • Nacos Server 集成 Ldap

  • Nacos Server Dashboard 集成公司的 Ldap 服务,并在用户首次登录时记录用户信息。

Nacos Server 界面

  • Nacos 界面权限

  • Nacos Server Dashboard 用户首次登陆时,默认分配普通用户(即非 ROLE_ADMIN )角色,对查询以外的按钮均无操作权限,以免出现误操作导致服务非正常上下线。

  • Nacos 界面显示服务概览

  • Nacos Server Dashboard 页面增加服务总数及实例总数的统计,该信息每 5 秒刷新一次。


Nacos 监控

Nacos Server 监控
  • 标准监控

  • 基于公司现有的 Prometheus 、 Grafana 、 AlertManager 从系统层监控 Nacos。


  • 高级监控

  • 根据 Nacos 监控手册,结合 Prometheus 和 Grafana 监控 Nacos 指标。


  • Nacos Eureka Sync Etcd 监控

  • 从如下界面可以监控到,业务服务列表是否在同步服务的集群上呈现一致性 Hash 均衡分布。


Nacos 日志

  • 日志合并及 JSON 格式化

  • 将 Nacos 多模块的日志统一按 info 、 warn、error 级别合并,定义 schema 字段标记不同模块,按 JSON 格式滚动输出到文件,供 ELK 采集展示。


Nacos 告警

Nacos Server 告警
  • 业务服务上下线的告警

  • 业务服务上下线的告警业务服务灰度蓝绿的告警

  • Nacos Eureka Sync 告警

  • 待同步的业务服务列表服务增加的告警待同步的业务服务列表服务删除的告警

  • 服务名大写告警

  • 钉钉机器人上的告警掌控 APP 上的告警

  • 业务服务同步完毕告警

  • 钉钉机器人上的告警

Nacos Client 落地

Solar Nacos SDK 环境初始化

应用接入 Solar Nacos SDK 在启动时需要初始化完成 Nacos Server 的连接配置,即 spring.cloud.nacos.discovery.server-addr 参数的赋值。不同环境下连接的 Nacos Server ,因此需要读取机器所在的 env 环境参数,来选择相对应的 Nacos Server 地址。


初始化逻辑代码如下:


public class NacosClientConfigApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext>, Ordered {    private static final Logger logger = LoggerFactory.getLogger(NacosClientConfigApplicationContextInitializer.class);
@Override public void initialize(ConfigurableApplicationContext applicationContext) { try { Properties props = new Properties();
String path = isOSWindows() ? CommonConstant.SERVER_PROPERTIES_WINDOWS : CommonConstant.SERVER_PROPERTIES_LINUX; File file = new File(path); if (file.exists() && file.canRead()) { FileInputStream fis = new FileInputStream(file); if (fis != null) { try { props.load(new InputStreamReader(fis, Charset.defaultCharset())); } finally { fis.close(); } } }
String env = System.getProperty("env"); if (!isBlank(env)) { env = env.trim().toLowerCase(); } else { env = System.getenv("ENV"); if (!isBlank(env)) { env = env.trim().toLowerCase(); } else { env = props.getProperty("env"); if (!isBlank(env)) { env = env.trim(); } else { env = NacosEnv.DEV.getCode(); } } }
String serverAddr = NacosEnv.getValueByCode(env); Map<String, Object> nacosClientPropertySource = new HashMap<>(); nacosClientPropertySource.put(CommonConstant.NACOS_DISCOVERY_SERVER_ADDR, serverAddr);
applicationContext.getEnvironment().getPropertySources().addLast(new MapPropertySource("solarNacosClientPropertySource", nacosClientPropertySource)); } catch (Exception e) { logger.error(e.getMessage()); } }
@Override public int getOrder() { return Ordered.LOWEST_PRECEDENCE; }
private boolean isOSWindows() { String osName = System.getProperty("os.name"); return !isBlank(osName) && osName.startsWith("Windows"); }
private boolean isBlank(String str) { return Strings.nullToEmpty(str).trim().isEmpty(); }}
复制代码

Solar Nacos 蓝绿灰度发布和子环境隔离

在 Nacos 和 Eureka 双注册中心过渡状态下, Solar SDK 支持跨注册中心调用的蓝绿灰度发布和子环境功能。下面的图片,只以 Eureka 为例:



我们只需要把 Eureka SDK 换到 Nacos SDK 即可,实现如下功能:


  • Solar 蓝绿灰度发布

  • 版本匹配灰度发布

  • 版本权重灰度发布

  • Solar 多区域路由

  • 区域匹配灰度路由

  • 区域权重灰度路由

  • Solar 子环境隔离

  • 环境隔离

  • 环境路由

  • Solar 版本号和区域值,子环境号策略

  • DEV 环境,Git 插件自动创建灰度版本号

  • DevOps 环境设置


Solar 蓝绿灰度发布架构图



Solar 基于版本维度的蓝绿灰度发布架构图:



Solar 子环境隔离架构图:



更多功能参考:


掌门1对1微服务体系Solar第1弹:全链路灰度蓝绿发布智能化实践,掌门教育已经实现通过灰度蓝绿发布方式,实现对流量的精确制导和调拨。


Nepxion Discovery 开源社区:


https://github.com/Nepxion/Discovery

Solar Nacos 集成 Sentinel

Solar Nacos 集成灰度蓝绿埋点到 Skywalking


Solar Nacos 集成 Sentinel 埋点到 Skywalking

  • 微服务上的 Sentinel 埋点



  • 网关上的 Sentinel 埋点



Solar Nacos 集成 DevOps 发布平台

  • 集成携程 VI Cornerstone 实现服务拉入拉出

  • Solar Nacos SDK 的服务,在应用发布时需要做服务的拉入拉出,目的是为了发布时流量无损。掌门使用 VI Cornerstone 实现拉入拉出功能。具体实现是在初始化 NacosDiscoveryProperties 对象时设置 instance.enabled 属性值为 false,在服务完全初始化后,通过发布系统调用 Solar Nacos SDK 的 API 接口再修改为 true 来被外部发现并提供服务。

  • spring.factories 配置文件:

Solar Nacos SDK 接入

Solar 版本定义
  • Solar 2.3.x & 1.3.x,基于 Nacos SDK

  • Solar 2.2.x & 1.2.x,基于 Eureka SDK

Solar 版本关系
  • Solar 版本与 Spring Boot 技术栈的关系

  • 框架版本Spring Cloud版本Spring Boot版本Spring Cloud Alibaba版本
    2.x.xGreenwich2.1.x.RELEASE2.1.x.RELEASE
    1.x.xEdgware1.5.x.RELEASE1.5.x.RELEASE

  • Solar 版本与注册中心的关系

  • 框架版本支持的注册中心支持的Cornerstone(VI)版本
    1.0.x ~ 1.2.xEureka<= 0.2.4
    >= 1.3.xNacos>= 1.0.0
    2.0.x ~ 2.2.xEureka<= 0.2.4
    >= 2.3.xNacos>= 1.0.0

Solar SDK 接入:
  • 设置 Parent

  • 添加到 pom.xml

  • 只需引入一个 Jar 包,对接成本极低,只做基本组件封装,非常轻量级。

  • 微服务

  • 网关

  • 入口类添加注解

  • @EnableSolarService , @EnableSolarZuul 封装了标准 Spring Boot / Spring Cloud / Apollo 等大量注解,降低业务的使用成本。

  • 微服务

  • 网关

Solar Nacos SDK 和 Solar Eureka SDK 升级和回滚

升级和回滚方案非常简单,此方式同时适用于网关和服务,见下图:



作者介绍


吴毅挺 ,掌门技术副总裁,负责技术中台和少儿技术团队。曾就职于百度、eBay 、携程,曾任携程高级研发总监,负责从零打造携程私有云、容器云、桌面云和 PaaS 平台。


任浩军 ,掌门基础架构部负责人。曾就职于平安银行、万达、惠普,曾负责平安银行平台架构部 PaaS 平台 Halo 基础服务框架研发。10 多年开源经历,Github ID:@HaojunRen,Nepxion 开源社区创始人,Nacos Group Member,Spring Cloud Alibaba & Nacos & Sentinel& OpenTracing Committer。


本文转载自公众号阿里巴巴中间件(ID:Aliware_2018)。


原文链接


https://mp.weixin.qq.com/s?__biz=MzU4NzU0MDIzOQ==&mid=2247490123&idx=1&sn=10d7cd89bf43f07152513718c08dd80c&chksm=fdeb282bca9ca13d2ffb2128c2b5e1acfa5743c0cf835e266835cd5e0233bef5adbca896c8bd&scene=27#wechat_redirect


2020-08-05 10:064457

评论 3 条评论

发布
用户头像
这广告做的真好。
2020-08-06 16:06
回复
用户头像
为啥Nacos就比Eureka牛逼?这个是重点但没看到。。。
2020-08-06 13:36
回复
用户头像
这不就是个加机器的事儿吗.
多加几台机器,升级下机器配置.
2020-08-05 18:09
回复
没有更多了
发现更多内容

一文入门JVM虚拟机

Simon郎

深入理解JVM

LeetCode | 1. Two Sum 两数之和

Puran

Python C# 算法 LeetCode arts

谈谈控制感(13):为什么是旁观者清?

史方远

读书笔记 个人成长 心理学 随笔杂谈

带你学够浪:Go语言基础系列 - 8分钟学控制流语句

程序员柠檬

后台开发 Go 语言

【Sentry搭建之 docker-compose】

卓丁

DevOps Docker-compose CI/CD sentry

centos7分区命令parted的用法(大于2T)

唯爱

初识 LeetCode

Puran

LeetCode arts

【vue-openlayers】弹窗

德育处主任

html Vue 大前端 openlayers ol

坚持ARTS-week2

王钰淇

ARTS 打卡计划

工作的创新能力

punkboy

产品 重新理解创业 产品经理 创新突破 创新

ARTS打卡week#1

对方正在输入…

ARTS 打卡计划

程序员的晚餐 | 6 月 2 日 红烧鸡爪的味道

清远

美食

架构演变之路:为何要搞微服务架构?

帅旋

Kubernetes 微服务 dubbo SpringCloud

LeetCode | 2. Reverse Integer 整数反转

Puran

Python C# 算法 LeetCode arts

同一浏览器只允许登录一个账号

AR7

Vue 大前端

分布式事务 - 理论模型

Java收录阁

分布式事务

路漫漫其修远兮

无心水

洞悉MySQL底层架构:游走在缓冲与磁盘之间

帅旋

MySQL 数据库 MVCC

什么时候去面试

escray

微信小程序开发 | 如何在小程序中使用自定义 icon 图标

彭宏豪95

微信小程序 学习 编程 大前端 IT

重学 Java 设计模式:实战适配器模式

小傅哥

设计模式 小傅哥 重构 代码质量 代码坏味道

【译】5 个你需要知道的 JavaScript 小技巧

零和幺

Java 大前端 技巧

程序员都惧怕的故障域

松花皮蛋me

Java 问题处理

【大厂面试02期】Redis过期key是怎么样清理的?

NotFound9

Java 数据库 redis 架构 后端

Java 走过的创新25年

田晓旭

Java25周年

有的线程它死了,于是它变成一道面试题。

why技术

源码分析 面试 jdk源码 线程池

深入理解JVM内存管理 - 堆和栈

Skye

堆栈 深入理解JVM VM参数

ARTS 01 - 技术人的理想主义

jerry.mei

算法 Vue 练习 ARTS 打卡计划 ARTS活动

游戏夜读 | 如何管理公司?

game1night

SpringBatch系列入门之Tasklet

稻草鸟人

spring SpringBatch 批处理

Java 最新的JDK14.0.1调试成功

程李文华

Nacos 企业级落地实践_服务革新_基础架构部开发组_InfoQ精选文章