掌门教育微服务体系 Solar | 阿里巴巴 Nacos 企业级落地上篇

本文涉及的产品
应用实时监控服务-应用监控,每月50GB免费额度
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: 在高速发展的时候,公司规模越来越大,老师人数越来越多,这时候公司不能铺太多人去做运营与服务,必须提高每个人效,这就需要技术驱动。因此掌门教育转变成一家技术驱动型的公司,如果被迫成为一家靠资金驱动的公司就活不下去了。

头图.png

联席作者:吴毅挺 任浩军 张彬彬 廖梦鸽 张金星 胡振建
郑重鸣谢:Nacos - 彦林,Spring Cloud Alibab - 小马哥、落夜,Nacos 社区 - 张龙(pader)、春少(chuntaojun)

前言

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

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

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

背景故事

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

1)第一次生产事故

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

1.png

2.png

3.png

org.apache.catalina.connector.ClientAbortException: java.io.IOException: Broken pipe

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

4.png

5.png

2)第二次生产事故

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

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

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

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

6.png

7.png

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

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

官方介绍

1. Nacos 简介

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

  • Nacos Landscape

8.png

  • Nacos Map

9.jpg

摘自官网 What is Nacos:https://nacos.io/en-us/docs/what-is-nacos.html

2. Spring Cloud Alibaba 简介

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

10.png

摘自官网 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 开发篇

1. Nacos Server 落地

1)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 服务,并在用户首次登录时记录用户信息。

2)Nacos Server 界面

  • Nacos 界面权限

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

  • Nacos 界面显示服务概览

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

11.png

3)Nacos 监控

【Nacos Server 监控】

  • 标准监控

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

12.png

  • 高级监控

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

13.png

【Nacos Eureka Sync Etcd 监控】

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

14.png

4)Nacos 日志

  • 日志合并及 JSON 格式化

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

15.png

5)Nacos 告警

【Nacos Server 告警】

  • 业务服务上下线的告警

16、17.jpg

  • Nacos Eureka Sync 告警

18、19.jpg

  • 服务名大写告警

20、21.jpg

  • 业务服务同步完毕告警

22(1).jpg

2. Nacos Client 落地

1)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();
    }
}

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

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

23.png

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

  • Solar 蓝绿灰度发布

    • 版本匹配灰度发布
    • 版本权重灰度发布
  • Solar 多区域路由

    • 区域匹配灰度路由
    • 区域权重灰度路由
  • Solar 子环境隔离

    • 环境隔离
    • 环境路由
  • Solar 版本号和区域值,子环境号策略

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

Solar 蓝绿灰度发布架构图:

24.png

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

25.png

Solar 子环境隔离架构图:

26.png

更多功能参考:

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

Nepxion Discovery 开源社区:https://github.com/Nepxion/Discovery

3)Solar Nacos 集成 Sentinel

27.jpg

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

28.png

29.png

5)Solar Nacos 集成 Sentinel 埋点到 Skywalking

  • 微服务上的 Sentinel 埋点

30.jpg

31.jpg

  • 网关上的 Sentinel 埋点

32.jpg

33.jpg

6)Solar Nacos 集成 DevOps 发布平台

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

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

public class NacosApplicationContextInitializer implements EnvironmentPostProcessor {
    @Override
    public void postProcessEnvironment(ConfigurableEnvironment configurableEnvironment, SpringApplication springApplication) {
        Boolean bootstrapEnabled = configurableEnvironment.getProperty("devops.enabled", Boolean.class, false);
        if (bootstrapEnabled) {
            Properties properties = new Properties();
            properties.put("spring.cloud.nacos.discovery.instanceEnabled", "false");
            PropertiesPropertySource propertiesPropertySource = new PropertiesPropertySource("devopsEnabledNacosDiscoveryProperties", properties);
            MutablePropertySources mutablePropertySources = configurableEnvironment.getPropertySources();
            mutablePropertySources.addFirst(propertiesPropertySource);
        }
    }
}

spring.factories 配置文件:

org.springframework.boot.env.EnvironmentPostProcessor=\
com.ctrip.framework.cs.spring.NacosApplicationContextInitializer

7)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 技术栈的关系

34.jpg

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

35.jpg

【Solar SDK 接入】

  • 设置 Parent
<parent>
    <groupId>com.zhangmen</groupId>
    <artifactId>solar-parent</artifactId>
    <version>${solar.version}</version>
</parent>
  • 添加到 pom.xml

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

微服务:

<dependency>
    <groupId>com.zhangmen</groupId>
    <artifactId>solar-framework-starter-service</artifactId>
    <version>${solar.version}</version>
</dependency>

网关:

<dependency>
    <groupId>com.zhangmen</groupId>
    <artifactId>solar-framework-starter-zuul</artifactId>
    <version>${solar.version}</version>
</dependency>
  • 入口类添加注解

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

微服务:

@EnableSolarService
public class DemoApplication {
    public static void main(String[] args) {
        new SpringApplicationBuilder(DemoApplication.class).run(args);
    }
}

网关:

@EnableSolarZuul
public class DemoApplication {
    public static void main(String[] args) {
        new SpringApplicationBuilder(DemoApplication.class).run(args);
    }
}

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

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

36.png

作者信息

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

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

参与 Nacos 落地的基础架构部成员,包括:童子龙,张彬彬,廖梦鸽,张金星,胡振建,谢璐,谢庆芳,伊安娜

阿里巴巴云原生关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的公众号。”

相关文章
|
3月前
|
Cloud Native Java Nacos
微服务时代的新宠儿!Spring Cloud Nacos实战指南,带你玩转服务发现与配置管理,拥抱云原生潮流!
【8月更文挑战第29天】Spring Cloud Nacos作为微服务架构中的新兴之星,凭借其轻量、高效的特点,迅速成为服务发现、配置管理和治理的首选方案。Nacos(命名和配置服务)由阿里巴巴开源,为云原生应用提供了动态服务发现及配置管理等功能,简化了服务间的调用与依赖管理。本文将指导你通过五个步骤在Spring Boot项目中集成Nacos,实现服务注册、发现及配置动态管理,从而轻松搭建出高效的微服务环境。
261 0
|
11天前
|
网络安全 Nacos 开发者
Nacos作为流行的微服务注册与配置中心,“节点提示暂时不可用”是常见的问题之一
Nacos作为流行的微服务注册与配置中心,其稳定性和易用性备受青睐。然而,“节点提示暂时不可用”是常见的问题之一。本文将探讨该问题的原因及解决方案,帮助开发者快速定位并解决问题,确保服务的正常运行。通过检查服务实例状态、网络连接、Nacos配置、调整健康检查策略等步骤,可以有效解决这一问题。
24 4
|
11天前
|
Java 网络安全 Nacos
Nacos作为流行的微服务注册与配置中心,其稳定性和易用性备受青睐。
Nacos作为流行的微服务注册与配置中心,其稳定性和易用性备受青睐。然而,实际使用中常遇到“客户端不发送心跳检测”的问题。本文深入探讨该问题的原因及解决方案,帮助开发者快速定位并解决问题,确保服务正常运行。通过检查客户端配置、网络连接、日志、版本兼容性、心跳策略、注册状态、重启应用和环境变量等步骤,系统地排查和解决这一问题。
31 3
|
11天前
|
安全 Nacos 数据库
Nacos是一款流行的微服务注册与配置中心,但直接暴露在公网中可能导致非法访问和数据库篡改
Nacos是一款流行的微服务注册与配置中心,但直接暴露在公网中可能导致非法访问和数据库篡改。本文详细探讨了这一问题的原因及解决方案,包括限制公网访问、使用HTTPS、强化数据库安全、启用访问控制、监控和审计等步骤,帮助开发者确保服务的安全运行。
26 3
|
29天前
|
Java Nacos 微服务
微服务中间件之Nacos
Nacos是阿里巴巴开源的动态服务发现、配置管理和服务管理平台,支持服务注册与发现、配置管理及服务健康监测。采用Spring Cloud、Spring Boot、Raft算法等技术,适用于微服务架构和云原生应用,提供简单易用的安装部署方式和丰富的应用场景。
142 2
|
1月前
|
负载均衡 算法 Nacos
SpringCloud 微服务nacos和eureka
SpringCloud 微服务nacos和eureka
61 0
|
3月前
|
Cloud Native Java Nacos
微服务注册中心-Nacos概述
该博客文章提供了对Nacos的全面概述,包括其基本介绍、与Spring Cloud集成的优势、主要功能以及如何在Spring Cloud Alibaba项目中作为服务注册中心使用Nacos。文章解释了Nacos是一个动态服务发现、配置管理和服务管理平台,支持服务发现、健康监测、动态配置、DNS服务和元数据管理。还介绍了如何下载和启动Nacos服务器,以及如何将微服务注册到Nacos中,包括修改pom.xml文件引入依赖、配置application.properties文件和使用@EnableDiscoveryClient注解开启服务注册发现功能。
微服务注册中心-Nacos概述
|
3月前
|
JSON Nacos 开发工具
微服务通过nacos实现动态路由
微服务通过nacos实现动态路由
79 7
|
3月前
|
存储 供应链 Nacos
Nacos Stream 引领微服务异步消息潮流,为数字化转型保驾护航,你跟上了吗?
【8月更文挑战第29天】在微服务架构中,异步消息处理框架至关重要。Nacos Stream 通过可靠的消息传递机制、优秀的扩展性及灵活的消息过滤与路由功能,在电商系统等场景下展现了巨大价值。其简化了开发过程,支持高并发消息处理,确保了微服务系统的稳定运行与平滑扩展,为复杂系统的构建提供了强有力的消息通信保障。
34 0
|
3月前
|
Kubernetes Nacos 微服务
【技术难题破解】Nacos v2.2.3 + K8s 微服务注册:强制删除 Pod 却不消失?!7步排查法+实战代码,手把手教你解决Nacos Pod僵死问题,让服务瞬间满血复活!
【8月更文挑战第15天】Nacos作为微服务注册与配置中心受到欢迎,但有时会遇到“v2.2.3 k8s 微服务注册nacos强制删除 pod不消失”的问题。本文介绍此现象及其解决方法,帮助开发者确保服务稳定运行。首先需检查Pod状态与事件、配置文件及Nacos配置,确认无误后可调整Pod生命周期管理,并检查Kubernetes版本兼容性。若问题持续,考虑使用Finalizers、审查Nacos日志或借助Kubernetes诊断工具。必要时,可尝试手动强制删除Pod。通过系统排查,通常能有效解决此问题。
73 0