java - 在没有 DOS 漏洞的 tomcat 服务器中限制每个客户端的每秒事务数 (TPS)

标签 java tomcat servlets tomcat7 servlet-filters

我有一个网络服务,我需要限制客户端可以执行的交易数量。事务正在使用正确的参数访问 URL。每个客户端每秒可以执行的事务数量不同。客户端将根据 IP 地址或 URL 中的参数进行识别。

客户端可以执行的最大 TPS 将保存在数据库或任何其他可配置的方式中。我知道可以编写 servlet 过滤器来执行此操作。过滤器将计算每秒请求数并建立数据库连接以获得客户端的最大 TPS,并在达到 TPS 时拒绝请求,因为它会进一步减慢应用程序响应。但这在 DOS 攻击期间将无济于事。有没有更好的办法?

最佳答案

我不得不做同样的事情。我就是这样做的。

1) 我有一个用于跟踪 IP 请求的数据模型。它主要通过使用一些允许我添加新请求的数学来跟踪请求率,并且该 IP 的新请求率将很快被重新计算。让我们调用这个类 IpRequestRate

2) 对于发出请求的每个唯一 IP,IpRequestRate 实例被实例化。每个 IP 只需要一个实例。它们被放入 HashMap 中以进行快速检索。如果有新的 IP 进来,则会为其创建一个新的 IpRequestRate 实例。

3) 当请求进来时,如果 HashMap 中已经有 IpRequestRate 的实例,那么我会将新请求添加到该实例并获取新速率。如果速率高于某个阈值,则不会处理该请求。

4) 如果请求者不小心超出了该阈值,则速率将迅速降至阈值以下。但是,如果它是一个真正的 DOS,或者在我的情况下,尝试访问帐户的次数太多(由于黑客),那么他们的速率将需要更长的时间才能降至阈值以下;这就是我想要的。

5) 我不记得我是否有清除旧 IP 的清理线程,但这在某些时候是需要的。您可以使用 EhCache 作为您的 HashMap,这样它就可以自动为您执行此操作。

6) 它工作得非常好,我考虑将其开源。但它真的很简单,而且很容易重现。您只需要正确地进行数学运算即可。获得速率的数学很容易使其准确,但如果您希望它更快,则有点棘手,因此当将新请求添加到 IpRequestRate 时,CPU 不会花费太多时间来计算新速率

这是否回答了您的问题,或者您是否需要有关如何在您的服务器中设置过滤器的更多信息?

编辑:WRT DOS,在 DOS 攻击期间,我们希望浪费尽可能少的资源。如果所有可能的 DOS 检测都应该在负载平衡器或反向代理或网关或防火墙中完成。

如果我们想做每个 IP 的最大传输速率,它存储在数据库中,那么我将只缓存最大传输速率。这可以在不对请求进行数据库查找的情况下完成。我会改为将表加载到 HashMap 中。

1) 在应用程序开始时,比如在 init() 方法中,我会将表加载到将 IP 映射到 maxTransmissionRate 的 HashMap 中。

2) 当请求到来时,尝试从 HashMap 中获取 maxTransmissionRate。如果不存在,则使用默认的 maxTransmissionRate。

3) 在 init() 期间,启动一个 ScheduleExecutorService 以在某个期望的时间间隔更新 HashMap,以保持 HashMap 的新鲜度。这是 ScheduleExecutorService 的链接,它并不难。 http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html

4) 我们应该使用哪种 HashMap 实现?如果我们使用常规的 HashMap 那么当它被 ScheduledExecutorService 更新时我们就会遇到问题。我们可以使用同步的 HashMap,但这会锁定 HashMap 并在并发请求期间损害性能。所以我会选择 ConcurrentHashMap,它是为速度和多线程环境设计的。您可以放心地在单独的线程上安全地更新 ConcurrentHashMap。

如果您应用此技术,那么它仍然是防止 DOS 并支持每个客户端 maxTransmissionRate 的可行解决方案。

关于java - 在没有 DOS 漏洞的 tomcat 服务器中限制每个客户端的每秒事务数 (TPS),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31716128/

相关文章:

Java 日期月差

java - 什么时候在 Java 中使用 LinkedList 而不是 ArrayList?

java - 支柱2 : Change default messages on tags

java - 无需安装即可设置java版本的批处理文件

java - Mustache 在 NetBeans servlet 中抛出 "File not under root"异常

java - 调试tomcat崩溃

java - 如果 AppContext 初始化失败,正确终止 Spring Boot 和 Tomcat

java: 关于过滤器和 servlet 映射的问题

java - 无法解析 jakarta.persistence.EntityManagerFactory 类型。它是从所需的 .class 文件间接引用的

html - web.xml 使用/*后如何转发到html文件