我对编程并不陌生,但对golang还是比较陌生,但仍未完全习惯于golang并发方法。

常规设置:

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

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

天真的方法#1(RWLock)

  • 内存中有大量项目。
  • 用RW锁保护它

这种方法的问题:我成功地序列化了Web服务器:)

好的,请忘记这种方法。

方法2:分解内容

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

这样更好,从理论上讲,我什至可以在服务器之间分配工作。

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

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

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

并且:通常,这是一个好方法吗?有没有更好的办法?现在我将自己限制为X,这无法扩展。如果我希望X在运行时进行更改,我该如何告知处理程序该更改(不再次变为串行)?

您实际上并没有使用RWLock序列化服务器。 使用RLock()并行读取文档。

检查用于Go库的线程安全并发映射。 它同时使用互斥和分片技术。 我还将CQRS添加到数据库级别,它可以轻松地处理每秒10万个并发请求。