Service Weaver:Google开源基于分布式应用程序开发的框架,重新定义微服务边界

本文主要是介绍Service Weaver:Google开源基于分布式应用程序开发的框架,重新定义微服务边界,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

大家好,我是萧楚河,公众号:golang面试经典讲解,感谢关注,一起学习一起成长。

一、前言

今年6月,一群谷歌员工(由谷歌软件工程师Michael Whittaker领导)发表了一篇名为“Towards Modern Development of Cloud Applications”的论文。

正如Whittaker等人所指出的,从架构上讲,微服务本身设置就有问题,它是一个没有边界的结构它们将逻辑边界(如何编写代码)与物理边界(如何部署代码)混为一谈。这就是问题的开始。

因此,谷歌的工程师们提出了一种堪称“微服务2.0”的方法。将应用程序构建为逻辑整体,但将其交给自动化运行时,后者可以根据应用程序所需的内容和可用的内容来决定在哪里运行工作负载。

基于新提出的结构,他们能够将系统的延迟降低15倍,成本降低9倍。

“从有组织的模块化代码开始,我们就可以将部署架构作为实现细节,”Google开发人员倡导者Kelsey Hightower在10月份对这项工作表示了下一步计划。

鉴于以上实践,诞生了Service Weaver。

1.1 什么是Service Weaver

ServiceWeaver是一个用于编写、部署和管理分布式应用程序的编程框架。您可以在机器上本地运行、测试和调试Service Weaver应用程序,然后使用单个命令将该应用程序部署到云中。

Service Weaver应用程序由许多组件组成。组件被呈现为常规Go接口,组件之间通过调用这些接口定义的方法来相互交互。这使得编写Service Weaver应用程序变得容易。你不需要编写任何联网或序列化代码,你只要写Go。Service Weaver还提供用于日志记录、度量、跟踪、路由、测试等的库。

1.2 什么是模块单体应用?

对于不熟悉的人来说,模块化单体应用是一种体系结构,其中整个应用程序都写成一个单独的应用程序,在一个单一的代码库中。模块化方面意味着单体应用被分成单独的组件,并且在不同组件之间有干净明确的接口。

这里是一个例子:
在这里插入图片描述

在这个单体应用中,有三个组件:订单、支付和运输。每个组件实现单体应用的一个特定部分,关键在于每个组件的大部分都是私有的,并且组件之间的任何通信都是通过明确定义的接口进行的。

这使得每个组件的内部可以进行更改和更新,而不会影响任何其他组件,假设接口未更改或破坏。

当多个团队在单体应用上工作时,这确实有助于在团队之间设定明确的边界,并使每个组件独立于其他任何组件发展,同时在组件之间显示明确的依赖关系。

每当你的单体应用被部署时,它都被部署为一个单一的应用程序,每个单体应用的实例都运行一个单一的进程。例如,如果你要部署到AWS,每个单体应用的实例都将作为一个进程运行在EC2实例上。

二、Service Weaver工作原理

2.1 与模块化单体应用区别

Service Weaver和传统的模块化单体应用之间的区别在于部署方式。使用Service Weaver构建的应用程序在部署时,不是将所有组件运行在同一台机器上的一个大进程。

在这里插入图片描述
相反,每个组件都作为一个独立的微服务进行部署。这非常巧妙,因为您既可以获得将所有代码放在单个代码库中并进行方便的本地开发的好处,又可以获得运行分布式架构的好处,其中您可以根据需要缩放每个组件,例如内存,CPU和实例数量等。

2.2 如何工作的?

ServiceWeaver的核心抽象是组件。组件就像一个参与者,ServiceWeaver应用程序是作为一组组件来实现的。具体地说,组件用一个常规Go接口表示,组件通过调用这些接口定义的方法来相互交互。

2.2.1 单组件

在本节中,我们将定义一个简单的hello组件,它只打印一个字符串并返回。首先,运行go mod init hello来创建一个go模块。

mkdir hello/
cd hello/
go mod init hello然后,创建一个名为main.go的文件,其中包含以下内容:

package main

import (
“context”
“fmt”
“log”

"github.com/ServiceWeaver/weaver"

)

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

// app is the main component of the application. weaver.Run creates
// it and passes it to serve.
type app struct{
weaver.Implements[weaver.Main]
}

// serve is called by weaver.Run and contains the body of the application.
func serve(context.Context, *app) error {
fmt.Println(“Hello”)
return nil
}

在构建和运行应用程序之前,我们需要运行ServiceWeaver的代码生成器,称为weavergenerate。weavergenerate编写一个weaver_gen.go文件,其中包含ServiceWeaver运行时所需的代码。我们将详细说明weaver generate到底做了什么,以及为什么我们稍后需要运行它。最后,运行应用程序!

$ go mod tidy
$ weaver generate .
$ go run .
Hello

2.2.2 多组件

在ServiceWeaver应用程序中,任何组件都可以调用任何其他组件。为了演示这一点,我们引入了第二个Reverser组件。创建一个文件Reverser.go。转到以下内容:

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组件由Reverse接口表示,该接口具有反转字符串的Reverse方法。reverser结构是我们对reverser组件的实现(如weaver.Implements[Reverser]所示它包含的字段)。

接下来,在main.go中编辑应用程序组件以使用reverser组件:


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]hello    weaver.Listener
}func serve(ctx context.Context, app *app) error {// Call the Reverse method.// 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)
}

应用程序结构有一个类型为weaver.Ref[Reverser]的新字段,提供对反向器组件的访问权限。

2.2.3 多进程执行

我们已经了解了如何通过go run在单个流程中运行Service Weaver应用程序。现在,我们将在多个进程中运行我们的应用程序,在作为RPC执行的组件之间进行方法调用。首先,创建一个名为weaver.toml的TOML配置文件,其中包含以下内容:

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

此配置文件指定ServiceWeaver应用程序的二进制文件,以及hello侦听器的固定地址。接下来,使用weaver multi-deploy构建并运行应用程序:

go build                        # build the ./hello binary
weaver multi deploy weaver.toml # deploy the application

2.3 微服务如何组合?

我发现图表有助于理解的一个例子,这是Google解释了这些不同部分如何组合在一起的图表:

在这里插入图片描述
我们还没有谈到 Service Weaver 框架的多功能性。传统微服务的一个缺点是,你经常会遇到接口过于频繁的问题。毕竟,没有人能预见架构的演变方向。

然后,你不得不忍受增加的延迟和更高的网络调用失败率,或者花时间将这两个微服务合并起来。

使用 Service Weaver,这个问题得到了解决。如果你查看上面的图表,你会发现有四个模块被定义了。当部署为微服务时,你会注意到 A 和 B 住在一起,C 和 D 是他们自己的微服务。

使用 Service Weaver,你可以自由地定义组件在哪里部署。你可以选择让多个组件一起运行在单个微服务中,或者将所有组件都部署为单独的微服务。如果你的应用程序演变到两个组件变得过于频繁,并且作为单独的微服务运行,你可以轻松地将它们合并,而不需要改变代码,并在 Service Weaver 中快速更改配置。

三、Service Weaver使用

这里基于我的理解对Service Weaver的初步介绍,鉴于很多人可能希望自己实践一下,可以通过如下地址进入官方网站进行学习:https://serviceweaver.dev

这篇关于Service Weaver:Google开源基于分布式应用程序开发的框架,重新定义微服务边界的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/577406

相关文章

GSON框架下将百度天气JSON数据转JavaBean

《GSON框架下将百度天气JSON数据转JavaBean》这篇文章主要为大家详细介绍了如何在GSON框架下实现将百度天气JSON数据转JavaBean,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录前言一、百度天气jsON1、请求参数2、返回参数3、属性映射二、GSON属性映射实战1、类对象映

sysmain服务可以禁用吗? 电脑sysmain服务关闭后的影响与操作指南

《sysmain服务可以禁用吗?电脑sysmain服务关闭后的影响与操作指南》在Windows系统中,SysMain服务(原名Superfetch)作为一个旨在提升系统性能的关键组件,一直备受用户关... 在使用 Windows 系统时,有时候真有点像在「开盲盒」。全新安装系统后的「默认设置」,往往并不尽编

Python 基于http.server模块实现简单http服务的代码举例

《Python基于http.server模块实现简单http服务的代码举例》Pythonhttp.server模块通过继承BaseHTTPRequestHandler处理HTTP请求,使用Threa... 目录测试环境代码实现相关介绍模块简介类及相关函数简介参考链接测试环境win11专业版python

Nginx中配置使用非默认80端口进行服务的完整指南

《Nginx中配置使用非默认80端口进行服务的完整指南》在实际生产环境中,我们经常需要将Nginx配置在其他端口上运行,本文将详细介绍如何在Nginx中配置使用非默认端口进行服务,希望对大家有所帮助... 目录一、为什么需要使用非默认端口二、配置Nginx使用非默认端口的基本方法2.1 修改listen指令

解决Nginx启动报错Job for nginx.service failed because the control process exited with error code问题

《解决Nginx启动报错Jobfornginx.servicefailedbecausethecontrolprocessexitedwitherrorcode问题》Nginx启... 目录一、报错如下二、解决原因三、解决方式总结一、报错如下Job for nginx.service failed bec

SysMain服务可以关吗? 解决SysMain服务导致的高CPU使用率问题

《SysMain服务可以关吗?解决SysMain服务导致的高CPU使用率问题》SysMain服务是超级预读取,该服务会记录您打开应用程序的模式,并预先将它们加载到内存中以节省时间,但它可能占用大量... 在使用电脑的过程中,CPU使用率居高不下是许多用户都遇到过的问题,其中名为SysMain的服务往往是罪魁

解决若依微服务框架启动报错的问题

《解决若依微服务框架启动报错的问题》Invalidboundstatement错误通常由MyBatis映射文件未正确加载或Nacos配置未读取导致,需检查XML的namespace与方法ID是否匹配,... 目录ruoyi-system模块报错报错详情nacos文件目录总结ruoyi-systnGLNYpe

Nginx进行平滑升级的实战指南(不中断服务版本更新)

《Nginx进行平滑升级的实战指南(不中断服务版本更新)》Nginx的平滑升级(也称为热升级)是一种在不停止服务的情况下更新Nginx版本或添加模块的方法,这种升级方式确保了服务的高可用性,避免了因升... 目录一.下载并编译新版Nginx1.下载解压2.编译二.替换可执行文件,并平滑升级1.替换可执行文件

Django中的函数视图和类视图以及路由的定义方式

《Django中的函数视图和类视图以及路由的定义方式》Django视图分函数视图和类视图,前者用函数处理请求,后者继承View类定义方法,路由使用path()、re_path()或url(),通过in... 目录函数视图类视图路由总路由函数视图的路由类视图定义路由总结Django允许接收的请求方法http

Python Web框架Flask、Streamlit、FastAPI示例详解

《PythonWeb框架Flask、Streamlit、FastAPI示例详解》本文对比分析了Flask、Streamlit和FastAPI三大PythonWeb框架:Flask轻量灵活适合传统应用... 目录概述Flask详解Flask简介安装和基础配置核心概念路由和视图模板系统数据库集成实际示例Stre