Skip to content

JustGopher/CloudBook

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

限流

保护系统

在功能完成之后,现在要进一步考虑保护我们的系统。

一般来说,你要考虑两方面的事情:

  • 正常用户会不会搞崩你的系统?
  • 如果有人攻击你的系统,你能撑住吗?

对于中小型公司来说,第一条不会是问题,对于大公司来说,就要两条都考虑

现在我们的系统最明显的漏洞就是:

  • 任何人都可以注册
  • 任何人都可以登录

用脚本来刷,很容易构造出每秒几千几万的请求

也就是说,万一有一个人,用 shell 脚本拼命给你发注册请求、登录请求,系统负载就会很高,而且这两个请求都会查询数据库,也就是说数据库负载也很高

这个时候,我们可以考虑,能不能限制住每个人发的请求数量?又或者,限制住系统处理的请求数量?

这就是限流

限流是最常见的保护系统的办法。限流有很多算法,但是都大同小异,后面在微服务架构部分会进一步讲解。

这里我们使用限流,限制每一个用户,每秒最多发送固定数量的请求。

所以问题来了:

  • 我怎么认定谁是谁?尤其是在登录和注册这个接口里,都还没登录成功,我都不知道他是谁。

  • 我怎么确定我限流的这个阈值应该是多少?每秒 100 还是每秒 200?

限流对象

第一个问题的答案是:用 IP。也就是说我们的限流针对的是 IP。

IP 虽然并不能实际意义上代表一个人,但这已经是我们比较好的选择了。

更好的选择是用 MAC 地址或者设备标识符之类的,比如说 CPU 序列号,但是在 Web 端很少用。(不容易拿到)

APP 端就可以考虑用设备序列号。

当然,在使用 IP 的情况下,我们可能会误把不同的人看成是同一个人。但是只要我们限制的阈值不是很小,就不会有问题。

限流阈值

限流阈值应该是多少?

理论上来说,这应该是通过压测来得到的(面试回答这个)。比如说你压测整个系统,发现最多只能撑住每秒 1000 个请求,那么阈值就是 1000。

而我们是针对个人,搞不了压测。所以可以凭借经验来设置,比如说我们正常人手速,一秒钟撑死一个请求,那么就算我们考虑到共享 IP 之类的问题,给个每秒 100 也已经足够了。

被限流的请求怎么办?

如果我每秒处理 100 个请求,那第 101 个请求过来怎么办?

显然,只能拒绝了,也就是返回错误。

这个错误,不同公司有不同的规范。如果你自己决策的话,可以返回什么服务器繁忙之类的信息。

使用 Gin 的限流插件

Gin 里面有很多限流插件,从功能和非功能特性上,它们都没有什么区别。

但是你们要小心并发问题。

滑动窗口算法,同时收到多个请求,可能超出窗口限制

为啥用 Redis 限流?

为什么要基于 Redis 来实现呢?

因为你要考虑到整个单体应用部署多个实例,用户的请求经过负载均衡之类的东西之后,就不一定落到同一个机器上了。

因此需要 Redis 来计数。

安全问题

现在的问题是,不管是用 JWT 还是 Session,一旦被攻击者拿到关键的 JWT 或者 ssid,攻击者就能假冒你。

HTTPS 可以有效阻止攻击者拿到你的 JWT 或者 ssid。

但是如果你电脑中了病毒,那 HTTPS 就无能为力。

怎么解决呢?

所以我们就要想,在用户登录校验过程中,我得进一步判断,用这个 JWT/ssid 的人是不是原本登录的那个人。

目前做得好的都是使用二次验证,也就是给你发邮件、发短信等。但是也有一些比较初步但也好用的手段,那就是用登录的辅助信息来判断。

登录的其他信息

在你登录的时候,记录一下你当时登录的一些额外信息。比如说:

  • 你使用的浏览器,对应到 HTTP 的 User-Agent 头部。
  • 你的硬件信息——手机 APP 比较多见。

问题:能不能用 IP?

在登录校验的时候,比较一下你当次请求的这些辅助信息和上一次的信息,不一样就认为有风险。

不能,换个网络或地点 IP 就不同了

利用 User-Agent 增强安全性

右图则是在登录校验的时候比较了 User-Agent 这个参数。

为此你需要改造两个地方:

  • Login 接口,在 JWT token 里面带上 User-Agent信息。
  • JWT 登录校验中间件,在里面比较 User-Agent。

保护公司前端接口

检查公司的前端接口,而后加入限流功能。

  • 可以考虑整个集群限流

  • 针对核心业务的接口限流

  • 针对不需要登录就可以访问的接口限流

  • 为限流添加对应的监控和告警

面试要点

  • 刷新 Session 过期时间的几种可行的办法,你要能够深入分析不同做法的优缺点。注意,面试不是实践,不能说我记住最佳的就行,而是你要尽可能”水“时间,展示自己博闻广识。
  • 增强登录的安全性:
    • 怎么保护 Session id?主要还是要启用 HTTPS 协议,把 Cookie 的 Secure 和 HttpOnly 都设置为true。
    • 怎么做到在 Session id 或者 JWT token 泄露之后保护住用户?要在登录的时候记录一下登录的附加信息,例如 User-Agent,在登录校验的时候一并校验。
  • 如何保护 Web 服务? 针对 IP 限流、整个集群限流。后续你还会接触到更加多的保护措施。
  • 注意:这一部分的内容在你们面试初级工程师的时候,是属于比较有技术含量的点了,你在面试前一定要试着按照自己的说话习惯,整理好对应的答案,写出来多读几遍。

About

小云书

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published