自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

單體 or 微服務(wù)?Service Weaver:我全都要!

開(kāi)發(fā) 前端
Service Weaver 的思路很好,針對(duì)目前微服務(wù)架構(gòu)的問(wèn)題做了優(yōu)化和提升,再加上有 Google 的背書(shū),希望繼續(xù)演進(jìn)下去。尤其當(dāng)前只支持 Go 語(yǔ)言,雖說(shuō) Go 在云原生中風(fēng)生水起,當(dāng)時(shí)業(yè)務(wù)開(kāi)發(fā)大部分仍是 Java 技術(shù)棧。在業(yè)務(wù)開(kāi)發(fā)中,Go 的受眾還是相當(dāng)小。

TL;DR

怎么理解 Service Weaver,就是一個(gè)應(yīng)用中有很多的接口,這些接口間會(huì)互相調(diào)用。如果將操作系統(tǒng)進(jìn)程(應(yīng)用)比做一塊電路板,接口比做元器件。可以選擇將哪些元器件放入該電路板中,哪些元器件放入其他的電路板中。

同一塊電路板中的元器件間通過(guò)板上的導(dǎo)線連接(進(jìn)程內(nèi)的本地方法調(diào)用);不同電路板中的元器件間通過(guò)排線來(lái)連接(遠(yuǎn)程方法調(diào)用)。

總結(jié)幾個(gè)關(guān)鍵詞:

  • 一個(gè)編程框架
  • 用于編寫(xiě)、部署、管理分布式應(yīng)用
  • 支持的語(yǔ)言 Go
  • 在本地以單進(jìn)程、多進(jìn)程運(yùn)行
  • 在云端由框架拆分成微服務(wù),并于云供應(yīng)商集成
  • 單體方式開(kāi)發(fā),微服務(wù)方式部署

體驗(yàn)了一圈下來(lái),給我的感覺(jué)有點(diǎn)類似 Notion、Obsidian 這類筆記軟件。傳統(tǒng)的筆記軟件只能引用其他的筆記,而這類筆記可以細(xì)粒度到 heading 內(nèi)容。

放到微服務(wù)下就是管理的維度不在是服務(wù)本身,而且更小的接口,并且對(duì)某些接口進(jìn)行擴(kuò)展,即使所有接口都位于同一個(gè)二進(jìn)制文件中。

背景

架構(gòu)的演進(jìn),總是在解決問(wèn)題的過(guò)程中引入新的問(wèn)題,然后再解決問(wèn)題,循環(huán)往復(fù)。

從單體到微服務(wù)

軟件架構(gòu)從單體演進(jìn)到微服務(wù)架構(gòu)已經(jīng)十多年了,尤其是近幾年云原生風(fēng)生水起,微服務(wù)架構(gòu)已有深入人心的架勢(shì)。

單體架構(gòu)由于在規(guī)模擴(kuò)大時(shí),單體面臨性能瓶頸和硬件限制、無(wú)法支撐業(yè)務(wù)的快讀迭代、開(kāi)發(fā)效率下降協(xié)同難度增加等原因,頹勢(shì)日漸明顯。然后就有了微服務(wù)架構(gòu)的提出,來(lái)解決單體架構(gòu)的各種問(wèn)題。

上云

由于云平臺(tái)提供顯著的成本效益,減少初始投資并實(shí)現(xiàn)按需付費(fèi)、提供極大的靈活性和可擴(kuò)展性、提供的穩(wěn)定性和可靠性確保業(yè)務(wù)連續(xù)性、專業(yè)的安全保障和合規(guī)性支持減輕企業(yè)的運(yùn)營(yíng)負(fù)擔(dān),企業(yè)將其業(yè)務(wù)和數(shù)據(jù)遷移至云計(jì)算平臺(tái)。

問(wèn)題

拆分成微服務(wù),由此帶來(lái)了不少好處:更高效的應(yīng)用擴(kuò)展、更小的錯(cuò)誤傳播半徑、獨(dú)立的安全域以及完善的模塊邊界。

反過(guò)來(lái),如何正確地找到邊界進(jìn)行拆分并非易事。拆分的依據(jù)是什么?two pizza team?依據(jù)資源使用、組織架構(gòu)、數(shù)據(jù)結(jié)構(gòu)?亦或是考慮未來(lái)的增長(zhǎng)?

微服務(wù)的拆分執(zhí)行下來(lái)毫無(wú)章法,最終的結(jié)果是微服務(wù)越來(lái)越多、更多的故障點(diǎn)、更長(zhǎng)的鏈路、更大的延遲。這實(shí)際上增加了應(yīng)用的開(kāi)發(fā)、部署和管理成本。

  • 原本單個(gè)二進(jìn)制文件,拆分后有多個(gè);原本一次部署完成,拆分后需要多個(gè) CI/CD 流水線來(lái)部署;原本一個(gè)配置文件,拆分后需要維護(hù)多個(gè)。
  • 微服務(wù)彼此獨(dú)立部署,無(wú)法忽略多版本的情況。需要調(diào)整部署策略來(lái)降低風(fēng)險(xiǎn),同樣還有本地開(kāi)發(fā)和測(cè)試的難度增加。
  • 學(xué)習(xí)成本高,需要學(xué)習(xí)如何將應(yīng)用二進(jìn)制文件包裝成容器,并了解云的各種工具和部署方式,即使對(duì)經(jīng)驗(yàn)豐富的程序員來(lái)說(shuō)也難以理解。
  • 同時(shí)還要解決分布式帶來(lái)的各種問(wèn)題,如服務(wù)發(fā)現(xiàn)、安全、負(fù)載均衡,以及服務(wù)間的調(diào)用。
  • 延遲增加,時(shí)間消耗在數(shù)據(jù)的序列化以及網(wǎng)絡(luò)傳輸上。

為什么用 Service Weaver?

今年 3 月 Google 開(kāi)源了 Service Weaver[1],希望能解決微服務(wù)架構(gòu)的各種問(wèn)題。

有了 Servier Weaver,你可以專注在業(yè)務(wù)邏輯的開(kāi)發(fā)上,其他的工作交給 Service Weaver 來(lái)完成。

無(wú)需要糾結(jié)微服務(wù)的拆分規(guī)則,可以拆分為任意數(shù)量的組件。可以在部署的時(shí)候輕松指定哪些組件作為一個(gè)微服務(wù)來(lái)運(yùn)行,哪些在不同的微服務(wù)上運(yùn)行。

使用 Service 可以部署和管理單一二進(jìn)制文件。

Service Weaver 使用自定義的序列化和傳輸協(xié)議,成本效益比行業(yè)最佳的解決方案(gRPC+protobuf)高出三倍。

如何使用 Service Weaver 開(kāi)發(fā)應(yīng)用?

Service Weaver 的核心是組件(component),一個(gè)類似 actor 的計(jì)算單元。

組件是個(gè)常見(jiàn)的 Go 接口,組件間的交互通過(guò)調(diào)用接口定義的方法來(lái)完成。

下面的示例中定義了一個(gè) Reverser 組件,用于反轉(zhuǎn)字符串。

// The interface of the Reverser component.
type Reverser interface {
    Reverse(context.Context, string) (string, error)
}

// The implementation of the Reverser component.
type reverser struct{
    weaver.Implements[Reverser]
}

func (r reverser) Reverse(_ context.Context, s string) (string, error) {
    runes := []rune(s)
    n := len(runes)
    for i := 0; i < n/2; i++ {
        runes[i], runes[n-i-1] = runes[n-i-1], runes[i]
    }
    return string(runes), nil
}

其他組件可以調(diào)用 Reverser 組件的方法:

reversed, err := reverser.Reverse(ctx, "Hello, World!")

組件的最大優(yōu)點(diǎn)是不依賴于系統(tǒng)進(jìn)程。上面的例子中,盡管沒(méi)有編寫(xiě)任何網(wǎng)絡(luò)和序列化相關(guān)的代碼,這些組件可以運(yùn)行在不同的進(jìn)程中甚至是不同的機(jī)器上。

圖片圖片

如上圖所示,如果組件位于同一個(gè)進(jìn)程中,方法的調(diào)用就是傳統(tǒng)的 Go 方法調(diào)用;如果位于不同的進(jìn)程中,方法的調(diào)用就是 RPC。

將應(yīng)用拆分為不同組件的過(guò)程,有點(diǎn)類似微服務(wù)的拆分。組件也同樣有著清晰的邊界,以及很好的擴(kuò)展性。但又沒(méi)有微服務(wù)的缺陷:

  • 所有組件都運(yùn)行同一個(gè)版本,無(wú)需考慮版本的兼容性。
  • 可以很容易地通過(guò) go run 和 go test 運(yùn)行和測(cè)試應(yīng)用。
  • 微服務(wù)的拆分和合并是非常痛苦的。

如何管理 Service Weaver 應(yīng)用?

部署

在云上運(yùn)行就跟本地運(yùn)行一樣簡(jiǎn)單:

$ go run .                           # Run locally, in the same OS process.
$ weaver multi deploy weaver.toml    # Run locally, in multiple OS processes.
$ weaver gke deploy weaver.toml      # Run in the cloud.

配置

Service Weaver 需要的配置非常少。一個(gè) 在線商城[2] 的演示中可能需要超過(guò) 1500 行配置,而 Service Weaver 編寫(xiě)的同樣應(yīng)用所需的配置不超過(guò) 10 行:

[weaver]
binary = "./online_boutique"
rollout = "6h"

[gke]
regions = ["us-west1", "us-east2"]
listeners.boutique = {public_hostname = "online-boutique.net"}

只需指定二進(jìn)制文件、部署的持續(xù)時(shí)間、部署的區(qū)域以及公開(kāi)訪問(wèn)的地址。就這么簡(jiǎn)單。

發(fā)布新版本

傳統(tǒng)的微服務(wù),在發(fā)布新版本時(shí),舊版本的示例可以會(huì)與其他新版本的示例進(jìn)行通信。

Service Weaver 使用不同的方式升級(jí),確??蛻舳说恼?qǐng)求完全在相同的版本下處理:不同版本的組件不會(huì)發(fā)生通信。

這就避免了大多數(shù)的系統(tǒng)故障:研究表明的:多大三分之二的故障是由系統(tǒng)多個(gè)版本之間的交互引起的[3]。

有了 Service Weaver,僅需更新代碼、構(gòu)建、運(yùn)行即可,其他的交給 Service Weaver。

可觀測(cè)性

Service Weaver 提供了用于日志、指標(biāo)和鏈路跟蹤的庫(kù),并自動(dòng)與應(yīng)用的部署環(huán)境集成。

下面的示例演示了如何為 Reverser 組件添加計(jì)數(shù)指標(biāo):

var reverseCount = metrics.NewCounter(
    "reverse_count",
    "The number of times Reverser.Reverse has been called",
)

func (reverser) Reverse(_ context.Context, s string) (string, error) {
    reverseCount.Add(1.0)
    // ...
}

測(cè)試

傳統(tǒng)的微服務(wù),應(yīng)用開(kāi)發(fā)周期非常慢。在迭代中,需要安裝笨重的云依賴、復(fù)雜的測(cè)試框架,或者部署到云上。這些都極大影響了開(kāi)發(fā)進(jìn)度。

有了 Service Weaver 可以想運(yùn)行 Go 程序一樣完成構(gòu)建、運(yùn)行、測(cè)試。提供的 weavertest包可用來(lái)編寫(xiě)端到端測(cè)試,就像寫(xiě)單元測(cè)試一樣簡(jiǎn)單。

演示

安裝 Service Weaver

參考 安裝文檔[4],注意要求 Go 的版本不低于 1.21。在 macOS 上直接用 Homebrew 安裝:

brew install  service-weaver
weaver version
weaver v0.21.2 darwin/arm64
go version
go version go1.21.3 darwin/arm64

初始化工程

mkdir hello-sample
cd hello-sample
go mod init hello-sample

使用上面 Reverser 組件的例子。

編寫(xiě) Reverser 組件

創(chuàng)建 reverser.go 文件,內(nèi)容如下:

package main
import (
    "context"
    "github.com/ServiceWeaver/weaver"
)
// Reverser component.
type Reverser interface {
    Reverse(context.Context, string) (string, error)
}
// Implementation of the Reverser component.
type reverser struct{
    weaver.Implements[Reverser]
}
func (r *reverser) Reverse(_ context.Context, s string) (string, error) {
    runes := []rune(s)
    n := len(runes)
    for i := 0; i < n/2; i++ {
        runes[i], runes[n-i-1] = runes[n-i-1], runes[i]
    }
    return string(runes), nil
}

Reverser 組件通過(guò)定義創(chuàng)建接口 Reverser 定義,該接口定義了用于反轉(zhuǎn)字符串的方法 Reverse;結(jié)構(gòu)體類型 reverser 通過(guò) weaver.Implements[Reverser] 定義為組件 Reverser 的實(shí)現(xiàn)。

接下來(lái)是調(diào)用組件的代碼。

編寫(xiě) Main 組件

創(chuàng)建 main.go 文件,內(nèi)容如下,也就是 main 組件:

package main
import (
    "context"
    "fmt"
    "log"
    "github.com/ServiceWeaver/weaver"
)
func main() {
    if err := weaver.Run(context.Background(), serve); err != nil {
        log.Fatal(err)
    }
}
type app struct{
    weaver.Implements[weaver.Main]
    reverser weaver.Ref[Reverser]
}
func serve(ctx context.Context, app *app) error {
    // Call the Reverse method.
    var r Reverser = app.reverser.Get()
    reversed, err := r.Reverse(ctx, "!dlroW ,olleH")
    if err != nil {
        return err
    }
    fmt.Println(reversed)
    return nil
}

weaver.Run(...) 初始化并運(yùn)行 Service Weaver 應(yīng)用,每個(gè)應(yīng)用都有一組組件組成。運(yùn)行時(shí)會(huì)自動(dòng)創(chuàng)建 weaver.Main 并將其交給應(yīng)用。

查看其源碼可以看到使用了泛型:

func Run[T any, P PointerToMain[T]](ctx context.Context, app func(context.Context, *T "T any, P PointerToMain[T]") error) error {
 ...
}

Run 執(zhí)行時(shí)會(huì)先找到 Main 組件的定義,在上面的代碼中結(jié)構(gòu)體類型 app 被定義為 weaver.Main 組件,然后創(chuàng)建該組件并將其交給代碼中的 serve 來(lái)使用,然后調(diào)用 serve 函數(shù)。

在 Main 組件 app 中我們還可以看到 reverser weaver.Ref[Reverser]。在 Service Weaver 中,如果一個(gè)組件 X 要調(diào)用組件 Y,就會(huì)再 X 的定義中加入 y weaver.Ref[Y],因此這里 Main 組件將會(huì)調(diào)用 Reverser 組件。

在創(chuàng)建 Main 組件時(shí),會(huì)從“注冊(cè)表”中找到組件 Reverser 的“真正”實(shí)現(xiàn),并將其交給 Main 組件。

這里的真正實(shí)現(xiàn),可能是本地的調(diào)用,也可能是遠(yuǎn)程的調(diào)用。怎么實(shí)現(xiàn)的?還有很重要的一步:生成代碼。

生成代碼

然后執(zhí)行下面的命令生成代碼 weaver_gen.go:

weaver generate

簡(jiǎn)單看下文件的內(nèi)容(里面用了大量的反射),首先有個(gè) init() 方法進(jìn)行組件的注冊(cè),注冊(cè)信息包括

  • 組件名
  • 接口
  • 接口的實(shí)現(xiàn)
  • 本地調(diào)用 stub
  • 遠(yuǎn)程調(diào)用的客戶端 stub
  • 供遠(yuǎn)程調(diào)用的服務(wù)端 stub
  • 通過(guò)反射進(jìn)行方法調(diào)用的 stub

其中幾個(gè) stub 也都在 weaver_gen.go 文件中,由上面的命令自動(dòng)生成。

因此,假如不執(zhí)行 weaver generate 命令就沒(méi)有 weaver_gen.go 文件,在運(yùn)行時(shí)也就找不到任何組件的注冊(cè)信息的。

運(yùn)行

現(xiàn)在可以運(yùn)行應(yīng)用:

go run .          
╭───────────────────────────────────────────────────╮
│ app        : hello-sample                         │
│ deployment : 09caf84b-822c-44d3-a149-a5b2e733a136 │
╰───────────────────────────────────────────────────╯
Hello, World!

對(duì)服務(wù)來(lái)說(shuō)用這種方式來(lái)觸發(fā)調(diào)用肯定不合理,而是應(yīng)該讓其接收 HTTP 的流量。

進(jìn)階 - 單進(jìn)程部署部署

接下來(lái),使用下面的代碼替換 main.go:

package main

import (
    "context"
    "fmt"
    "log"
    "net/http"

    "github.com/ServiceWeaver/weaver"
)

func main() {
    if err := weaver.Run(context.Background(), serve); err != nil {
        log.Fatal(err)
    }
}

type app struct {
    weaver.Implements[weaver.Main]
    reverser weaver.Ref[Reverser]
    hello    weaver.Listener
}

func serve(ctx context.Context, app *app) error {
    // The hello listener will listen on a random port chosen by the operating
    // system. This behavior can be changed in the config file.
    fmt.Printf("hello listener available on %v\n", app.hello)

    // Serve the /hello endpoint.
    http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
        name := r.URL.Query().Get("name")
        if name == "" {
            name = "World"
        }
        reversed, err := app.reverser.Get().Reverse(ctx, name)
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }
        fmt.Fprintf(w, "Hello, %s!\n", reversed)
    })
    return http.Serve(app.hello, nil)
}

在定義 Main 組件時(shí)加入了 hello weaver.Listener,Service Weaver 會(huì)自動(dòng)初始化一個(gè) HTTP 監(jiān)聽(tīng)器,并接收網(wǎng)絡(luò)流量。

在 serve 中定義了 HTTP 路徑 /hello:在接收到流量后從請(qǐng)求中讀取參數(shù) name 的值,然后調(diào)用 Reverser 組件;同時(shí) serve 返回的 http.Server 運(yùn)行在 Main 組件的 HTTP 監(jiān)聽(tīng)器上。

生成代碼

由于修改了 Main 組件的定義,需要執(zhí)行 weaver generate 重新生成代碼。在更新后的 weaver_gen.go中可以看到 Main 組件的注冊(cè)信息多了一個(gè) Listeners,值是個(gè)字符串?dāng)?shù)組 []string{"hello"},對(duì)應(yīng)著代碼中監(jiān)聽(tīng)器的名字 hello。

配置文件

此時(shí)如果運(yùn)行應(yīng)用,會(huì)隨機(jī)給應(yīng)用分配一個(gè)端口。如果要自定義端口的話,就需要增加配置文件了。

創(chuàng)建一個(gè)名為 weaver.toml 的文件,內(nèi)容如下:

[single]
listeners.hello = {address = "localhost:12345"}

在配置文件中設(shè)置監(jiān)聽(tīng)器 hello 的監(jiān)聽(tīng)地址。

運(yùn)行

在運(yùn)行時(shí)需要將配置文件的路徑提供給應(yīng)用。

SERVICEWEAVER_CONFIG=weaver.toml go run . 
╭───────────────────────────────────────────────────╮
│ app        : hello-sample                         │
│ deployment : 68e82ba2-a5ba-49c0-8b56-4edb775dba4b │
╰───────────────────────────────────────────────────╯
hello listener available on 127.0.0.1:12345

發(fā)送請(qǐng)求,可以收到反轉(zhuǎn)后的字符串。

curl "localhost:12345/hello?name=world"
Hello, dlrow!

[!INFO] 可以通過(guò) /debug/weaver/healthz 端點(diǎn)查看應(yīng)用的健康狀態(tài)。 curl -i "localhost:12345/debug/weaver/healthz" HTTP/1.1 200 OK Date: Wed, 11 Oct 2023 00:20:01 GMT Content-Length: 2 Content-Type: text/plain; charset=utf-8 OK

進(jìn)階 - 多進(jìn)程

配置文件

接下來(lái)修改配置文件,用下面的內(nèi)容替換:

[serviceweaver]
binary = "./hello-sample"
[multi]
listeners.hello = {address = "localhost:12345"}

在配置文件中,這次我們加入了二進(jìn)制文件地址,以及多進(jìn)程部署的地址。

運(yùn)行

因?yàn)槭嵌噙M(jìn)程運(yùn)行無(wú)法使用 go run 命令了,此時(shí)要用到 weaver multi 命令了(通過(guò) weaver multi -h查看使用方式):

weaver multi deploy weaver.toml 
╭───────────────────────────────────────────────────╮
│ app        : hello-sample                         │
│ deployment : 9956d5c9-e88b-4d0f-a808-d4f7f475ed36 │
╰───────────────────────────────────────────────────╯
S1011 08:36:28.419836 stdout               5df75365                      │ hello listener available on 127.0.0.1:12345
S1011 08:36:28.419922 stdout               74d79043                      │ hello listener available on 127.0.0.1:12345

weaver multi 為每個(gè)組件各創(chuàng)建了兩個(gè)副本,因此可以看到打印了兩行日志。如果再次發(fā)送請(qǐng)求,也會(huì)得到同樣的應(yīng)答。

這次我們通過(guò) Weaver Dashboard 來(lái)查看應(yīng)用情況,通過(guò)下面的命令啟用 dashboard(為其隨機(jī)分配監(jiān)聽(tīng)接口):

weaver multi dashboard
Dashboard available at: http://127.0.0.1:56108

在瀏覽器中可以打開(kāi)其 dashboard。

圖片圖片

點(diǎn)擊鏈接后可以獲取其詳細(xì)信息,其中就可以看到每個(gè)組件都有兩個(gè)進(jìn)程:

圖片圖片

Dashboard 展示的信息相比命令行的內(nèi)容會(huì)更加詳細(xì):

weaver multi status
╭────────────────────────────────────────────────────────────────╮
│ DEPLOYMENTS                                                    │
├──────────────┬──────────────────────────────────────┬──────────┤
│ APP          │ DEPLOYMENT                           │ AGE      │
├──────────────┼──────────────────────────────────────┼──────────┤
│ hello-sample │ 9956d5c9-e88b-4d0f-a808-d4f7f475ed36 │ 1h46m17s │
╰──────────────┴──────────────────────────────────────┴──────────╯
╭──────────────────────────────────────────────────────────────────╮
│ COMPONENTS                                                       │
├──────────────┬────────────┬───────────────────────┬──────────────┤
│ APP          │ DEPLOYMENT │ COMPONENT             │ REPLICA PIDS │
├──────────────┼────────────┼───────────────────────┼──────────────┤
│ hello-sample │ 9956d5c9   │ weaver.Main           │ 28079, 28082 │
│ hello-sample │ 9956d5c9   │ hello-sample.Reverser │ 28083, 28084 │
╰──────────────┴────────────┴───────────────────────┴──────────────╯
╭────────────────────────────────────────────────────────╮
│ LISTENERS                                              │
├──────────────┬────────────┬──────────┬─────────────────┤
│ APP          │ DEPLOYMENT │ LISTENER │ ADDRESS         │
├──────────────┼────────────┼──────────┼─────────────────┤
│ hello-sample │ 9956d5c9   │ hello    │ 127.0.0.1:12345 │
╰──────────────┴────────────┴──────────┴─────────────────╯

進(jìn)階 - 云端部署

[!IMPORTANT] 注意! 接下來(lái)的操作是在 X86 的平臺(tái)上完成的。

安裝 weaver-kube

使用 weaver-kube[5] 可以將應(yīng)用部署到普通的 Kubernetes 上。

go install github.com/ServiceWeaver/weaver-kube/cmd/weaver-kube@latest
weaver-kube version 
weaver kube v0.21.2 darwin/arm64

配置文件

使用下面的內(nèi)容替換 weaver.toml 文件:

[serviceweaver]
binary = "./hello-sample"
[kube]
repo = "docker.io/addozhang"
listeners.hello = {public = true}

這次使用 kube 配置,對(duì)應(yīng) weaver kube deploy 操作。其中 repo 是執(zhí)行操作時(shí)構(gòu)建鏡像所推送的倉(cāng)庫(kù)地址,設(shè)置監(jiān)聽(tīng)器為 {public = true} 將會(huì)為其創(chuàng)建 Kubernetes LoadBalancer Service。

weaver kube deploy weaver.toml

...
Generating kube deployment info ...
Generated roles and bindings
Replica sets generated successfully [hello-sample/Reverser github.com/ServiceWeaver/weaver/Main]
Generated kube deployment for replica set github.com/ServiceWeaver/weaver/Main
Generated kube autoscaler for replica set github.com/ServiceWeaver/weaver/Main
Generated kube listener service for listener hello
Generated kube deployment for replica set hello-sample/Reverser
Generated kube autoscaler for replica set hello-sample/Reverser
Generated Jaeger deployment
Generated Jaeger service
Generated kube deployment for config map hello-sample-prometheus-config-4beb9a0b
Generated kube deployment for Prometheus hello-sample-prometheus-21ee5ea1
Generated kube service for Prometheus hello-sample-prometheus-21ee5ea1
Generated kube deployment for config map hello-sample-loki-config-e2c46e76
Generated kube deployment for config map hello-sample-promtail-b648e7f2
Generated kube deployment for Loki hello-sample-loki-e8d90de6
Generated kube service for Loki hello-sample-loki-e8d90de6
Generated kube daemonset for Promtail hello-sample-promtail-b648e7f2
Generated kube deployment for config map hello-sample-grafana-config-a873d265
Generated Grafana deployment
Generated Grafana service
kube deployment information successfully generated
/tmp/kube_1cfbd355-10a4-47b6-aaec-efd9bbd17a06.yaml

鏡像推送到倉(cāng)庫(kù)后,還會(huì)生成部署所需的 manifest 文件,執(zhí)行命令進(jìn)行部署:

kubectl apply -f /tmp/kube_1cfbd355-10a4-47b6-aaec-efd9bbd17a06.yaml

集群我用的是 k3s 創(chuàng)建的:

export INSTALL_K3S_VERSION=v1.27.1+k3s1 curl -sfL https://get.k3s.io | sh -s - --disable traefik --disable local-storage --disable metrics-server --write-kubeconfig-mode 644 --write-kubeconfig ~/.kube/config

測(cè)試

查看 Pod 和 LoadBalancer 的端口,可以看到為兩個(gè)組件各創(chuàng)建了一個(gè) Pod。

kubectl get po,svc -l appName=hello-sample
NAME                                                                  READY   STATUS    RESTARTS   AGE
pod/hello-sample-github-com-serviceweaver-weaver-main-a0713fddsfgb2   1/1     Running   0          6h16m
pod/hello-sample-hello-sample-reverser-ad954898-01bf315f-86df6pvchc   1/1     Running   0          6h16m

kubectl get svc -l lisName=hello                                                                                                                                                                                default ?
NAME                              TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
hello-sample-lis-hello-4701ccf4   LoadBalancer   10.43.195.210   10.0.2.4      80:31340/TCP   6h17m

在宿主機(jī)上執(zhí)行命令,執(zhí)行成功。

curl "localhost/hello?name=world"
Hello, dlrow!

總結(jié)

Service Weaver 的思路很好,針對(duì)目前微服務(wù)架構(gòu)的問(wèn)題做了優(yōu)化和提升,再加上有 Google 的背書(shū),希望繼續(xù)演進(jìn)下去。尤其當(dāng)前只支持 Go 語(yǔ)言,雖說(shuō) Go 在云原生中風(fēng)生水起,當(dāng)時(shí)業(yè)務(wù)開(kāi)發(fā)大部分仍是 Java 技術(shù)棧。在業(yè)務(wù)開(kāi)發(fā)中,Go 的受眾還是相當(dāng)小。

當(dāng)前的版本是 v0.21.2,仍處于很早期的階段,請(qǐng)謹(jǐn)慎對(duì)待(源碼里搜了下 TODO 關(guān)鍵詞有 100 多處)。

沒(méi)有完美的架構(gòu),沒(méi)有銀彈!

參考資料

[1] Google 開(kāi)源了 Service Weaver: https://opensource.googleblog.com/2023/03/introducing-service-weaver-framework-for-writing-distributed-applications.html

[2] 在線商城: https://github.com/ServiceWeaver/onlineboutique

[3] 研究表明的:多大三分之二的故障是由系統(tǒng)多個(gè)版本之間的交互引起的: https://scholar.google.com/scholar?cluster=4116586908204898847

[4] 安裝文檔: https://serviceweaver.dev/docs.html#installation

[5] weaver-kube: https://github.com/ServiceWeaver/weaver-kube

責(zé)任編輯:武曉燕 來(lái)源: 云原生指北
相關(guān)推薦

2023-03-24 09:17:04

微服務(wù)架構(gòu)谷歌

2020-05-27 11:57:11

華為

2022-12-21 16:13:31

微服務(wù)架構(gòu)

2022-03-29 08:30:15

微服務(wù)架構(gòu)單體架構(gòu)

2022-04-11 17:33:29

微服務(wù)架構(gòu)單體

2024-01-19 11:57:42

2022-08-05 07:37:39

單體架構(gòu)遷移微服務(wù)

2024-11-19 08:10:00

2023-11-01 11:17:26

單體架構(gòu)微服務(wù)架構(gòu)

2023-02-27 16:24:17

架構(gòu)開(kāi)發(fā)數(shù)字化

2018-07-04 14:17:10

微服務(wù)代碼開(kāi)發(fā)

2020-10-11 16:56:10

分解單體式數(shù)據(jù)庫(kù)數(shù)據(jù)庫(kù)微服務(wù)

2019-07-31 10:21:15

單體架構(gòu)微服務(wù)

2019-01-07 08:10:54

微服務(wù)單體 Web

2024-01-26 06:06:26

單體微服務(wù)容器化

2023-12-19 22:29:37

架構(gòu)微服務(wù)系統(tǒng)

2020-04-14 10:06:20

微服務(wù)Netflix語(yǔ)言

2022-08-22 14:27:30

微服務(wù)遷移

2024-07-01 09:55:13

2022-02-22 08:15:59

微服務(wù)架構(gòu)單體架構(gòu)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)