# coding=utf-8 """ 应用 API 限流模型 存储应用的 API 调用限流配置 """ import uuid_utils.compat as uuid from django.db import models from common.mixins.app_model_mixin import AppModelMixin class RateLimitType(models.TextChoices): """限流类型""" QPS = 'QPS', '每秒请求数' QPM = 'QPM', '每分钟请求数' QPH = 'QPH', '每小时请求数' QPD = 'QPD', '每日请求数' class RateLimit(AppModelMixin): """应用 API 限流配置""" id = models.UUIDField(primary_key=True, max_length=128, default=uuid.uuid7, editable=False, verbose_name="主键id") application = models.OneToOneField( 'application.Application', on_delete=models.CASCADE, db_constraint=False, verbose_name="应用", db_index=True ) is_enabled = models.BooleanField(verbose_name="是否启用限流", default=False) rate_type = models.CharField( max_length=10, choices=RateLimitType.choices, default=RateLimitType.QPM, verbose_name="限流类型" ) max_requests = models.IntegerField(verbose_name="最大请求数", default=60) burst_size = models.IntegerField(verbose_name="突发容量", default=10) window_seconds = models.IntegerField(verbose_name="时间窗口(秒)", default=60) class Meta: db_table = "application_rate_limit" def __str__(self): return f"RateLimit({self.application_id}) - {self.rate_type}: {self.max_requests}" class RateLimitLog(AppModelMixin): """限流日志""" id = models.UUIDField(primary_key=True, max_length=128, default=uuid.uuid7, editable=False, verbose_name="主键id") application = models.ForeignKey( 'application.Application', on_delete=models.CASCADE, db_constraint=False, verbose_name="应用", db_index=True ) client_ip = models.CharField(max_length=45, verbose_name="客户端IP", default="") request_path = models.CharField(max_length=512, verbose_name="请求路径", default="") is_limited = models.BooleanField(verbose_name="是否被限流", default=False) request_time = models.DateTimeField(verbose_name="请求时间", auto_now_add=True) class Meta: db_table = "application_rate_limit_log" ordering = ['-request_time']