rate_limit.py 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. # coding=utf-8
  2. """
  3. 应用 API 限流模型
  4. 存储应用的 API 调用限流配置
  5. """
  6. import uuid_utils.compat as uuid
  7. from django.db import models
  8. from common.mixins.app_model_mixin import AppModelMixin
  9. class RateLimitType(models.TextChoices):
  10. """限流类型"""
  11. QPS = 'QPS', '每秒请求数'
  12. QPM = 'QPM', '每分钟请求数'
  13. QPH = 'QPH', '每小时请求数'
  14. QPD = 'QPD', '每日请求数'
  15. class RateLimit(AppModelMixin):
  16. """应用 API 限流配置"""
  17. id = models.UUIDField(primary_key=True, max_length=128, default=uuid.uuid7, editable=False, verbose_name="主键id")
  18. application = models.OneToOneField(
  19. 'application.Application',
  20. on_delete=models.CASCADE,
  21. db_constraint=False,
  22. verbose_name="应用",
  23. db_index=True
  24. )
  25. is_enabled = models.BooleanField(verbose_name="是否启用限流", default=False)
  26. rate_type = models.CharField(
  27. max_length=10,
  28. choices=RateLimitType.choices,
  29. default=RateLimitType.QPM,
  30. verbose_name="限流类型"
  31. )
  32. max_requests = models.IntegerField(verbose_name="最大请求数", default=60)
  33. burst_size = models.IntegerField(verbose_name="突发容量", default=10)
  34. window_seconds = models.IntegerField(verbose_name="时间窗口(秒)", default=60)
  35. class Meta:
  36. db_table = "application_rate_limit"
  37. def __str__(self):
  38. return f"RateLimit({self.application_id}) - {self.rate_type}: {self.max_requests}"
  39. class RateLimitLog(AppModelMixin):
  40. """限流日志"""
  41. id = models.UUIDField(primary_key=True, max_length=128, default=uuid.uuid7, editable=False, verbose_name="主键id")
  42. application = models.ForeignKey(
  43. 'application.Application',
  44. on_delete=models.CASCADE,
  45. db_constraint=False,
  46. verbose_name="应用",
  47. db_index=True
  48. )
  49. client_ip = models.CharField(max_length=45, verbose_name="客户端IP", default="")
  50. request_path = models.CharField(max_length=512, verbose_name="请求路径", default="")
  51. is_limited = models.BooleanField(verbose_name="是否被限流", default=False)
  52. request_time = models.DateTimeField(verbose_name="请求时间", auto_now_add=True)
  53. class Meta:
  54. db_table = "application_rate_limit_log"
  55. ordering = ['-request_time']