Golang Web服务器和内存缓存的并发方法

时间:2016-10-28 08:50:07

标签: go

我不是编程的新手,但我对golang相对较新,但仍然没有完全习惯golang并发方法。

一般设置:

  • Web服务器(应该快速并行),所以我使用net / http
  • 我需要存储和检索大量文档。虽然检索比存储更频繁,但因素相当低。也许20。
  • 检索到目前为止,最重要的是最后存储的文档。如果需要,可以从磁盘/ DB中检索其余部分。
    • 解决方案:在最后添加项目的内存缓存中。
    • 注意:在检索时,我不在乎最后3秒。意思是,如果在时间(A),我要求提供最后添加项目的完整列表,则在最后3秒内添加的项目可能(部分或完全)丢失。但是当在时间再次询问(A + 3s)时,所有这些项目都应该在列表中。

我的问题与如何实现内存缓存有关。

天真的方法#1(RWLock)

  • 在内存中有大量项目。
  • 使用RW锁定保护

此方法存在问题:我成功序列化了Web服务器:)

好的,请忘记这种方法。

方法#2:拆分

  • 在内存中有X个列表(每个都有RWLock)
  • 在http处理程序启动时获取一个随机数并选择其中一个X列表,仅在该列表上工作
  • 另一个收集程序例程每2.5秒开始收集和组合列表

这样更好,理论上我甚至可以在服务器之间拆分工作。

但是,例如基于golang旅游代码:

func main() {
    http.HandleFunc("/view/", makeHandler(viewHandler))
    http.HandleFunc("/edit/", makeHandler(editHandler))
    http.HandleFunc("/save/", makeHandler(saveHandler))
    http.ListenAndServe(":8080", nil)
}

如何在没有序列化的情况下在http处理程序中传递/获取新的随机数?

  • 它不需要加密安全。我只是想用它来挑选一个X列表。
  • 我知道有一个全局随机生成器,但内部使用互斥,所以回到1。
  • 我可以要求客户端(JavaScript)提供随机数作为get参数。但这听起来很危险(DOS)?或者这样可以吗?
  • 我可能不知道go服务器中的用户IP地址(反向代理设置)。

并且:一般来说这是一个好方法吗?有更好的方法吗?现在我将自己限制在X,这不会扩展。如果我希望X在运行时更改,我怎么能告诉处理程序有关该更改(不再重新编译)?

1 个答案:

答案 0 :(得分:1)

您不能使用 RWLock 来真正序列化您的服务器。使用RLock()并行读取文档。

检查thread-safe concurrent map for go库。它同时使用互斥和分片技术。我还将CQRS添加到数据库级别,它可以轻松处理100K并发请求/秒。