掌门教育微服务体系 Solar | 阿里巴巴 Nacos 企业级落地上篇
聯(lián)席作者:吳毅挺 任浩軍 張彬彬 廖夢(mèng)鴿 張金星 胡振建
鄭重鳴謝:Nacos - 彥林,Spring Cloud Alibab - 小馬哥、落夜,Nacos 社區(qū) - 張龍(pader)、春少(chuntaojun)
前言
在高速發(fā)展的時(shí)候,公司規(guī)模越來越大,老師人數(shù)越來越多,這時(shí)候公司不能鋪太多人去做運(yùn)營與服務(wù),必須提高每個(gè)人效,這就需要技術(shù)驅(qū)動(dòng)。因此掌門教育轉(zhuǎn)變成一家技術(shù)驅(qū)動(dòng)型的公司,如果被迫成為一家靠資金驅(qū)動(dòng)的公司就活不下去了。
– 張翼(掌門教育創(chuàng)始人兼 CEO)
掌門教育自 2014 年正式轉(zhuǎn)型在線教育以來,秉承“讓教育共享智能,讓學(xué)習(xí)高效快樂”的宗旨和愿景,經(jīng)歷云計(jì)算、大數(shù)據(jù)、人工智能、 AR / VR / MR 以及現(xiàn)今最火的 5G ,一直堅(jiān)持用科技賦能教育。掌門教育的業(yè)務(wù)近幾年得到了快速發(fā)展,特別是今年的疫情,使在線教育成為了新的風(fēng)口,也給掌門教育新的機(jī)遇。
隨著業(yè)務(wù)規(guī)模進(jìn)一步擴(kuò)大,流量進(jìn)一步暴增,微服務(wù)數(shù)目進(jìn)一步增長,使老的微服務(wù)體系所采用的注冊(cè)中心 Eureka 不堪重負(fù),同時(shí) Spring Cloud 體系已經(jīng)演進(jìn)到第二代,第一代的 Eureka 注冊(cè)中心已經(jīng)不大適合現(xiàn)在的業(yè)務(wù)邏輯和規(guī)模,同時(shí)它目前被 Spring Cloud 官方置于維護(hù)模式,將不再向前發(fā)展。如何選擇一個(gè)更為優(yōu)秀和適用的注冊(cè)中心,這個(gè)課題就擺在了掌門人的面前。經(jīng)過對(duì) Alibaba Nacos 、HashiCorp Consul 等開源注冊(cè)中心做了深入的調(diào)研和比較,最終選定 Alibaba Nacos 做微服務(wù)體系 Solar 中的新注冊(cè)中心。
背景故事
1. 掌門教育微服務(wù)面臨的挑戰(zhàn)
1)第一次生產(chǎn)事故
2020 年疫情爆發(fā)后的幾個(gè)月后,掌門教育的微服務(wù)實(shí)例數(shù)比去年猛增 40% ,基礎(chǔ)架構(gòu)部樂觀的認(rèn)為注冊(cè)中心 Eureka 服務(wù)器可以抗住該數(shù)量級(jí)的實(shí)例數(shù)規(guī)模, Eureka 服務(wù)器在阿里云 PROD 環(huán)境上執(zhí)行三臺(tái) 8C16G 普通型機(jī)器三角結(jié)構(gòu)型對(duì)等部署,運(yùn)行了好幾年都一直很穩(wěn)定,但災(zāi)難還是在2020年3月某天晚上降臨,當(dāng)天晚上大概 9 點(diǎn) 30 分左右,其中兩臺(tái) Eureka 服務(wù)器無征兆的 CPU 占用迅速上升到100%,同時(shí)大量業(yè)務(wù)服務(wù)掉線,告警系統(tǒng)被觸發(fā),釘釘機(jī)器人告警和郵件告警鋪天蓋地而來。基礎(chǔ)架構(gòu)部和運(yùn)維部緊急重啟 Eureka 服務(wù)器,但沒多久,CPU 依舊沒抗住,而且更加來勢(shì)兇猛,打開的文件描述符數(shù)瞬間達(dá)到 8000+ ,TCP 連接達(dá)到 1 萬+ ,業(yè)務(wù)服務(wù)和 Eureka 服務(wù)器的通信產(chǎn)生大面積的 TCP CLOSE_WAIT 事件,且伴有大量 Broken pipe 異常。
org.apache.catalina.connector.ClientAbortException: java.io.IOException: Broken pipe運(yùn)維人員嘗試把機(jī)器升級(jí)成增強(qiáng)型 8C16G ,折騰一番后,于 23:00 左右恢復(fù)正常。
2)第二次生產(chǎn)事故
微服務(wù)實(shí)例數(shù)依舊在增長, Eureka 服務(wù)器平穩(wěn)運(yùn)行了大概半個(gè)月后,災(zāi)難又一次降臨,CPU 再次飆升到100%,過程就不表述了。處理方式,把機(jī)器升級(jí)成增強(qiáng)型 16C32G,并把 Eureka 服務(wù)器的版本升級(jí)到 Spring Cloud Hoxton 版,并優(yōu)化了它的一些配置參數(shù),爾后事件再也沒出現(xiàn)。
2. 掌門教育新微服務(wù)演進(jìn)思考
雖然 Eureka 服務(wù)器目前運(yùn)行平穩(wěn),但我們依舊擔(dān)心此類事故在未來會(huì)再次發(fā)生,于是痛定思痛,經(jīng)過深入的調(diào)研和比較一段時(shí)間后,通過由基礎(chǔ)架構(gòu)部牽頭,各大業(yè)務(wù)線負(fù)責(zé)人和架構(gòu)師參與的專項(xiàng)注冊(cè)中心架構(gòu)評(píng)審會(huì)上,CTO 拍板,做出決議:選擇落地 Alibaba Nacos 作為掌門教育的新注冊(cè)中心。
Talk is cheap,show me the solution。基礎(chǔ)架構(gòu)部說干就干,Nacos 部署到 FAT 環(huán)境后,打頭陣的是測(cè)試組的同學(xué),對(duì) Nacos 做全方位的功能和性能測(cè)試,畢竟 Nacos 是阿里巴巴拳頭開源產(chǎn)品,迭代了2年多,在不少互聯(lián)網(wǎng)型和傳統(tǒng)型公司都已經(jīng)落地,我們選擇了穩(wěn)定的 1.2.1 版本,得出結(jié)論是功能穩(wěn)定,性能上佳,關(guān)于功能和性能方面的相關(guān)數(shù)據(jù),具體參考:《掌門1對(duì)1微服務(wù)體系 Solar | 阿里巴巴 Nacos 企業(yè)級(jí)落地下篇》。
但是,如何遷移 Eureka 上的業(yè)務(wù)服務(wù)到 Nacos 上?業(yè)務(wù)服務(wù)實(shí)例數(shù)目眾多,遷移工作量巨大,需要全公司業(yè)務(wù)部門配合,同時(shí) Eureka 對(duì)注冊(cè)的業(yè)務(wù)服務(wù)名大小寫不敏感,而 Nacos 對(duì)注冊(cè)的業(yè)務(wù)服務(wù)名大小寫敏感,那么對(duì)于業(yè)務(wù)服務(wù)名不規(guī)范的業(yè)務(wù)部門需要改造。而對(duì)于基礎(chǔ)架構(gòu)部來說, Nacos Eureka Sync 方案如同一座大山橫亙?cè)谖覀兠媲?#xff0c;是首先需要邁過去的坎,縱觀整個(gè)過程,該方案選型還是折騰了一番,具體參考:《掌門1對(duì)1微服務(wù)體系 Solar | 阿里巴巴 Nacos 企業(yè)級(jí)落地中篇》。
阿里巴巴 Nacos 企業(yè)級(jí)落地的優(yōu)化代碼,在不久的將來會(huì)通過開源的方式回饋給業(yè)界。
官方介紹
1. Nacos 簡介
阿里巴巴中間件部門開發(fā)的新一代集服務(wù)注冊(cè)發(fā)現(xiàn)中心和配置中心為一體的中間件。它是構(gòu)建以“服務(wù)”為中心的現(xiàn)代應(yīng)用架構(gòu) (例如微服務(wù)范式、云原生范式) 的服務(wù)基礎(chǔ)設(shè)施,支持幾乎所有主流類型的“服務(wù)”的發(fā)現(xiàn)、配置和管理,更敏捷和容易地構(gòu)建、交付和管理微服務(wù)平臺(tái)。
- Nacos Landscape
- Nacos Map
摘自官網(wǎng) What is Nacos:https://nacos.io/en-us/docs/what-is-nacos.html
2. Spring Cloud Alibaba 簡介
阿里巴巴中間件部門開發(fā)的 Spring Cloud 增強(qiáng)套件,致力于提供微服務(wù)開發(fā)的一站式解決方案。此項(xiàng)目包含開發(fā)分布式應(yīng)用微服務(wù)的必需組件,方便開發(fā)者通過 Spring Cloud 編程模型輕松使用這些組件來開發(fā)分布式應(yīng)用服務(wù)。依托 Spring Cloud Alibaba ,您只需要添加一些注解和少量配置,就可以將 Spring Cloud 應(yīng)用接入阿里微服務(wù)解決方案,通過阿里中間件來迅速搭建分布式應(yīng)用系統(tǒng)。
摘自官網(wǎng) Spring Cloud Alibaba Introduction:https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-docs/src/main/asciidoc-zh/introduction.adoc
關(guān)于 Nacos 和 Spring Cloud Alibaba 如何使用,它的技術(shù)實(shí)現(xiàn)原理怎樣等,官方文檔或者民間博客、公眾號(hào)文章等可以提供非常詳盡且有價(jià)值的材料,這些不在本文的討論范圍內(nèi),就不一一贅述。筆者嘗試結(jié)合掌門教育現(xiàn)有的技術(shù)棧以及中間件一體化的戰(zhàn)略,并著眼于強(qiáng)大的 Nacos 和 Spring Cloud Alibaba 技術(shù)生態(tài)圈展開闡釋。
Nacos?開發(fā)篇
1. Nacos Server 落地
1)Nacos Server
- Nacos Server 環(huán)境和域名
掌門的應(yīng)用環(huán)境分為 4 套,DEV | FAT | UAT | PROD 分別對(duì)應(yīng)開發(fā)、測(cè)試、準(zhǔn)生產(chǎn)環(huán)境、生產(chǎn)環(huán)境,因此 Nacos Server 也分為 4 套獨(dú)立環(huán)境。除了 DEV 環(huán)境是單機(jī)部署外,其他是集群方式部署。對(duì)外均以域名方式訪問,包括 SDK 方式連接 Nacos Server 和訪問 Nacos Server Dashboard 控制臺(tái)頁面。
- Nacos Server 環(huán)境隔離和調(diào)用隔離
Nacos Server 可以創(chuàng)建不同的命名空間,做到同一個(gè)應(yīng)用環(huán)境的基礎(chǔ)上更細(xì)粒度的劃分,隔離服務(wù)注冊(cè)和發(fā)現(xiàn)。在某些場(chǎng)景下,開發(fā)本地有需要連接測(cè)試環(huán)境的 Nacos Server ,但其他測(cè)試服務(wù)不能調(diào)用到開發(fā)本地,這時(shí)候可以將 NacosDiscoveryProperties 的 enabled 屬性設(shè)置為 false 。
- Nacos Server 集成 Ldap
Nacos Server Dashboard 集成公司的 Ldap 服務(wù),并在用戶首次登錄時(shí)記錄用戶信息。
2)Nacos Server 界面
- Nacos 界面權(quán)限
Nacos Server Dashboard 用戶首次登陸時(shí),默認(rèn)分配普通用戶(即非 ROLE_ADMIN )角色,對(duì)查詢以外的按鈕均無操作權(quán)限,以免出現(xiàn)誤操作導(dǎo)致服務(wù)非正常上下線。
- Nacos 界面顯示服務(wù)概覽
Nacos Server Dashboard 頁面增加服務(wù)總數(shù)及實(shí)例總數(shù)的統(tǒng)計(jì),該信息每 5 秒刷新一次。
3)Nacos 監(jiān)控
【Nacos Server 監(jiān)控】
- 標(biāo)準(zhǔn)監(jiān)控
基于公司現(xiàn)有的 Prometheus 、 Grafana 、 AlertManager 從系統(tǒng)層監(jiān)控 Nacos。
- 高級(jí)監(jiān)控
根據(jù) Nacos 監(jiān)控手冊(cè),結(jié)合 Prometheus 和 Grafana 監(jiān)控 Nacos 指標(biāo)。
【Nacos Eureka Sync Etcd 監(jiān)控】
從如下界面可以監(jiān)控到,業(yè)務(wù)服務(wù)列表是否在同步服務(wù)的集群上呈現(xiàn)一致性 Hash 均衡分布。
4)Nacos 日志
- 日志合并及 JSON 格式化
將 Nacos 多模塊的日志統(tǒng)一按 info 、 warn、error 級(jí)別合并,定義 schema 字段標(biāo)記不同模塊,按 JSON 格式滾動(dòng)輸出到文件,供 ELK 采集展示。
5)Nacos 告警
【Nacos Server 告警】
- 業(yè)務(wù)服務(wù)上下線的告警
- Nacos Eureka Sync 告警
- 服務(wù)名大寫告警
- 業(yè)務(wù)服務(wù)同步完畢告警
2. Nacos?Client 落地
1)Solar Nacos SDK 環(huán)境初始化
應(yīng)用接入 Solar Nacos SDK 在啟動(dòng)時(shí)需要初始化完成 Nacos Server 的連接配置,即 spring.cloud.nacos.discovery.server-addr 參數(shù)的賦值。不同環(huán)境下連接的 Nacos Server ,因此需要讀取機(jī)器所在的 env 環(huán)境參數(shù),來選擇相對(duì)應(yīng)的 Nacos Server 地址。
初始化邏輯代碼如下:
public class NacosClientConfigApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext>, Ordered {private static final Logger logger = LoggerFactory.getLogger(NacosClientConfigApplicationContextInitializer.class);@Overridepublic 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());}}@Overridepublic 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 藍(lán)綠灰度發(fā)布和子環(huán)境隔離
在 Nacos 和 Eureka 雙注冊(cè)中心過渡狀態(tài)下, Solar SDK 支持跨注冊(cè)中心調(diào)用的藍(lán)綠灰度發(fā)布和子環(huán)境功能。下面的圖片,只以 Eureka 為例:
我們只需要把 Eureka SDK 換到 Nacos SDK 即可,實(shí)現(xiàn)如下功能:
- Solar?藍(lán)綠灰度發(fā)布
- 版本匹配灰度發(fā)布
- 版本權(quán)重灰度發(fā)布
- Solar?多區(qū)域路由
- 區(qū)域匹配灰度路由
- 區(qū)域權(quán)重灰度路由
- Solar?子環(huán)境隔離
- 環(huán)境隔離
- 環(huán)境路由
- Solar?版本號(hào)和區(qū)域值,子環(huán)境號(hào)策略
- DEV?環(huán)境,Git?插件自動(dòng)創(chuàng)建灰度版本號(hào)
- DevOps?環(huán)境設(shè)置
Solar 藍(lán)綠灰度發(fā)布架構(gòu)圖:
Solar 基于版本維度的藍(lán)綠灰度發(fā)布架構(gòu)圖:
Solar 子環(huán)境隔離架構(gòu)圖:
更多功能參考:
掌門 1 對(duì) 1 微服務(wù)體系 Solar 第 1 彈:全鏈路灰度藍(lán)綠發(fā)布智能化實(shí)踐,掌門教育已經(jīng)實(shí)現(xiàn)通過灰度藍(lán)綠發(fā)布方式,實(shí)現(xiàn)對(duì)流量的精確制導(dǎo)和調(diào)撥。
Nepxion Discovery 開源社區(qū):https://github.com/Nepxion/Discovery
3)Solar Nacos 集成 Sentinel
4)Solar Nacos 集成灰度藍(lán)綠埋點(diǎn)到 Skywalking
5)Solar Nacos 集成 Sentinel 埋點(diǎn)到 Skywalking
- 微服務(wù)上的 Sentinel 埋點(diǎn)
- 網(wǎng)關(guān)上的 Sentinel 埋點(diǎn)
6)Solar Nacos 集成 DevOps 發(fā)布平臺(tái)
- 集成攜程 VI Cornerstone 實(shí)現(xiàn)服務(wù)拉入拉出
Solar Nacos SDK 的服務(wù),在應(yīng)用發(fā)布時(shí)需要做服務(wù)的拉入拉出,目的是為了發(fā)布時(shí)流量無損。掌門使用 VI Cornerstone 實(shí)現(xiàn)拉入拉出功能。具體實(shí)現(xiàn)是在初始化 NacosDiscoveryProperties 對(duì)象時(shí)設(shè)置 instance.enabled 屬性值為 false,在服務(wù)完全初始化后,通過發(fā)布系統(tǒng)調(diào)用 Solar Nacos SDK 的 API 接口再修改為 true 來被外部發(fā)現(xiàn)并提供服務(wù)。
public class NacosApplicationContextInitializer implements EnvironmentPostProcessor {@Overridepublic 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.NacosApplicationContextInitializer7)Solar Nacos SDK 接入
【Solar 版本定義】
- Solar 2.3.x & 1.3.x,基于 Nacos SDK
- Solar 2.2.x & 1.2.x,基于 Eureka SDK
【Solar 版本關(guān)系】
- Solar 版本與 Spring Boot 技術(shù)棧的關(guān)系
- Solar 版本與注冊(cè)中心的關(guān)系
【Solar SDK 接入】
- 設(shè)置 Parent
- 添加到 pom.xml
只需引入一個(gè) Jar 包,對(duì)接成本極低,只做基本組件封裝,非常輕量級(jí)。
微服務(wù):
<dependency><groupId>com.zhangmen</groupId><artifactId>solar-framework-starter-service</artifactId><version>${solar.version}</version> </dependency>網(wǎng)關(guān):
<dependency><groupId>com.zhangmen</groupId><artifactId>solar-framework-starter-zuul</artifactId><version>${solar.version}</version> </dependency>- 入口類添加注解
@EnableSolarService , @EnableSolarZuul 封裝了標(biāo)準(zhǔn) Spring Boot / Spring Cloud / Apollo 等大量注解,降低業(yè)務(wù)的使用成本。
微服務(wù):
@EnableSolarService public class DemoApplication {public static void main(String[] args) {new SpringApplicationBuilder(DemoApplication.class).run(args);} }網(wǎng)關(guān):
@EnableSolarZuul public class DemoApplication {public static void main(String[] args) {new SpringApplicationBuilder(DemoApplication.class).run(args);} }8)Solar Nacos SDK 和 Solar Eureka SDK 升級(jí)和回滾
升級(jí)和回滾方案非常簡單,此方式同時(shí)適用于網(wǎng)關(guān)和服務(wù),見下圖:
作者信息
吳毅挺,掌門技術(shù)副總裁,負(fù)責(zé)技術(shù)中臺(tái)和少兒技術(shù)團(tuán)隊(duì)。曾就職于百度、eBay 、攜程,曾任攜程高級(jí)研發(fā)總監(jiān),負(fù)責(zé)從零打造攜程私有云、容器云、桌面云和 PaaS 平臺(tái)。
任浩軍,掌門基礎(chǔ)架構(gòu)部負(fù)責(zé)人。曾就職于平安銀行、萬達(dá)、惠普,曾負(fù)責(zé)平安銀行平臺(tái)架構(gòu)部 PaaS 平臺(tái) Halo 基礎(chǔ)服務(wù)框架研發(fā)。10 多年開源經(jīng)歷,Github ID:@HaojunRen,Nepxion 開源社區(qū)創(chuàng)始人,Nacos Group Member,Spring Cloud Alibaba & Nacos & Sentinel & OpenTracing Committer。
參與 Nacos 落地的基礎(chǔ)架構(gòu)部成員,包括:童子龍,張彬彬,廖夢(mèng)鴿,張金星,胡振建,謝璐,謝慶芳,伊安娜
“阿里巴巴云原生關(guān)注微服務(wù)、Serverless、容器、Service Mesh 等技術(shù)領(lǐng)域、聚焦云原生流行技術(shù)趨勢(shì)、云原生大規(guī)模的落地實(shí)踐,做最懂云原生開發(fā)者的公眾號(hào)。”
總結(jié)
以上是生活随笔為你收集整理的掌门教育微服务体系 Solar | 阿里巴巴 Nacos 企业级落地上篇的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SpringCloud 应用在 Kube
- 下一篇: CNCF 新增两个孵化项目 | 云原生生