当前位置:首页 > 科技  > 软件

单体 or 微服务?Service Weaver:我全都要!

来源: 责编: 时间:2023-10-13 14:37:01 189观看
导读TL;DR怎么理解 Service Weaver,就是一个应用中有很多的接口,这些接口间会互相调用。如果将操作系统进程(应用)比做一块电路板,接口比做元器件。可以选择将哪些元器件放入该电路板中,哪些元器件放入其他的电路板中。同一块电

TL;DR

怎么理解 Service Weaver,就是一个应用中有很多的接口,这些接口间会互相调用。如果将操作系统进程(应用)比做一块电路板,接口比做元器件。可以选择将哪些元器件放入该电路板中,哪些元器件放入其他的电路板中。Z8B28资讯网——每日最新资讯28at.com

同一块电路板中的元器件间通过板上的导线连接(进程内的本地方法调用);不同电路板中的元器件间通过排线来连接(远程方法调用)。Z8B28资讯网——每日最新资讯28at.com

总结几个关键词:Z8B28资讯网——每日最新资讯28at.com

  • 一个编程框架
  • 用于编写、部署、管理分布式应用
  • 支持的语言 Go
  • 在本地以单进程、多进程运行
  • 在云端由框架拆分成微服务,并于云供应商集成
  • 单体方式开发,微服务方式部署

体验了一圈下来,给我的感觉有点类似 Notion、Obsidian 这类笔记软件。传统的笔记软件只能引用其他的笔记,而这类笔记可以细粒度到 heading 内容。Z8B28资讯网——每日最新资讯28at.com

放到微服务下就是管理的维度不在是服务本身,而且更小的接口,并且对某些接口进行扩展,即使所有接口都位于同一个二进制文件中。Z8B28资讯网——每日最新资讯28at.com

背景

架构的演进,总是在解决问题的过程中引入新的问题,然后再解决问题,循环往复。Z8B28资讯网——每日最新资讯28at.com

从单体到微服务

软件架构从单体演进到微服务架构已经十多年了,尤其是近几年云原生风生水起,微服务架构已有深入人心的架势。Z8B28资讯网——每日最新资讯28at.com

单体架构由于在规模扩大时,单体面临性能瓶颈和硬件限制、无法支撑业务的快读迭代、开发效率下降协同难度增加等原因,颓势日渐明显。然后就有了微服务架构的提出,来解决单体架构的各种问题。Z8B28资讯网——每日最新资讯28at.com

上云

由于云平台提供显著的成本效益,减少初始投资并实现按需付费、提供极大的灵活性和可扩展性、提供的稳定性和可靠性确保业务连续性、专业的安全保障和合规性支持减轻企业的运营负担,企业将其业务和数据迁移至云计算平台。Z8B28资讯网——每日最新资讯28at.com

问题

拆分成微服务,由此带来了不少好处:更高效的应用扩展、更小的错误传播半径、独立的安全域以及完善的模块边界。Z8B28资讯网——每日最新资讯28at.com

反过来,如何正确地找到边界进行拆分并非易事。拆分的依据是什么?two pizza team?依据资源使用、组织架构、数据结构?亦或是考虑未来的增长?Z8B28资讯网——每日最新资讯28at.com

微服务的拆分执行下来毫无章法,最终的结果是微服务越来越多、更多的故障点、更长的链路、更大的延迟。这实际上增加了应用的开发、部署和管理成本。Z8B28资讯网——每日最新资讯28at.com

  • 原本单个二进制文件,拆分后有多个;原本一次部署完成,拆分后需要多个 CI/CD 流水线来部署;原本一个配置文件,拆分后需要维护多个。
  • 微服务彼此独立部署,无法忽略多版本的情况。需要调整部署策略来降低风险,同样还有本地开发和测试的难度增加。
  • 学习成本高,需要学习如何将应用二进制文件包装成容器,并了解云的各种工具和部署方式,即使对经验丰富的程序员来说也难以理解。
  • 同时还要解决分布式带来的各种问题,如服务发现、安全、负载均衡,以及服务间的调用。
  • 延迟增加,时间消耗在数据的序列化以及网络传输上。

为什么用 Service Weaver?

今年 3 月 Google 开源了 Service Weaver[1],希望能解决微服务架构的各种问题。Z8B28资讯网——每日最新资讯28at.com

有了 Servier Weaver,你可以专注在业务逻辑的开发上,其他的工作交给 Service Weaver 来完成。Z8B28资讯网——每日最新资讯28at.com

无需要纠结微服务的拆分规则,可以拆分为任意数量的组件。可以在部署的时候轻松指定哪些组件作为一个微服务来运行,哪些在不同的微服务上运行。Z8B28资讯网——每日最新资讯28at.com

使用 Service 可以部署和管理单一二进制文件。Z8B28资讯网——每日最新资讯28at.com

Service Weaver 使用自定义的序列化和传输协议,成本效益比行业最佳的解决方案(gRPC+protobuf)高出三倍。Z8B28资讯网——每日最新资讯28at.com

如何使用 Service Weaver 开发应用?

Service Weaver 的核心是组件(component),一个类似 actor 的计算单元。Z8B28资讯网——每日最新资讯28at.com

组件是个常见的 Go 接口,组件间的交互通过调用接口定义的方法来完成。Z8B28资讯网——每日最新资讯28at.com

下面的示例中定义了一个 Reverser 组件,用于反转字符串。Z8B28资讯网——每日最新资讯28at.com

// 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}

其他组件可以调用 Reverser 组件的方法:Z8B28资讯网——每日最新资讯28at.com

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

组件的最大优点是不依赖于系统进程。上面的例子中,尽管没有编写任何网络和序列化相关的代码,这些组件可以运行在不同的进程中甚至是不同的机器上。Z8B28资讯网——每日最新资讯28at.com

图片图片Z8B28资讯网——每日最新资讯28at.com

如上图所示,如果组件位于同一个进程中,方法的调用就是传统的 Go 方法调用;如果位于不同的进程中,方法的调用就是 RPC。Z8B28资讯网——每日最新资讯28at.com

将应用拆分为不同组件的过程,有点类似微服务的拆分。组件也同样有着清晰的边界,以及很好的扩展性。但又没有微服务的缺陷:Z8B28资讯网——每日最新资讯28at.com

  • 所有组件都运行同一个版本,无需考虑版本的兼容性。
  • 可以很容易地通过 go run 和 go test 运行和测试应用。
  • 微服务的拆分和合并是非常痛苦的。

如何管理 Service Weaver 应用?

部署

在云上运行就跟本地运行一样简单:Z8B28资讯网——每日最新资讯28at.com

$ 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 需要的配置非常少。一个 在线商城[2] 的演示中可能需要超过 1500 行配置,而 Service Weaver 编写的同样应用所需的配置不超过 10 行:Z8B28资讯网——每日最新资讯28at.com

[weaver]binary = "./online_boutique"rollout = "6h"[gke]regions = ["us-west1", "us-east2"]listeners.boutique = {public_hostname = "online-boutique"}

只需指定二进制文件、部署的持续时间、部署的区域以及公开访问的地址。就这么简单。Z8B28资讯网——每日最新资讯28at.com

发布新版本

传统的微服务,在发布新版本时,旧版本的示例可以会与其他新版本的示例进行通信。Z8B28资讯网——每日最新资讯28at.com

Service Weaver 使用不同的方式升级,确保客户端的请求完全在相同的版本下处理:不同版本的组件不会发生通信。Z8B28资讯网——每日最新资讯28at.com

这就避免了大多数的系统故障:研究表明的:多大三分之二的故障是由系统多个版本之间的交互引起的[3]。Z8B28资讯网——每日最新资讯28at.com

有了 Service Weaver,仅需更新代码、构建、运行即可,其他的交给 Service Weaver。Z8B28资讯网——每日最新资讯28at.com

可观测性

Service Weaver 提供了用于日志、指标和链路跟踪的库,并自动与应用的部署环境集成。Z8B28资讯网——每日最新资讯28at.com

下面的示例演示了如何为 Reverser 组件添加计数指标:Z8B28资讯网——每日最新资讯28at.com

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)    // ...}

测试

传统的微服务,应用开发周期非常慢。在迭代中,需要安装笨重的云依赖、复杂的测试框架,或者部署到云上。这些都极大影响了开发进度。Z8B28资讯网——每日最新资讯28at.com

有了 Service Weaver 可以想运行 Go 程序一样完成构建、运行、测试。提供的 weavertest包可用来编写端到端测试,就像写单元测试一样简单。Z8B28资讯网——每日最新资讯28at.com

演示

安装 Service Weaver

参考 安装文档[4],注意要求 Go 的版本不低于 1.21。在 macOS 上直接用 Homebrew 安装:Z8B28资讯网——每日最新资讯28at.com

brew install  service-weaverweaver versionweaver v0.21.2 darwin/arm64go versiongo version go1.21.3 darwin/arm64

初始化工程

mkdir hello-samplecd hello-samplego mod init hello-sample

使用上面 Reverser 组件的例子。Z8B28资讯网——每日最新资讯28at.com

编写 Reverser 组件

创建 reverser.go 文件,内容如下:Z8B28资讯网——每日最新资讯28at.com

package mainimport (    "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 组件通过定义创建接口 Reverser 定义,该接口定义了用于反转字符串的方法 Reverse;结构体类型 reverser 通过 weaver.Implements[Reverser] 定义为组件 Reverser 的实现。Z8B28资讯网——每日最新资讯28at.com

接下来是调用组件的代码。Z8B28资讯网——每日最新资讯28at.com

编写 Main 组件

创建 main.go 文件,内容如下,也就是 main 组件:Z8B28资讯网——每日最新资讯28at.com

package mainimport (    "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(...) 初始化并运行 Service Weaver 应用,每个应用都有一组组件组成。运行时会自动创建 weaver.Main 并将其交给应用。Z8B28资讯网——每日最新资讯28at.com

查看其源码可以看到使用了泛型:Z8B28资讯网——每日最新资讯28at.com

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

Run 执行时会先找到 Main 组件的定义,在上面的代码中结构体类型 app 被定义为 weaver.Main 组件,然后创建该组件并将其交给代码中的 serve 来使用,然后调用 serve 函数。Z8B28资讯网——每日最新资讯28at.com

在 Main 组件 app 中我们还可以看到 reverser weaver.Ref[Reverser]。在 Service Weaver 中,如果一个组件 X 要调用组件 Y,就会再 X 的定义中加入 y weaver.Ref[Y],因此这里 Main 组件将会调用 Reverser 组件。Z8B28资讯网——每日最新资讯28at.com

在创建 Main 组件时,会从“注册表”中找到组件 Reverser 的“真正”实现,并将其交给 Main 组件。Z8B28资讯网——每日最新资讯28at.com

这里的真正实现,可能是本地的调用,也可能是远程的调用。怎么实现的?还有很重要的一步:生成代码。Z8B28资讯网——每日最新资讯28at.com

生成代码

然后执行下面的命令生成代码 weaver_gen.go:Z8B28资讯网——每日最新资讯28at.com

weaver generate

简单看下文件的内容(里面用了大量的反射),首先有个 init() 方法进行组件的注册,注册信息包括Z8B28资讯网——每日最新资讯28at.com

  • 组件名
  • 接口
  • 接口的实现
  • 本地调用 stub
  • 远程调用的客户端 stub
  • 供远程调用的服务端 stub
  • 通过反射进行方法调用的 stub

其中几个 stub 也都在 weaver_gen.go 文件中,由上面的命令自动生成。Z8B28资讯网——每日最新资讯28at.com

因此,假如不执行 weaver generate 命令就没有 weaver_gen.go 文件,在运行时也就找不到任何组件的注册信息的。Z8B28资讯网——每日最新资讯28at.com

运行

现在可以运行应用:Z8B28资讯网——每日最新资讯28at.com

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

对服务来说用这种方式来触发调用肯定不合理,而是应该让其接收 HTTP 的流量。Z8B28资讯网——每日最新资讯28at.com

进阶 - 单进程部署部署

接下来,使用下面的代码替换 main.go:Z8B28资讯网——每日最新资讯28at.com

package mainimport (    "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 组件时加入了 hello weaver.Listener,Service Weaver 会自动初始化一个 HTTP 监听器,并接收网络流量。Z8B28资讯网——每日最新资讯28at.com

在 serve 中定义了 HTTP 路径 /hello:在接收到流量后从请求中读取参数 name 的值,然后调用 Reverser 组件;同时 serve 返回的 http.Server 运行在 Main 组件的 HTTP 监听器上。Z8B28资讯网——每日最新资讯28at.com

生成代码

由于修改了 Main 组件的定义,需要执行 weaver generate 重新生成代码。在更新后的 weaver_gen.go中可以看到 Main 组件的注册信息多了一个 Listeners,值是个字符串数组 []string{"hello"},对应着代码中监听器的名字 hello。Z8B28资讯网——每日最新资讯28at.com

配置文件

此时如果运行应用,会随机给应用分配一个端口。如果要自定义端口的话,就需要增加配置文件了。Z8B28资讯网——每日最新资讯28at.com

创建一个名为 weaver.toml 的文件,内容如下:Z8B28资讯网——每日最新资讯28at.com

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

在配置文件中设置监听器 hello 的监听地址。Z8B28资讯网——每日最新资讯28at.com

运行

在运行时需要将配置文件的路径提供给应用。Z8B28资讯网——每日最新资讯28at.com

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

发送请求,可以收到反转后的字符串。Z8B28资讯网——每日最新资讯28at.com

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

[!INFO] 可以通过 /debug/weaver/healthz 端点查看应用的健康状态。 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 OKZ8B28资讯网——每日最新资讯28at.com

进阶 - 多进程

配置文件

接下来修改配置文件,用下面的内容替换:Z8B28资讯网——每日最新资讯28at.com

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

在配置文件中,这次我们加入了二进制文件地址,以及多进程部署的地址。Z8B28资讯网——每日最新资讯28at.com

运行

因为是多进程运行无法使用 go run 命令了,此时要用到 weaver multi 命令了(通过 weaver multi -h查看使用方式):Z8B28资讯网——每日最新资讯28at.com

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:12345S1011 08:36:28.419922 stdout               74d79043                      │ hello listener available on 127.0.0.1:12345

weaver multi 为每个组件各创建了两个副本,因此可以看到打印了两行日志。如果再次发送请求,也会得到同样的应答。Z8B28资讯网——每日最新资讯28at.com

这次我们通过 Weaver Dashboard 来查看应用情况,通过下面的命令启用 dashboard(为其随机分配监听接口):Z8B28资讯网——每日最新资讯28at.com

weaver multi dashboardDashboard available at: http://127.0.0.1:56108

在浏览器中可以打开其 dashboard。Z8B28资讯网——每日最新资讯28at.com

图片图片Z8B28资讯网——每日最新资讯28at.com

点击链接后可以获取其详细信息,其中就可以看到每个组件都有两个进程:Z8B28资讯网——每日最新资讯28at.com

图片图片Z8B28资讯网——每日最新资讯28at.com

Dashboard 展示的信息相比命令行的内容会更加详细:Z8B28资讯网——每日最新资讯28at.com

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 │╰──────────────┴────────────┴──────────┴─────────────────╯

进阶 - 云端部署

[!IMPORTANT] 注意! 接下来的操作是在 X86 的平台上完成的。Z8B28资讯网——每日最新资讯28at.com

安装 weaver-kube

使用 weaver-kube[5] 可以将应用部署到普通的 Kubernetes 上。Z8B28资讯网——每日最新资讯28at.com

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

配置文件

使用下面的内容替换 weaver.toml 文件:Z8B28资讯网——每日最新资讯28at.com

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

这次使用 kube 配置,对应 weaver kube deploy 操作。其中 repo 是执行操作时构建镜像所推送的仓库地址,设置监听器为 {public = true} 将会为其创建 Kubernetes LoadBalancer Service。Z8B28资讯网——每日最新资讯28at.com

weaver kube deploy weaver.toml...Generating kube deployment info ...Generated roles and bindingsReplica sets generated successfully [hello-sample/Reverser github.com/ServiceWeaver/weaver/Main]Generated kube deployment for replica set github.com/ServiceWeaver/weaver/MainGenerated kube autoscaler for replica set github.com/ServiceWeaver/weaver/MainGenerated kube listener service for listener helloGenerated kube deployment for replica set hello-sample/ReverserGenerated kube autoscaler for replica set hello-sample/ReverserGenerated Jaeger deploymentGenerated Jaeger serviceGenerated kube deployment for config map hello-sample-prometheus-config-4beb9a0bGenerated kube deployment for Prometheus hello-sample-prometheus-21ee5ea1Generated kube service for Prometheus hello-sample-prometheus-21ee5ea1Generated kube deployment for config map hello-sample-loki-config-e2c46e76Generated kube deployment for config map hello-sample-promtail-b648e7f2Generated kube deployment for Loki hello-sample-loki-e8d90de6Generated kube service for Loki hello-sample-loki-e8d90de6Generated kube daemonset for Promtail hello-sample-promtail-b648e7f2Generated kube deployment for config map hello-sample-grafana-config-a873d265Generated Grafana deploymentGenerated Grafana servicekube deployment information successfully generated/tmp/kube_1cfbd355-10a4-47b6-aaec-efd9bbd17a06.yaml

镜像推送到仓库后,还会生成部署所需的 manifest 文件,执行命令进行部署:Z8B28资讯网——每日最新资讯28at.com

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

集群我用的是 k3s 创建的:Z8B28资讯网——每日最新资讯28at.com

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/configZ8B28资讯网——每日最新资讯28at.com

测试

查看 Pod 和 LoadBalancer 的端口,可以看到为两个组件各创建了一个 Pod。Z8B28资讯网——每日最新资讯28at.com

kubectl get po,svc -l appName=hello-sampleNAME                                                                  READY   STATUS    RESTARTS   AGEpod/hello-sample-github-com-serviceweaver-weaver-main-a0713fddsfgb2   1/1     Running   0          6h16mpod/hello-sample-hello-sample-reverser-ad954898-01bf315f-86df6pvchc   1/1     Running   0          6h16mkubectl get svc -l lisName=hello                                                                                                                                                                                default ⎈NAME                              TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGEhello-sample-lis-hello-4701ccf4   LoadBalancer   10.43.195.210   10.0.2.4      80:31340/TCP   6h17m

在宿主机上执行命令,执行成功。Z8B28资讯网——每日最新资讯28at.com

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

总结

Service Weaver 的思路很好,针对目前微服务架构的问题做了优化和提升,再加上有 Google 的背书,希望继续演进下去。尤其当前只支持 Go 语言,虽说 Go 在云原生中风生水起,当时业务开发大部分仍是 Java 技术栈。在业务开发中,Go 的受众还是相当小。Z8B28资讯网——每日最新资讯28at.com

当前的版本是 v0.21.2,仍处于很早期的阶段,请谨慎对待(源码里搜了下 TODO 关键词有 100 多处)。Z8B28资讯网——每日最新资讯28at.com

没有完美的架构,没有银弹!Z8B28资讯网——每日最新资讯28at.com

参考资料

[1] Google 开源了 Service Weaver: https://opensource.googleblog.com/2023/03/introducing-service-weaver-framework-for-writing-distributed-applications.htmlZ8B28资讯网——每日最新资讯28at.com

[2] 在线商城: https://github.com/ServiceWeaver/onlineboutiqueZ8B28资讯网——每日最新资讯28at.com

[3] 研究表明的:多大三分之二的故障是由系统多个版本之间的交互引起的: https://scholar.google.com/scholar?cluster=4116586908204898847Z8B28资讯网——每日最新资讯28at.com

[4] 安装文档: https://serviceweaver.dev/docs.html#installationZ8B28资讯网——每日最新资讯28at.com

[5] weaver-kube: https://github.com/ServiceWeaver/weaver-kubeZ8B28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-13294-0.html单体 or 微服务?Service Weaver:我全都要!

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 商业智能在供应链管理中的作用

下一篇: 面试薪水被压?那是你还不懂多线程和高并发

标签:
  • 热门焦点
Top