掌門教育微服務體系Solar第3彈:Nacos企業級落地下篇

1.png

聯席做者:謝璐 謝慶芳 伊安娜 任浩軍
鄭重鳴謝:Nacos - 彥林,Spring Cloud Alibaba - 小馬哥、洛夜,Nacos 社區 - 張龍(pader)、春少(chuntaojun)html

相關文章推薦:java

前言

在高速發展的時候,公司規模愈來愈大,老師人數愈來愈多,這時候公司不能鋪太多人去作運營與服務,必須提升每一個人效,這就須要技術驅動。所以掌門教育轉變成一家技術驅動型的公司,若是被迫成爲一家靠資金驅動的公司就活不下去了。

-- 張翼(掌門教育創始人兼CEO)python

掌門教育自2014年正式轉型在線教育以來,秉承「讓教育共享智能,讓學習高效快樂」的宗旨和願景,經歷雲計算、大數據、人工智能、 AR / VR / MR 以及現今最火的 5G ,一直堅持用科技賦能教育。掌門教育的業務近幾年獲得了快速發展,特別是今年的疫情,使在線教育成爲了新的風口,也給掌門教育新的機遇。web

隨着業務規模進一步擴大,流量進一步暴增,微服務數目進一步增加,使老的微服務體系所採用的註冊中心 Eureka 不堪重負,同時 Spring Cloud 體系已經演進到第二代,第一代的 Eureka 註冊中心已經不大適合如今的業務邏輯和規模,同時它目前被 Spring Cloud 官方置於維護模式,將再也不向前發展。如何選擇一個更爲優秀和適用的註冊中心,這個課題就擺在了掌門人的面前。通過對 Alibaba NacosHashiCorp Consul等開源註冊中心作了深刻的調研和比較,最終選定 Alibaba Nacos 作微服務體系 Solar 中的新註冊中心。算法

背景故事

基礎架構部選擇新的註冊中心,測試組須要配合對業界成熟的註冊中心產品作分析和比較。因爲掌門教育採用的是比較純淨的 Spring Cloud 技術棧,因此咱們須要圍繞它的註冊中心,從測試角度,進行功能和性能上研究。api

Spring Cloud 技術棧官方支持 Netflix EurekaHashiCorp ConsulZookeeper 三個註冊中心,它們能夠相互間實現無縫遷移,Alibaba Nacos 是新加盟 Spring Cloud 技術棧的新成員。測試組的同窗們對上述四個註冊中心作了一一研究和分析,鑑於時間緊迫,除了 EurekaNacos 以外,其它兩個中間件未作深刻的功能測試和性能測試。下面提供來自阿里巴巴 Nacos 官方某次業界宣講的資料截圖以供你們參考:架構

  • Eureka 介紹

2.png

  • Zookeeper 介紹

3.png

  • Consul 介紹

4.png

  • 上述三個註冊中心比較

5.png

本文將圍繞 Alibaba Nacos 着重針對其功能測試和性能測試兩方面進行剖析和介紹。框架

Nacos 測試篇

Nacos 性能測試

① Nacos Server 性能測試

開發部署了 UATNacos ,測試親自壓測。less

  • 核心腳本
def registry(ip):
    fo = open("service_name.txt", "r")
    str = fo.read()
    service_name_list = str.split(";")
    service_name = service_name_list[random.randint(0,len(service_name_list) - 1)]
    fo.close()
    client = nacos.NacosClient(nacos_host, namespace='')
    print(client.add_naming_instance(service_name,ip,333,"default",1.0,{'preserved.ip.delete.timeout':86400000},True,True))
    while True:
      print(client.send_heartbeat(service_name,ip,333,"default",1.0,"{}"))
      time.sleep(5)
  • 壓測數據

表格 1.jpg

  • 壓測結果圖

6.png

7.png

Nacos Server 是3臺 1C4G 集羣,同時承受1499個服務和12715個實例註冊,並且 CPU 和內存長期保持在一個合適的範圍內,果然 Nacos 性能是至關 OK 的。dom

Nacos 功能測試

① Nacos Server 接口測試

表格2.jpg

更多更詳 API 請參見 Nacos 官方文檔: Open API 指南

https://nacos.io/zh-cn/docs/open-api.html

② Nacos Eureka Sync 測試

  • 交叉註冊

網關,服務 A ,服務 B 各10臺實例,網關注冊 EurekaA 註冊 NacosB 註冊 Eureka ,同步正常,可調用。

  • 壓力測試

請求大於100萬次,查看 Sync Server 會不會受到影響,結果 ErrorRequest = 0,同步服務數和實例數沒有變化。

8.png

  • 有無損調用

網關 Sync Server 掛掉,網關服務 Eureka 同步 Nacos 失敗,不影響網關 -> A -> B 調用。

  • 自動建立同步

發佈系統第一次發佈應用到 Eureka / Nacos ,會自動建立 Eureka -> Nacos 的同步任務或 Nacos -> Eureka 的同步任務

9.png

  • 減小 Sync Server

Sync Server 4C8G ,中止機器,逐臺遞減,結論:平均1臺 4C8G 機器最大可同步100個服務。

  • 增長 Sync Server

2臺 Etcd 節點,停機一臺,Etcd 讀取超時,結論:600個服務至少2臺 Etcd 節點,這裏重點強調,新增服務時, Hash 算法虛擬節點數,務必和原有的保持一致,否則會出現同步失敗,影響跨註冊中心調用。

10.png

  • 重啓 Sync Server

增長 Sync Server 個數,重啓 Sync Server ,各節點同步數從新計算且均衡。

③ Nacos Client 功能測試

Nacos Client 界面重點測試集羣管理,服務列表和權限控制。

  • Nacos Server 重啓後,集羣管理界面正常展現3臺集羣節點 IP
  • 服務註冊 Nacos Server 後,服務列表新增註冊上去的服務名和實例個數,並且可查看詳情。

11.png

  • 服務上下線操做,健康狀態和元數據等展現正常。
  • 編輯,刪除等操做只有具有 Admin 權限的人員纔可操做。

④ Nacos Client 自動化測試

  • 自動化測試鏈路

全鏈路測試路徑

API網關 -> 服務A(兩個實例) -> 服務B(兩個實例)

12.png

全鏈路服務部署

表格3.jpg

  • 自動化測試入口

結合 Spring Boot JunitTestApplication.class 爲測試框架內置應用啓動程序, MyTestConfiguration 用於初始化全部測試用例類。在測試方法上面加入 JUnit@Test註解

@RunWith(SpringRunner.class)
@SpringBootTest(classes = { TestApplication.class, MyTestConfiguration.class }, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class MyTest {
    @Autowired
    private MyTestCases myTestCases;

    private static long startTime;

    @BeforeClass
    public static void beforeTest() {
        startTime = System.currentTimeMillis();
    }

    @AfterClass
    public static void afterTest() {
        LOG.info("* Finished automation test in {} seconds", (System.currentTimeMillis() - startTime) / 1000);
    }

    @Test
    public void testNoGray() throws Exception {
        myTestCases.testNoGray(gatewayTestUrl);
        myTestCases.testNoGray(zuulTestUrl);
    }

    @Test
    public void testVersionStrategyGray() throws Exception {
        myTestCases.testVersionStrategyGray1(gatewayGroup, gatewayServiceId, gatewayTestUrl);
        myTestCases.testVersionStrategyGray1(zuulGroup, zuulServiceId, zuulTestUrl);
    }
}
@Configuration
public class MyTestConfiguration {
    @Bean
    public MyTestCases myTestCases() {
        return new MyTestCases();
    }
}
  • 基於 Nacos Client 的普通調用自動化測試

在測試方法上面增長註解 @DTest ,經過斷言 Assert 來判斷測試結果。註解 @DTest 內容以下:

@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface DTest {

}

代碼以下:

public class MyTestCases {
    @Autowired
    private TestRestTemplate testRestTemplate;

    @DTest
    public void testNoGray(String testUrl) {
        int noRepeatCount = 0;
        List<String> resultList = new ArrayList<String>();
        for (int i = 0; i < 4; i++) {
            String result = testRestTemplate.getForEntity(testUrl, String.class).getBody();

            LOG.info("Result{} : {}", i + 1, result);

            if (!resultList.contains(result)) {
                noRepeatCount++;
            }
            resultList.add(result);
        }

        Assert.assertEquals(noRepeatCount, 4);
    }
}
  • 基於 Nacos Client 的灰度藍綠調用自動化測試

在測試方法上面增長註解 @DTestConfig ,經過斷言 Assert 來判斷測試結果。註解 DTestConfig 註解內容以下:

@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface DTestConfig {
    // 組名
    String group();

    // 服務名
    String serviceId();

    // 組名-服務名組合鍵值的前綴
    String prefix() default StringUtils.EMPTY;

    // 組名-服務名組合鍵值的後綴
    String suffix() default StringUtils.EMPTY;

    // 執行配置的文件路徑。測試用例運行前,會把該文件裏的內容推送到遠程配置中心或者服務
    String executePath();

    // 重置配置的文件路徑。測試用例運行後,會把該文件裏的內容推送到遠程配置中心或者服務。該文件內容是最初的默認配置
    // 若是該註解屬性爲空,則直接刪除從配置中心刪除組名-服務名組合鍵值
    String resetPath() default StringUtils.EMPTY;
}

代碼以下:

public class MyTestCases {
    @Autowired
    private TestRestTemplate testRestTemplate;

    @DTestConfig(group = "#group", serviceId = "#serviceId", executePath = "gray-strategy-version.xml", resetPath = "gray-default.xml")
    public void testVersionStrategyGray(String group, String serviceId, String testUrl) {
        for (int i = 0; i < 4; i++) {
            String result = testRestTemplate.getForEntity(testUrl, String.class).getBody();

            LOG.info("Result{} : {}", i + 1, result);

            int index = result.indexOf("[V=1.0]");
            int lastIndex = result.lastIndexOf("[V=1.0]");

            Assert.assertNotEquals(index, -1);
            Assert.assertNotEquals(lastIndex, -1);
            Assert.assertNotEquals(index, lastIndex);
        }
    }
}

初始默認無灰度藍綠的配置文件 gray-default.xml

<?xml version="1.0" encoding="UTF-8"?>
<rule>

</rule>

灰度藍綠生效的配置文件 gray-strategy-version.xml

<?xml version="1.0" encoding="UTF-8"?>
<rule>
    <strategy>
        <version>1.0</version>
    </strategy>
</rule>
  • 基於 Nacos Client 的自動化測試報告樣例
---------- Run automation testcase :: testStrategyCustomizationGray() ----------
Header : [a:"1", b:"2"]
Result1 : zuul -> solar-service-a[192.168.0.107:3002][V=1.1][R=qa][G=solar-group] -> solar-service-b[192.168.0.107:4002][V=1.1][R=dev][G=solar-group]
Result2 : zuul -> solar-service-a[192.168.0.107:3002][V=1.1][R=qa][G=solar-group] -> solar-service-b[192.168.0.107:4002][V=1.1][R=dev][G=solar-group]
Result3 : zuul -> solar-service-a[192.168.0.107:3002][V=1.1][R=qa][G=solar-group] -> solar-service-b[192.168.0.107:4002][V=1.1][R=dev][G=solar-group]
Result4 : zuul -> solar-service-a[192.168.0.107:3002][V=1.1][R=qa][G=solar-group] -> solar-service-b[192.168.0.107:4002][V=1.1][R=dev][G=solar-group]
* Passed
---------- Run automation testcase :: testVersionRuleGray() ----------
Result1 : zuul -> solar-service-a[192.168.0.107:3002][V=1.1][R=qa][G=solar-group] -> solar-service-b[192.168.0.107:4002][V=1.1][R=dev][G=solar-group]
Result2 : zuul -> solar-service-a[192.168.0.107:3001][V=1.0][R=dev][G=solar-group] -> solar-service-b[192.168.0.107:4001][V=1.0][R=qa][G=solar-group]
Result3 : zuul -> solar-service-a[192.168.0.107:3002][V=1.1][R=qa][G=solar-group] -> solar-service-b[192.168.0.107:4002][V=1.1][R=dev][G=solar-group]
Result4 : zuul -> solar-service-a[192.168.0.107:3001][V=1.0][R=dev][G=solar-group] -> solar-service-b[192.168.0.107:4001][V=1.0][R=qa][G=solar-group]
* Passed

Nacos 測試總結

Nacos 不只性能好,並且界面簡潔,這樣的註冊中心你值得擁有。

做者介紹

  • 吳毅挺,掌門技術副總裁,負責技術中臺和少兒技術團隊。曾就任於百度、eBay 、攜程,曾任攜程高級研發總監,負責從零打造攜程私有云、容器雲、桌面雲和 PaaS 平臺。
  • 任浩軍,掌門基礎架構部負責人。曾就任於平安銀行、萬達、惠普,曾負責平安銀行平臺架構部 PaaS 平臺 Halo 基礎服務框架研發。10 多年開源經歷,Github ID:@HaojunRen,Nepxion 開源社區創始人,Nacos Group Member,Spring Cloud Alibaba & Nacos & Sentinel & OpenTracing Committer。

參與 Nacos 落地的基礎架構部成員,包括:

  • 童子龍,張彬彬,廖夢鴿,張金星,胡振建,謝璐,謝慶芳,伊安娜
阿里巴巴雲原生關注微服務、Serverless、容器、Service Mesh 等技術領域、聚焦雲原生流行技術趨勢、雲原生大規模的落地實踐,作最懂雲原生開發者的公衆號。」
相關文章
相關標籤/搜索