天天看點

GIAC | KCL:聲明式的雲原生配置政策語言

GIAC | KCL:聲明式的雲原生配置政策語言

楔子: 以螞蟻集團典型的建站場景為例,在接入 Kusion 後,使用者側配置代碼減少到 5.5%,使用者面對的 4 個平台通過接入統一代碼庫而消減,在無其他異常的情況下傳遞時間從 2 天下降到 2 小時……

注:本文是柴樹杉在 2021 GIAC 大會上分享的内容。相關 PPT 内容請點選下方自行下載下傳

GIAC 大會 PPT 下載下傳:KCL聲明式的雲原生配置政策語言

0. 你好GIAC

大家好,我是來自螞蟻集團的同學,很高興能在GIAC的程式設計語言新範式闆塊和大家分享《KCL配置政策語言》。KCL語言是螞蟻内部的Kusion解決方案中針對雲原生基礎設施配置代碼化自研的DSL語言,目前已經在建站場景等一些場景開始小範圍推廣試用。

我們先看一下簡單的KCL代碼:

schema GIACInvitation[name: str]:
    Name:     str = name
    Topic:    str = "分享主題"
    Company?: str = None
    Type:     str = "分享嘉賓"
    Address:  str = "深圳"

invitation = GIACInvitation("姓名") {
    Topic:   "KCL配置政策語言"
    Company: "螞蟻集團"
}           

這個例子代碼先通過

schema

定義了一個

GIACInvitation

結構體:該結構體有一個

str

類型的

name

參數,同時還有一組标注了類型和預設值的屬性。然後通過聲明式的文法構造了

GIACInvitation

的執行個體

invitation

這個例子雖然簡單,但是包含了 KCL 最重要的 schema 語言結構。從例子可以看出 KCL 嘗試通過聲明式的文法、靜态類型檢查特性來改進配置代碼的編寫和維護工作。這也是設計 KCL 語言的初衷,我們希望通過程式設計領域成熟的技術理論來解決雲原生領域的配置代碼化的問題。

1. KCL語言的誕生背景

在經典的 Linux/UNIX 作業系統中,我們通過 Shell 和系統内置的各種工具和核心進行互動,同時通過 Shell 腳本來管理更上層的 App。可以說 Shell 語言極大地簡化了核心的程式設計界面,不僅僅提升了作業系統易用性也簡化了上層 App 的管理和運維,也提高了生産效率。而 Kubernetes 作為容器管理領域的事實标準,已經成為雲計算時代的Linux/UNIX。類比 UNIX 系統,Kubernetes 目前還缺少一種符合其聲明式、開放、共享設計理念的互動語言及工具。

GIAC | KCL:聲明式的雲原生配置政策語言

1.1 為何要設計KCL語言?

K8s已經成為雲計算的作業系統,但是目前尚缺少功能完備的SHELL互動界面。目前雖然有很多而且開源方案,但是還沒有像UNIX的Shell那種出現比較成熟的方案,特别是尚無法滿足頭部網際網路企業大規模工程化的要求。雲原生技術與企業落地之間存在Gap需要填補,這正是雲原生工程化要解決的問題,也是設計KCL語言的出發點。

1.2 目前是一個好時機

雲原生的思路是高度的開放化和民主化,結果就是萬物可配置,一切配置都是代碼。帶配置代碼面前人人平等,每個使用者都可以通過調整配置代碼和基礎平台設施進行互動。是以對配置的編寫和維護正在成為雲計算時代軟體工程師的必備的技能和需求。基于對雲原生配置代碼化需求的日益旺盛,矽谷的諸多頭部公司已經對這個方向進行了大規模的實踐和驗證,這些都給了我們大量可以參考的經驗。

是以螞蟻的 Kusion 項目嘗試通過 KCL 配置政策語言正是為了簡化雲原生技術設施的接入方式設計,其設計目标不僅僅是為了提升螞蟻基礎設施的開放程度及使用效率,同時希望能夠優化共享、協同的開發流程,可以說其定位正是雲原生時代的 Shell 語言。雖然目前還處于探索和實踐階段,我們通過此文和大家分享下 KCL 語言的設計與實作的一些理念,為雲原生的快速到來貢獻一點綿薄之力。

1.3 KCL誕生曆史

KCL 語言從2019年開始初期的調研和設計工作。到2020年3月釋出kcl-0.1,基于Python定制文法,采用Go版本的Grumpy和AntLR等工具開發。2020年下半年改用Python語言并加快了開發和疊代速度,釋出的kcl-0.2.x引入了大量語言特性、增加了Plugin擴充支援、同時支援IDEA插件。2021年上半年開始統一優化和整合語言特性,釋出的kcl-0.3優化類型系統、內建單元測試工具、優化執行性能并提供了Go等多語言的API支援、同時通過LSP為VSCode提供支援。2021年下半年開始在建站等常見落地,同時引入靜态類型檢查和優化性能,完善語言的文檔支援。

2. KCL語言的設計原則

基于螞蟻踐行多年的經典運維中台沉澱的經驗和對各種問題利弊的思考,Kusion 項目對如何充分利用雲原生技術帶來的紅利,打造一個開放、透明、聲明式、可協同的運維體系進行了探索和思考,提出并實踐了基于基礎設施代碼化的雲原生協同開發的模型。而 KCL 語言正是 Kusion 項目為了解決雲原生協同開發而設計的聲明式的配置程式設計語言,簡單、穩定、高效和工程化是 KCL 語言設計的設計理念。

GIAC | KCL:聲明式的雲原生配置政策語言

2.1 簡單為王

簡單不僅僅可以降低學習和溝通的成本,而且可以減少代碼出問題的風險。不論是 UNIX 奉行的 KISS 原則還是 Go語言推崇的 Less is more 設計理念,簡化易用的界面始終是各種成功産品追求的一個目标。同樣從簡單原則出發,KCL 語言在參考現代程式設計語言之上隻保留了必要的元素,同時通過類型自動推導、引入受限的控制流和 schema 提供了基礎靈活的配置定義編寫能力,删減語言特性始終是 KCL 語言設計工作的一個重要目标。

2.1.1 聲明式文法

聲明式程式設計是和指令式程式設計并列的一種程式設計範式,聲明式程式設計隻告訴你想要的結果,執行引擎負責執行的過程。聲明式程式設計使用更加簡單,可以降低指令式拼裝造成的複雜性和副作用,保持配置代碼清晰可讀,而複雜的執行邏輯已經由 Kubernetes 系統提供支援。KCL 語言通過簡化對 schema 結構體執行個體化的文法結構對聲明式文法提供支援,通過僅提供少量的語句來減少指令過程式程式設計帶來的複雜性。 圍繞 schema 和配置相關的文法,KCL 希望每種配置需求盡可能通過固定的寫法完成,使得配置代碼盡可能的統一化。

比如作為 KCL 聲明式文法的核心結構 schema 可以采用聲明式方式執行個體化:

schema Name:
    firstName: str
    lastName: str

schema Person:
    name: Name = {
        firstName: "John"
        lastName: "default"
    }

JohnDoe = Person {
    name.lastName: "Doe"
}           

首先通過schema定義了一個 Name 結構,結構包含2個字元串類型的必填屬性。然後在 Person 中複用 Name 類型聲明一個name屬性,并且給name屬性設定了預設值以簡化使用者使用。最終在定義 JohnDoe 配置定義的時候,隻需填寫 name.lastName 一個屬性參數即可,其他部分屬性均采用預設的參數。

對于一些标準的業務應用,通過将可複用的模型封裝為 KCL schema,這樣可以為前端使用者提供最簡單的配置界面。比如基于螞蟻内部Konfig大庫中 sofa.SofaAppConfiguration 隻需添加少量的配置參數就可以定制一個 App

appConfiguration = sofa.SofaAppConfiguration {
    resource: resource.Resource {
        cpu: "4"
        memory: "8Gi"
        disk: "50Gi"
    }
    overQuota: True
}           

通過聲明式文法描述必要的參數(其他的參數全部采用預設配置),可以極大簡化普通使用者的配置代碼。

2.1.2 順序無關文法

有别于指令式程式設計,KCL 推崇的是更适合于配置定義的聲明式文法。以斐波那契數列為例,可以把一組聲明式的定義看作一個方程組,方程式的編寫順序本質上不影響方程組的求解,而計算屬性依賴并“求解”的過程由 KCL 解釋器完成,這樣可以避免大量指令式拼裝過程及順序判斷代碼。

schema Fib:
    n1: int = n - 1
    n2: int = n1 - 1
    n: int
    value: int

    if n <= 1:
        value = 1
    elif n == 2:
        value = 1
    else:
        value = (Fib {n: n1}).value + (Fib {n: n2}).value

fib8 = (Fib {n: 8}).value  # 21           

代碼中 Fib 定義的成員n、n1和n2有一定的依賴關系,但是和它們書寫的順序并無關系。KCL 語言引擎會根據聲明式代碼中的依賴關系自動計算出正确的執行順序,同時對類似循環引用等異常狀态告警。

2.2.3 同名配置合并

當整個業務和開發維護團隊都變得複雜時,配置代碼的編寫和維護也将變得複雜化:同一份配置參數可能散落在多個團隊的多個子產品中,同時一個完整的應用配置則需要合并這些散落在不同地方的相同和不同配置參數才可以生效,而相同的配置參數可能因為不同團隊的修改而産生沖突。通過人工方式同步這些同名配置和合并不同的配置都是一個極大的挑戰。

比如 Konfig 大庫中應用配置模型分為 base 和各環境 stack 配置,要求程式運作時按照某一 merge 政策合并為一份應用配置,相當于要求大庫前端配置能夠自動合并,即能夠分開多次定義并且合并,然後執行個體化生成相應的唯一前端配置。借助 KCL 語言的能力和 Konfig 的最佳實踐,可通過将基線配置和環境配置自動合并簡化配置的編寫。比如對于标準 SOFA 應用 opsfree,其基線配置和環境配置分别維護,最終交由平台工具進行配置合并和檢查。KCL 語言通過自動化合并同名配置實作簡化團隊協同開發的設計目标。

比如 base 配置收集的通用的配置:

appConfiguration = sofa.SofaAppConfiguration {
    mainContainer: container.Main {
        readinessProbe: probe_tpl.defaultSofaReadinessProbe
    }
    resource: res_tpl.medium
    releaseStrategy: "percent"
}           

然後再預發環境在 base 配置的基礎之上針對某些參數進行微調:

appConfiguration = sofa.SofaAppConfiguration {
    resource: resource.Resource {
        cpu: "4"
        memory: "8Gi"
        disk: "50Gi"
    }
    overQuota: True
}           

合并的 pre 配置實際是一份 SofaAppConfiguration 配置(相當于如下等效代碼,環境配置的優先級預設高于基線配置)

appConfiguration = sofa.SofaAppConfiguration {
    mainContainer: container.Main {
        readinessProbe: probe_tpl.defaultSofaReadinessProbe
    }
    resource: resource.Resource {
        cpu: "4"
        memory: "8Gi"
        disk: "50Gi"
    }
    overQuota: True
    releaseStrategy: "percent"
}           

目前的同名配置雖然隻針對應用的主包配置有效,但已經帶來了可觀察的收益。

2.2 穩定壓倒一切

越是基礎的元件對穩定性要求越高,複用次數越多的穩定性帶來的收益也更好。因為穩定性是基礎設施領域一個必備的要求,不僅僅要求邏輯正确,而且需要降低錯誤出現的幾率。

2.2.1 靜态類型和強不可變性

GIAC | KCL:聲明式的雲原生配置政策語言

很多配置語言采用運作時動态檢查類型。動态類型最大的缺點隻能檢查正在被執行屬性的類型,這非常不利于開發階段提前發現類型的錯誤。靜态類型不僅僅可以提前分析大部分的類型錯誤,還可以降低後端運作時的動态類型檢查的性能損耗。

除了靜态類型,KCL 還通過 final 關鍵字禁止某些重要屬性被修改。靜态類型再結合屬性的強不可變性,可以為配置代碼提供更強的穩定性保障。 比如對于 CafeDeployment 中的 apiVersion 資訊是一種常量類型的配置參數,final 為這類配置提供保障:

schema CafeDeployment:
    final apiVersion: str = "apps.cafe.cloud.alipay.com/v1alpha1"
    final kind: str = 123  # 類型錯誤

schema ContainerPort:
    containerPort: int = 8080
    protocol: "TCP" | "UDP" | "SCTP" = "TCP"
    ext? : str = None           

代碼中 apiVersion 和 kind 屬性都被 final 保護禁止被修改。但是 kind 因為屬性類型初始值不同而隐含一個錯誤,通過靜态類型檢查很容易在開發階段發現錯誤并改正。

2.2.2 運作時類型和邏輯check驗證

KCL 的 schema 不僅僅是帶類型的結構體,也可以用于在運作時校驗存量的無類型的 JSON 和 YAML 資料。此外 schema 的 check 塊可以編寫語義檢查的代碼,在運作時執行個體化 schema 時會自動進行校驗。同時,基于 schema 的繼承和 mixin 可以産生跟多關聯的 check 規則。

GIAC | KCL:聲明式的雲原生配置政策語言

比如以下的例子展示 check 的常見用法:

schema sample:
    foo: str
    bar: int
    fooList: [str]

    check:
        bar > 0 # minimum, also support the exclusive case
        bar < 100, "message" # maximum, also support the exclusive case
        len(fooList) > 0 # min length, also support exclusive case
        len(fooList) < 100 # max length, also support exclusive case
        regex.match(foo, "^The.*Foo$") # regex match
        isunique(fooList) # unique
        bar in [range(100)] # range
        bar in [2, 4, 6, 8] # enum
        multiplyof(bar, 2) # multipleOf           

check 中每個語句都是一個可以産生 bool 結果的表達式和可選的錯誤資訊組成(每個普通的 bool 表達式其實是assert 語句的簡化而來)。通過内置的文法和函數可以實作在運作時對屬性值的邏輯驗證。

2.2.3 内置測試支援

單元測試是提升代碼品質的有效手段。KCL 基于已有的 schema 文法結構,配合一個内置 kcl-test 指令提供靈活的單元測試架構(結合 testing 包可指定面值類型的指令行參數)。

GIAC | KCL:聲明式的雲原生配置政策語言

内置測試工具

schema TestPerson:
    a = Person{}
    assert a.name == 'kcl'

schema TestPerson_age:
    a = Person{}
    assert a.age == 1           

kcl-test 指令不僅僅執行單元測試,還會統計每個測試執行的時間,而且可以通過正規表達式參數選擇執行指定的測試。此外通過

kcl-test ./...

可以遞歸執行子目錄的單元測試,同時支援內建測試和Plugin測試。

2.3 高效是永恒的追求

KCL 代碼不僅僅通過聲明式的風格簡化程式設計,同時通過子產品支援、mixin 特性、内置的 lint 和 fmt 工具、以及 IDE 插件提供高效的開發體驗。

2.3.1 schema 中好用的文法

schema 是 KCL 編寫配置程式的核心文法結構,其中幾乎每個特性均是針對具體的業務場景提效而設計。比如在定義和執行個體化深層次嵌套的配置參數時,均可以直接指定屬性的路徑定義和初始化。

schema A:
    a: b: c: int
    a: b: d: str = 'abc'

A {
    a.b.c: 5
}           

同時為了安全,對于每個屬性預設都是非空的字段,在執行個體化時會自動進行檢查。

schema 不僅僅是一個獨立的帶類型注解的配置對象,我們也可以通過繼承的方式來擴充已有的 schema:

schema Person:
    firstName: str
    lastName: str

# schema Scholar inherits schema Person
schema Scholar(Person):
    fullName: str = firstName + '_' + lastName
    subject: str

JohnDoe = Scholar {
    firstName: "John",
    lastName: "Doe",
    subject: "CS"
}           

代碼中 Scholar 從 Person 繼承,然後又擴充了一些屬性。作為子類的 Scholar 可以直接通路父類中定義的firstName 等屬性資訊。

繼承是 OOP 程式設計中基礎的代碼複用手段,但同時也有多繼承導緻的菱形繼承的技術問題。KCL 語言刻意簡化了繼承的文法,隻保留了單繼承的文法。同時 schema 可以通過 mixin 特性混入複用相同的代碼片段,對于不同的能力配套,我們通過 mixin 機制編寫,并通過 mixin 聲明的方式“混入”到不同的結構體中。

比如通過在 Person 中混入 FullnameMixin 可以給 schema 增加新的屬性或邏輯(包括 check 代碼塊):

schema FullnameProtocol:
    firstName : str = "default"
    lastName : str

mixin FullnameMixin for FullnameProtocol:
    fullName : str = "${firstName} ${lastName}"

schema relax Person:
    mixin [FullnameMixin]
    firstName : str = "default"
    lastName : str           

通過 KCL 的語言能力,平台側同學可以通過單繼承的方式擴充結構體,通過 mixin 機制定義結構體内屬性的依賴關系及值内容,通過結構體内順序無關的編寫方式完成聲明式的結構體定義,此外還支援如邏輯判斷、預設值等常用功能。

2.3.2 doc、fmt、lint和外圍的LSP工具

GIAC | KCL:聲明式的雲原生配置政策語言

在程式設計領域代碼雖然是最核心的部分,但是代碼對應的文檔和配套的工具也是和程式設計效率高度相關的部分。政策設計哲學并不局限于語言本身,還包括文檔、代碼格式化工具、代碼風格評估工具和IDE的支援等。KCL 通過 kcl-doc 支援從配置代碼直接提取産生文檔,自動化的文檔不僅僅減少了手工維護的成本,也降低的學習和溝通成本。kcl-fmt 則很友善将目前目錄下的全部代碼(包含嵌套的子目錄)格式化為唯一的一種風格,而相同格式的代碼同樣降低的溝通和代碼評審的成本。kcl-lint 工具則是通過将一些内置的風險監測政策對 KCL 代碼平行評估,友善使用者根據評估結果優化代碼的風格。

2.4 工程化的解決方案

任何語言想要在工程中實際應用,不僅僅需要很好的設計,還需要為更新、擴充和內建等正常的場景提供完整的解決方案。

2.4.1 多元度接口

KCL語言設計通過在不同的抽象層次為普通使用者(KCL指令行)、KCL語言定制者(Go-API、Python-API)、KCL庫擴充者(Plugin)和IDE開發者(LSP服務)均提供了幾乎等價的功能界面,進而提供了最大的靈活度。

2.4.2 千人千面的配置DB

KCL 是面向配置的程式設計語言,而配置的核心是結構化的資料。是以,我們可以将完整 KCL 代碼看做是一種配置資料庫。通過 KCL 的配置參數的查詢和更新(override/-O指令)可以和對應的配置屬性路徑,可以實作對屬性參數的查詢、臨時修改和存盤修改。

GIAC | KCL:聲明式的雲原生配置政策語言

将代碼化的配置作為DB的唯一源,不僅僅可以內建DB領域成熟的查詢和分析手段,而且可以通過配置代碼視角調整配置代碼的邏輯結構。特别是在自動化運維實踐中,通過程式自動生成的配置代碼修改的PullRequest可以友善引入開發人員進行代碼評審,很好地達到人機通過不同界面配合運維。

2.4.3 版本平滑更新

随着業務和代碼的演化,相關子產品的 API 也會慢慢腐化。KCL 語言設計通過嚴格的依賴版本管理,然後結合語言内置的文法和檢查工具保障 API 平滑的更新和過渡,再配合代碼內建測試和評審流程提升代碼安全。KCL 語言通過@deprecated特性在代碼出現腐化早期給出提示,同時為使用者的過渡更新留出一定的時間視窗,甚至等到API徹底腐爛前通過報錯的方式強制要求同步更新相關的代碼。

GIAC | KCL:聲明式的雲原生配置政策語言

比如在某次更新中,name 屬性被 fullName 替代了,則可以通過@deprecated特性标志:

schema Person:
    @deprecated(version="1.1.0", reason="use fullName instead", strict=True)
    name: str
    ... # Omitted contents

person = Person {
    # report an error on configing a deprecated attribute
    name: "name"
}           

這樣在執行個體化 Person 時,name 屬性的初始化語句将會及時收到報錯資訊。

2.4.4 内置子產品、KCL子產品、插件子產品

KCL 是面向配置的程式設計語言,通過内置子產品、KCL 子產品和插件子產品提供工程化的擴充能力。

GIAC | KCL:聲明式的雲原生配置政策語言

使用者代碼中不用導入直接使用 builtin 的函數(比如用 len 計算清單的長度、通過 typeof 擷取值的類型等),而對于字元串等基礎類型也提供了一些内置方法(比如轉化字元串的大小寫等方法)。對于相對複雜的通用工作則通過标志庫提供,比如通過 import 導入 math 庫就可以使用相關的數學函數,可以通過導入 regex 庫使用正規表達式庫。而針對 KCL 代碼也可以組織為子產品,比如 Konfig 大庫中将基礎設施和各種标準的應用抽象為子產品供上層使用者使用。此外還可以通過 Plugin 機制,采用 Python 為 KCL 開發插件,比如目前有 meta 插件可以通過網絡查詢中心配置資訊,app-context 插件則可以用于擷取目前應用的上下文資訊進而簡化代碼的編寫。

3. KCL語言的實作原理

3.1 整體架構

KCL 雖然作為一個專用于雲原生配置和政策定義的語言,但是保持大多數過程式和函數式程式設計語言的相似實作架構,其内部整體架構組成也是經典的編譯器 “三段式” 架構。下面是KCL實作的架構圖:

GIAC | KCL:聲明式的雲原生配置政策語言

主要有以下幾個關鍵子產品:

  • 解析器 Parser:解析器分析 KCL 源代碼産生 AST(抽象文法樹)。
  • 編譯器 Compiler:對 AST 進行多次周遊,對 AST 進行語義檢查(比如進行類型檢查、無效代碼檢查)并對 AST 進行優化(合并常量表達式等),最終産生虛拟機可以執行的位元組碼。
  • 虛拟機 Virtual Machine (VM):執行 Compiler 産生的位元組碼,計算産生相應的配置結果,并将配置結果序列化為 YAML/JSON 進行輸出。

整體架構分為三段式的好處是可以把針對 KCL 源語言的前端和針對目标機器的後端組合起來,這種建立編譯器組合的方法可以大大減少工作量。比如目前的 KCL 位元組碼定義和後端虛拟機采用自研實作,KCL 虛拟機主要用于計算産生配置結果并序列化為 YAML/JSON 進行輸出。如果遇到在其他特殊使用 KCL 的場景比如在浏覽器中執行 KCL,則可以重寫一個适配 WASM 的後端,就可輕易将 KCL 移植到浏覽器中使用,但是 KCL 本身的文法和語義不需要發生任何變化,編譯器前端代碼也無需任何改動。

3.2 Go和Python通信原理

為了更好地釋放 KCL 配置政策語言的能力以及遍于上層自動化産品內建(比如著名的編譯器後端 LLVM 就因其 API 設計良好,開發人員可以利用其 API 快速地建構自己的程式設計語言),KCLVM 目前提供了 Python 和 Go 兩種語言的 API,使得使用者可以使用相應的 API 快速地建構語言外圍工具,語言自動化查詢修改工具等提升語言的自動化能力,并且進一步可以基于此建構服務化能力,幫助更多的使用者建構自己雲原生配置代碼化應用或者快速接入基礎設施。

GIAC | KCL:聲明式的雲原生配置政策語言

KCLVM 主體采用 Python 代碼實作,而很多的雲原生應用以 Go 程式建構,是以為了更好地滿足雲原生應用使用者訴求。KCLVM 首先基于 CGo 和 CPython 建構了 Go 程式和 Python程式通信媒介,基于此設計了 Python 函數到 Go 函數的 RPC 調用,調用參數以 JSON 形式存儲,使得 KCLVM-Python 編譯器的能力平滑地過度到 Go 代碼中,通過 Go 一行 import 調用即可操作 KCL 代碼。

補充: 在服務化實踐的過程中,基于CGO調用Python的方案也遇到了一些問題:首先是Go+CGO+Python導緻交叉編譯困難,對ACI的自動化測試和打包産生了挑戰;其次是CGO之後的Python不支援多語言多線程并發,無法利用多核的性能;最後即使通過CGO将Python虛拟機編譯到了Go程式中,依然還是需要安裝Python的标準庫和第三方庫。

3.3 協同配置原理

當有了一個簡單易用并能夠保證穩定性的配置語言後,另一個面臨的問題是如何使用配置代碼化的方式提升協同能力。基于此,KCL 配置可分為使用者側和平台側配置兩類,最終的配置内容由各自使用者側和平台側的配置内容共同決定,是以存在兩個方面的協同問題:

  • 平台側配置與使用者側配置之間的協同
  • 使用者側配置之間的協同

針對上述協同問題,KCL 在技術側提出了順序無關文法,同名配置合并等抽象模型來滿足不同的協同配置場景。

GIAC | KCL:聲明式的雲原生配置政策語言

以上圖為例,首先 KCL 代碼在編譯過程中形成兩張圖(使用者不同配置直接的引用和從屬關系一般形式一張有向無環圖),分别對應結構體内部聲明代碼及結構體使用聲明代碼。編譯過程可以簡單分為三步

  • 首先定義平台側的結構體并形成結構體内部聲明代碼圖
  • 其次聲明并合并不同使用者側配置代碼圖
  • 最後将使用者側配置代碼圖計算的結果代入平台側結構體内部聲明代碼圖求解,最終得到完整配置圖定義。

通過這樣簡單的計算過程,可以在編譯時完成大部分代換運算,最終運作時僅進行少量計算即可得到最終的解。同時在編譯合并圖過程中仍然能夠執行類型檢查和值的檢查,差別是類型檢查是做泛化、取偏序上确界(檢查某個變量的值是否滿足既定類型或者既定類型的子類型),值檢查是做特化、取偏序下确界(比如将兩個字典合并為一個字典)。

4. 對未來的展望

KCL 語言目前依然處于一個高速發展的階段,目前已經有一些應用開始試用。我們希望通過 KCL 語言為 Kusion 技術棧提供更強的能力,在運維、可信、雲原生架構演進方面起到積極的作用。同時對于一些特殊的非标應用提供靈活的擴充和內建方案,比如我們正在考慮如何讓後端支援 WebAssembly 平台,進而支援更多的內建方案。

在合适的時間我們希望能夠開放 KCL 的全部代碼,為雲原生代碼化的快速落地貢獻綿薄之力。

謝謝大家。

更多文章請掃碼關注“金融級分布式架構”公衆号

GIAC | KCL:聲明式的雲原生配置政策語言