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

时间:2015-12-13 16:14:30

标签: go concurrency parallel-processing producer-consumer

我正在开发纯粹在Golang中的后端架构。我有一个API,用于将文件上传到golang服务器,然后我将文件传输到云存储(从golang服务器本身)。现在,我希望两个传输都是独立的,这样最终用户不必在上传文件后等待响应。

source 'http://github.com/MyPrivateRepo/Specs.git'

现在,我想到了两种方式:

  1. 用户完成上传后立即创建goroutine并将文件传输到云端。
  2. 将文件处理程序插入队列,另一个进程将读取此队列并将文件传输到云存储(多个生产者 - 单个消费者模型)。
  3. 我找到了使用goroutine和channel执行此操作的示例,但我认为这会创建尽可能多的goroutine以及上传。我想使用第二个选项,但无法理解如何在golang中进行操作?

    另外,如果我使用了错误的方法并且还有其他有效的方法,请建议。

    更新

    有关要求和约束的详细信息:
    1.我使用AWS S3作为云存储。如果在某些时候,从Go服务器上传到Amazon S3失败,应该保留文件处理程序以保留上载失败的记录。(我没有优先考虑,我可能会根据客户反馈更改此内容)
    2.上传成功完成到Amazon S3后,文件将从Go服务器中删除,以避免重复上传。此外,如果文件上传的名称相同,则会在Amazon S3上替换 3.正如评论中所指出的,我可以使用频道作为队列。是否可以使用Go的频道和goroutines设计上述架构?

2 个答案:

答案 0 :(得分:2)

上传文件的用户可以容忍错误,请重试。但是,如果上传的文件仅存在于上载的计算机上,并且在上传到云存储之前出现问题,则存在危险。在这种情况下,文件将丢失,对用户来说将是一个无赖。

这是通过良好的架构解决的。它是first-in, first out queue pattern

此模式的最喜欢的Go实现是go-workers,可能由Redis数据库支持。

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

理想情况下,接受文件上传的计算机都会挂载共享的Network File System,以便:

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

    一个。 服务器会在工作队列中添加一条记录,其中包含Redis存储中的唯一ID。

    湾此唯一ID用于创建文件名,文件通过管道直接从用户上载到NFS服务器上的临时存储。请注意,该文件永远不会驻留在运行服务器的计算机的存储上。

  2. 文件由工作人员

    上传到云端存储

    一个。 worker 从工作队列中获取下一个待办事项记录,该记录具有唯一ID

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

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

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

  3. 通过将服务器流量和工作队列大小监视为两个单独的度量标准,可以确定应分别运行服务器/工作服务的服务器数量。

答案 1 :(得分:2)

Marcio Castilho撰写了一篇关于类似问题的好文章。它可以在Handling one million requests per minutes with golang找到。

他展示了他所犯的错误以及他采取的纠正错误的步骤。一般来说,学习使用频道,goroutine和并发的好资源。

go-workers提到的

charneykaye也是很好的来源。