Project Icon

hollywood

Go语言高性能Actor引擎实现并发分布式系统

Hollywood是一个Go语言开发的高性能Actor引擎,专注于低延迟应用。每秒可处理1000万条消息,适用于游戏服务器、广告系统和交易引擎等场景。它提供消息投递保证、远程通信和集群支持,并使用protobuf进行高效序列化。Hollywood易用且高度可定制,是构建高并发分布式系统的有力工具。

Go 报告卡 示例工作流程 Discord 徽章

Golang 的极速低延迟 Actor 框架

Hollywood 是一个为速度和低延迟应用而构建的超高速 Actor 引擎。适用于游戏服务器、广告代理、交易引擎等场景。它能在 1 秒内处理 1000 万条消息

什么是 Actor 模型?

Actor 模型是一种用于构建高并发和分布式系统的计算模型。它由 Carl Hewitt 于 1973 年提出,旨在以更可扩展和容错的方式处理复杂系统。

在 Actor 模型中,基本构建块是 Actor(在 Hollywood 中有时称为接收者),它是一个独立的计算单元,通过交换消息与其他 Actor 通信。每个 Actor 都有自己的状态和行为,只能通过发送消息与其他 Actor 通信。这种消息传递范式允许系统高度去中心化和容错,因为即使其他 Actor 失败或不可用,Actor 也可以继续独立运行。

Actor 可以组织成层级结构,高级 Actor 监督和协调低级 Actor。这允许创建复杂的系统,能够以优雅和可预测的方式处理故障和错误。

通过在应用程序中使用 Actor 模型,您可以构建高度可扩展和容错的系统,能够处理大量并发用户和复杂的交互。

特性

  • Actor 失败时保证消息传递(缓冲机制)
  • 支持即发即忘或请求响应消息传递,或两者兼有
  • 高性能 dRPC 作为传输层
  • 优化的 proto buffers,无反射
  • 轻量级且高度可定制
  • 支持集群,用于编写分布式自发现 Actor

基准测试

make bench
生成了 10 个引擎
每个引擎生成 2000 个 Actor
开始发送风暴,将使用 20 个工作线程发送 10 秒
每秒发送的消息数 3244217
..
每秒发送的消息数 3387478
并发发送者:20 发送的消息 35116641,接收的消息 35116641 - 持续时间:10s
每秒消息数:3511664
死信:0

安装

go get github.com/anthdm/hollywood/...

Hollywood 需要 Golang 版本 1.21

快速入门

我们建议您从编写一些本地运行的示例开始。本地运行会更简单一些,因为编译器能够确定使用的类型。在远程运行时,您需要为编译器提供 protobuffer 定义。

Hello world

让我们来看一个 Hello world 消息的例子。完整示例可在 hello world 文件夹中找到。让我们从 main 开始:

engine, err := actor.NewEngine(actor.NewEngineConfig())

这创建了一个新的引擎。引擎是 Hollywood 的核心。它负责生成 Actor、发送消息和处理 Actor 的生命周期。如果 Hollywood 无法创建引擎,它会返回一个错误。对于开发来说,您不应该向引擎传递任何选项,所以可以传递 nil。我们稍后会看看这些选项。

接下来我们需要创建一个 Actor。这些有时被称为 Receivers,因为它们必须实现接口。让我们创建一个新的 Actor,当它收到消息时会打印一条消息。

pid := engine.Spawn(newHelloer, "hello")

这将导致引擎生成一个 ID 为 "hello" 的 Actor。Actor 将由提供的函数 newHelloer 创建。ID 必须是唯一的。它将返回一个指向 PID 的指针。PID 是进程标识符。它是 Actor 的唯一标识符。大多数情况下,您会使用 PID 向 Actor 发送消息。对于远程系统,您将使用 ID 发送消息,但在本地系统上,您主要使用 PID。

让我们看看 newHelloer 函数和它返回的 Actor。

type helloer struct{}

func newHelloer() actor.Receiver {
	return &helloer{}
}

很简单。newHelloer 函数返回一个新的 Actor。Actor 是一个实现 actor.Receiver 的结构体。让我们看看 Receive 方法。

type message struct {}

func (h *helloer) Receive(ctx *actor.Context) {
	switch msg := ctx.Message().(type) {
	case actor.Initialized:
		fmt.Println("helloer 已初始化")
	case actor.Started:
		fmt.Println("helloer 已启动")
	case actor.Stopped:
		fmt.Println("helloer 已停止")
	case *message:
		fmt.Println("hello world", msg.data)
	}
}

您可以看到我们定义了一个消息结构体。这是我们稍后会发送给 Actor 的消息。Receive 方法还处理了一些其他消息。这些生命周期消息由引擎发送给 Actor,您将使用这些来初始化您的 Actor。

引擎将 actor.Context 传递给 Receive 方法。这个上下文包含消息、发送者的 PID 和一些其他您可以使用的依赖项。

现在,让我们向 Actor 发送一条消息。我们将发送一个 message,但您可以发送任何类型的消息。唯一的要求是 Actor 必须能够处理该消息。对于能够跨网络传输的消息,它们必须是可序列化的。对于 protobuf 能够序列化消息,它必须是一个指针。本地消息可以是任何类型。

最后,让我们向 Actor 发送一条消息。

engine.Send(pid, "hello world!")

这将向 Actor 发送一条消息。Hollywood 将把消息路由到正确的 Actor。然后 Actor 将向控制台打印一条消息。

examples 文件夹是学习和进一步探索 Hollywood 的最佳地方。

生成 Actor

当您生成一个 Actor 时,您需要提供一个返回新 Actor 的函数。在生成 Actor 时,有一些可调整的选项可以提供。

使用默认配置

e.Spawn(newFoo, "myactorname")

向构造函数传递参数

有时您可能想向 Actor 构造函数传递参数。这可以通过使用闭包来实现。在 request 示例 中有一个这样的例子。让我们看看代码。

默认构造函数看起来像这样:

func newNameResponder() actor.Receiver {
	return &nameResponder{name: "noname"}
}

要构建一个带有名称的新 Actor,您可以这样做:

func newCustomNameResponder(name string) actor.Producer {
	return func() actor.Receiver {
		return &nameResponder{name}
	}
}

然后您可以使用以下代码生成 Actor:

pid := engine.Spawn(newCustomNameResponder("anthony"), "name-responder")

使用自定义配置

e.Spawn(newFoo, "myactorname",
	actor.WithMaxRestarts(4),
		actor.WithInboxSize(1024 * 2),
		actor.WithId("bar"),
	)
)

这些选项应该很容易理解。您可以设置最大重启次数,这告诉引擎在发生崩溃时给定的 Actor 应该重启多少次,设置收件箱大小,这设置了收件箱在开始阻塞之前可以容纳多少未处理消息的限制。

作为无状态函数

没有状态的 Actor 可以作为函数生成,因为这样快速简单。

e.SpawnFunc(func(c *actor.Context) {
	switch msg := c.Message().(type) {
	case actor.Started:
		fmt.Println("started")
		_ = msg
	}
}, "foo")

远程 Actor

Actor 可以通过 Remote 包在网络上相互通信。 这与本地 Actor 的工作方式相同,但是"通过网络"。Hollywood 支持使用 protobuf 进行序列化。

配置

remote.New() 接受一个监听地址和一个 remote.Config 结构体。

您可以使用以下代码实例化一个新的远程:

tlsConfig := TlsConfig: &tls.Config{
	Certificates: []tls.Certificate{cert},
}

config := remote.NewConfig().WithTLS(tlsConfig)
remote := remote.New("0.0.0.0:2222", config)

engine, err := actor.NewEngine(actor.NewEngineConfig().WithRemote(remote))

查看 远程 Actor 示例聊天客户端和服务器 以获取更多信息。

事件流

在生产系统中,事情最终会出错。Actor 会崩溃,机器会失败,消息会最终进入死信队列。您可以构建能够以优雅和可预测的方式处理这些事件的软件,方法是使用事件流。

事件流是一个强大的抽象,允许您构建灵活和可插拔的系统,而无需依赖关系。

  1. 将任何 Actor 订阅到各种系统事件列表
  2. 向所有订阅者广播您的自定义事件

请注意,未被任何 Actor 处理的事件将被丢弃。您应该有一个 Actor 订阅事件流以接收事件。作为最低限度,您将需要处理 DeadLetterEvent。如果 Hollywood 无法将消息传递给 Actor,它将向事件流发送 DeadLetterEvent

任何满足 actor.LogEvent 接口的事件都将被记录到默认日志记录器中,其严重性级别、消息和事件属性由 actor.LogEventlog() 方法设置。

内部系统事件列表

  • actor.ActorInitializedEvent,一个 Actor 已初始化但尚未处理其 actor.Started 消息
  • actor.ActorStartedEvent,一个 Actor 已启动
  • actor.ActorStoppedEvent,一个 Actor 已停止
  • actor.DeadLetterEvent,一条消息未能传递给 Actor
  • actor.ActorRestartedEvent,一个 Actor 在崩溃/恐慌后重新启动
  • actor.RemoteUnreachableEvent,通过网络向不可达的远程发送消息
  • cluster.MemberJoinEvent,新成员加入集群
  • cluster.MemberLeaveEvent,成员离开集群
  • cluster.ActivationEvent,集群上激活了新的 Actor
  • cluster.DeactivationEvent,集群上停用了 Actor

事件流示例

有一个 事件流监控示例,展示了如何使用事件流。它包含两个 Actor,一个不稳定,每秒都会崩溃。另一个 Actor 订阅了事件流,并维护了几个不同事件的计数器,如崩溃等。

应用程序将运行几秒钟,然后毒化不稳定的 Actor。然后它会向监视器发送请求查询。由于 Actor 在引擎内部浮动,这是与它们交互的方式。main 将打印查询结果,然后应用程序退出。

定制引擎

我们使用函数选项模式。所有函数选项都在 actor 包中,其名称以 "EngineOpt" 开头。目前,唯一的选项是提供一个远程。这可以通过以下方式完成:

r := remote.New(remote.Config{ListenAddr: addr})
engine, err := actor.NewEngine(actor.EngineOptRemote(r))

addr 是一个格式为 "host:port" 的字符串。

中间件

您可以为您的接收者添加自定义中间件。这对于存储指标、在 actor.Startedactor.Stopped 时保存和加载接收者的数据很有用。

有关如何实现自定义中间件的示例,请查看 examples 文件夹中的中间件文件夹。

日志记录

Hollywood 有一些内置的日志记录功能。它将使用 log/slog 包中的默认日志记录器。您可以通过使用 slog.SetDefaultLogger() 设置默认日志记录器来配置您喜欢的日志记录器。这将允许您自定义日志级别、格式和输出。请参阅 slog 包以获取更多信息。

请注意,某些事件

项目侧边栏1项目侧边栏2
推荐项目
Project Cover

豆包MarsCode

豆包 MarsCode 是一款革命性的编程助手,通过AI技术提供代码补全、单测生成、代码解释和智能问答等功能,支持100+编程语言,与主流编辑器无缝集成,显著提升开发效率和代码质量。

Project Cover

AI写歌

Suno AI是一个革命性的AI音乐创作平台,能在短短30秒内帮助用户创作出一首完整的歌曲。无论是寻找创作灵感还是需要快速制作音乐,Suno AI都是音乐爱好者和专业人士的理想选择。

Project Cover

有言AI

有言平台提供一站式AIGC视频创作解决方案,通过智能技术简化视频制作流程。无论是企业宣传还是个人分享,有言都能帮助用户快速、轻松地制作出专业级别的视频内容。

Project Cover

Kimi

Kimi AI助手提供多语言对话支持,能够阅读和理解用户上传的文件内容,解析网页信息,并结合搜索结果为用户提供详尽的答案。无论是日常咨询还是专业问题,Kimi都能以友好、专业的方式提供帮助。

Project Cover

阿里绘蛙

绘蛙是阿里巴巴集团推出的革命性AI电商营销平台。利用尖端人工智能技术,为商家提供一键生成商品图和营销文案的服务,显著提升内容创作效率和营销效果。适用于淘宝、天猫等电商平台,让商品第一时间被种草。

Project Cover

吐司

探索Tensor.Art平台的独特AI模型,免费访问各种图像生成与AI训练工具,从Stable Diffusion等基础模型开始,轻松实现创新图像生成。体验前沿的AI技术,推动个人和企业的创新发展。

Project Cover

SubCat字幕猫

SubCat字幕猫APP是一款创新的视频播放器,它将改变您观看视频的方式!SubCat结合了先进的人工智能技术,为您提供即时视频字幕翻译,无论是本地视频还是网络流媒体,让您轻松享受各种语言的内容。

Project Cover

美间AI

美间AI创意设计平台,利用前沿AI技术,为设计师和营销人员提供一站式设计解决方案。从智能海报到3D效果图,再到文案生成,美间让创意设计更简单、更高效。

Project Cover

AIWritePaper论文写作

AIWritePaper论文写作是一站式AI论文写作辅助工具,简化了选题、文献检索至论文撰写的整个过程。通过简单设定,平台可快速生成高质量论文大纲和全文,配合图表、参考文献等一应俱全,同时提供开题报告和答辩PPT等增值服务,保障数据安全,有效提升写作效率和论文质量。

投诉举报邮箱: service@vectorlightyear.com
@2024 懂AI·鲁ICP备2024100362号-6·鲁公网安备37021002001498号