hollywood

hollywood

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

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

HollywoodActor模型Go语言并发编程分布式系统Github开源项目

Go 报告卡 示例工作流程 <a href="https://discord.gg/gdwXmXYNTh"> <img src="https://yellow-cdn.veclightyear.com/2b54e442/299bc037-9307-49c3-972f-a6d459e66471.png?style=shield" alt="Discord 徽章"/> </a>

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 包以获取更多信息。

请注意,某些事件

编辑推荐精选

音述AI

音述AI

全球首个AI音乐社区

音述AI是全球首个AI音乐社区,致力让每个人都能用音乐表达自我。音述AI提供零门槛AI创作工具,独创GETI法则帮助用户精准定义音乐风格,AI润色功能支持自动优化作品质感。音述AI支持交流讨论、二次创作与价值变现。针对中文用户的语言习惯与文化背景进行专门优化,支持国风融合、C-pop等本土音乐标签,让技术更好地承载人文表达。

QoderWork

QoderWork

阿里Qoder团队推出的桌面端AI智能体

QoderWork 是阿里推出的本地优先桌面 AI 智能体,适配 macOS14+/Windows10+,以自然语言交互实现文件管理、数据分析、AI 视觉生成、浏览器自动化等办公任务,自主拆解执行复杂工作流,数据本地运行零上传,技能市场可无限扩展,是高效的 Agentic 生产力办公助手。

lynote.ai

lynote.ai

一站式搞定所有学习需求

不再被海量信息淹没,开始真正理解知识。Lynote 可摘要 YouTube 视频、PDF、文章等内容。即时创建笔记,检测 AI 内容并下载资料,将您的学习效率提升 10 倍。

AniShort

AniShort

为AI短剧协作而生

专为AI短剧协作而生的AniShort正式发布,深度重构AI短剧全流程生产模式,整合创意策划、制作执行、实时协作、在线审片、资产复用等全链路功能,独创无限画布、双轨并行工业化工作流与Ani智能体助手,集成多款主流AI大模型,破解素材零散、版本混乱、沟通低效等行业痛点,助力3人团队效率提升800%,打造标准化、可追溯的AI短剧量产体系,是AI短剧团队协同创作、提升制作效率的核心工具。

seedancetwo2.0

seedancetwo2.0

能听懂你表达的视频模型

Seedance two是基于seedance2.0的中国大模型,支持图像、视频、音频、文本四种模态输入,表达方式更丰富,生成也更可控。

nano-banana纳米香蕉中文站

nano-banana纳米香蕉中文站

国内直接访问,限时3折

输入简单文字,生成想要的图片,纳米香蕉中文站基于 Google 模型的 AI 图片生成网站,支持文字生图、图生图。官网价格限时3折活动

扣子-AI办公

扣子-AI办公

职场AI,就用扣子

AI办公助手,复杂任务高效处理。办公效率低?扣子空间AI助手支持播客生成、PPT制作、网页开发及报告写作,覆盖科研、商业、舆情等领域的专家Agent 7x24小时响应,生活工作无缝切换,提升50%效率!

堆友

堆友

多风格AI绘画神器

堆友平台由阿里巴巴设计团队创建,作为一款AI驱动的设计工具,专为设计师提供一站式增长服务。功能覆盖海量3D素材、AI绘画、实时渲染以及专业抠图,显著提升设计品质和效率。平台不仅提供工具,还是一个促进创意交流和个人发展的空间,界面友好,适合所有级别的设计师和创意工作者。

图像生成热门AI工具AI图像AI反应堆AI工具箱AI绘画GOAI艺术字堆友相机
码上飞

码上飞

零代码AI应用开发平台

零代码AI应用开发平台,用户只需一句话简单描述需求,AI能自动生成小程序、APP或H5网页应用,无需编写代码。

Vora

Vora

免费创建高清无水印Sora视频

Vora是一个免费创建高清无水印Sora视频的AI工具

下拉加载更多