为了账号安全,请及时绑定邮箱和手机立即绑定

golang中的生产者消费者-并发与并行?

golang中的生产者消费者-并发与并行?

Go
梦里花落0921 2021-11-29 16:07:09
我正在研究纯粹使用 Golang 的后端架构。我有一个 API,用于将文件上传到 golang 服务器,然后我将文件传输到云存储(从 golang 服务器本身)。现在,我希望两个传输都是独立的,这样最终用户就不必在上传文件后等待响应。End User -> Golang Server ->[Concurrency/Parallelism] -> Cloud Storage现在,我想到了两种方法:用户完成上传并将文件传输到云后,立即创建一个 goroutine。将文件处理程序插入队列,不同的进程将读取此队列并将文件传输到云存储(多生产者 - 单消费者模型)。我找到了使用 goroutine 和 channels 执行此操作的示例,但我认为这将创建与上传一样多的 goroutine。我想使用第二个选项,但无法理解如何在 golang 中进行操作?另外,请建议我是否使用了错误的方法,并且还有其他一些有效的方法可以做到这一点。更新有关要求和约束的详细信息:1. 我使用 AWS S3 作为云存储。如果在某个时候,从 Go 服务器到 Amazon S3 的上传失败,文件处理程序应该保持原样以记录失败的上传。(我没有优先考虑这一点,我可能会根据客户的反馈进行更改)2.上传到 Amazon S3 成功完成后,文件将立即从 Go 服务器中删除,以避免重复上传。此外,如果文件以相同的名称上传,它将在 Amazon S3 中被替换。3.正如评论中所指出的,我可以使用频道作为队列。是否可以使用 Go 的 Channels 和 goroutines 来设计上述架构?
查看完整描述

2 回答

?
侃侃尔雅

TA贡献1801条经验 获得超15个赞

上传文件的用户可以容忍错误,然后重试。但是当上传的文件只存在于它上传到的机器上时存在危险,并且在上传到云存储之前出现问题。在这种情况下,文件将丢失,这对用户来说将是一个无赖。

这是通过良好的架构解决的。这是一个先进先出的队列模式

这种模式的一个最受欢迎的 Go 实现是go-workers,它可能由Redis数据库支持。

假设在任何给定时间有n个服务器运行您的服务。假设您的后端代码编译了两个单独的二进制文件,一个服务器二进制文件和一个工作二进制文件。

理想情况下,接受文件上传的机器都会挂载一个共享的网络文件系统,这样:

  1. 用户上传文件到服务器

    一种。服务器将一条记录添加到工作队列中,该记录包含来自 Redis 存储的唯一 ID。

    湾 这个唯一的 ID 用于创建文件名,文件直接从用户上传到 NFS 服务器上的临时存储。请注意,该文件永远不会驻留在运行服务器的机器的存储中。

  2. 文件由工人上传到云存储

    一种。worker从具有唯一 ID 的工作队列中取出下一个待办事项记录

    湾 使用唯一 ID 在 NFS 服务器上查找文件,工作人员将文件上传到云存储

    C。成功后,worker更新工作队列中的记录以反映成功

    d. worker删除 NFS 服务器上的文件

通过将服务器流量和工作队列大小作为两个独立的指标进行监控,可以确定应该分别运行服务器/工作器服务的服务器数量。


查看完整回答
反对 回复 2021-11-29
?
米脂

TA贡献1836条经验 获得超3个赞

Marcio Castilho 写了一篇关于类似问题的好文章。它可以在使用 golang 处理每分钟一百万个请求中找到

他展示了他所犯的错误以及他为纠正这些错误所采取的步骤。一般学习通道、goroutines 和并发的使用的好资源。

charneykaye提到的go-workers也是很好的来源。


查看完整回答
反对 回复 2021-11-29
  • 2 回答
  • 0 关注
  • 127 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信