GO中的软件架构:节流云设计模式的可扩展性和安全性

136 阅读2分钟

欢迎来到涵盖质量属性/非功能要求的系列的另一个帖子,这次我说的是一种提高可扩展性安全性云设计模式,叫做:节流

什么是节流?

Throttling 是一种在一段时间内限制资源访问的方式。定义如何限制这些资源取决于具体的用例,例如,我们可以按用户ID、按应用程序名称来限制,或者根本不做区分,对进入我们服务的所有请求进行节流。

Throttling example

Throttling 这是一种提高可扩展性的方法,因为它允许我们目前的服务在处理负载高峰时不会失败,同时弹性启动;也是一种提高安全性的方法,因为它允许我们检测来自同一来源的请求,这些请求可能导致使用过多的资源。

货币化也是使用Throttling 的另一个原因,但实际上这并不是一个质量属性/非功能需求,但它仍然是你可以考虑使用这种模式的另一个用例。

节流的工作原理是什么?

在最基本的形式下,Throttling ,包括跟踪一个具体用户访问一个资源的次数,我们定义一个用户的方式取决于我们的用户案例,它可以基于IP地址,头文件或甚至资源路径。

  1. 用户请求一个资源。
  2. 节流层决定是否允许它继续。
  3. 它允许请求继续,最后
  4. 将结果反馈给用户。

Throttling Implementation 1

Throttling 已经被触发的情况下,步骤被简化。

  1. 用户请求一个资源。
  2. 节流层确定它不允许继续,并将其阻断,最后
  3. 向用户返回一个错误信息。

Throttling Implementation 1

如何在Go中实现节流?

在Go中,有多个实现Throttling 的包,这里仅举几例。

我在这篇文章中使用的是didip/tollbooth包中实现的,它很容易使用,并且已经实现了一个可以添加到HTTP处理程序中的中间件,关于这个包的一个重要的事情是它不支持持久化存储,所以负载平衡器后面的不同HTTP服务器不能共享节流的细节。

使用它真的很简单。

lmt := tollbooth.NewLimiter(3, &limiter.ExpirableOptions{DefaultExpirationTTL: time.Second})

lmtmw := tollbooth.LimitHandler(lmt, r)

然后在你的HTTP服务器中使用它作为一个处理程序。

return &http.Server{
  Handler:           lmtmw, // Using handler throttling requests!
  Addr:              conf.Address,
  ReadTimeout:       1 * time.Second,
  ReadHeaderTimeout: 1 * time.Second,
  WriteTimeout:      1 * time.Second,
  IdleTimeout:       1 * time.Second,
}, nil

结论

Throttling 模式提高了可扩展性,因为它允许在非恶意的 "尖峰 "负载发生时停止处理请求,它也提高了恶意用户试图故意使我们的服务过载的情况下的安全性