You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django生产环境API响应时快时慢问题排查求助

问题描述

我有一个以提供API为核心的Django应用,包含三个URL:

  • api/:从数据库渲染数据
  • test/:仅返回HttpResponse("Done")的测试页
  • insert/:向数据库插入数据

该应用在开发环境响应速度正常(255ms),但在生产环境中有时快(260ms),多数时候极慢(30-40秒),甚至加载仅显示单个单词的test页面也是如此。请问该问题是与代码相关还是托管服务商相关?

补充信息:

  • 前端使用React,路由为mainsite.com/home
  • 后端使用子域名api.mainsite.com/api或api.mainsite.com/insert

相关代码

抽象模型类(Equipment和Machine模型与此类似)

class Device(models.Model):
    class Meta:
        abstract = True

    gas1 = models.FloatField()
    gas2= models.FloatField()
    gas3= models.FloatField()
    gas4= models.FloatField()
    gas5= models.FloatField()
    gas6= models.FloatField()

    humidity = models.FloatField()
    temperature = models.FloatField()

    created_datetime = models.DateTimeField(auto_now_add=True, null=True)
    display_datetime = models.DateTimeField(null=True, db_index=True)

def save(self, *args, **kwargs):
    super(Device, self).save(*args, **kwargs)

    time = f"{str(self.created_datetime.date())}{(format(self.created_datetime.hour,'02d'))}:{(format(self.created_datetime.minute // 5 * 5, '02d'))}:00"
    formatt = "%Y-%m-%d%H:%M:%S"
    self.display_datetime = datetime.datetime.strptime(time, formatt)
    super(Device, self).save(*args, **kwargs)

序列化器(Equipment和Machine序列化器与此类似)

class Deviceserializer(serializers.ModelSerializer):
    class Meta:
        model = Device
        fields = [
            "id",
            "name",
            "room",
            "deviceName",
            "total gas",
            "gas1",
            "gas2",
            "gas3",
            "gas4",
            "gas5",
            "gas6",
            "humidity",
            "temperature",
            "method1",
            "method2",
            "method3",
            "method4",
            "method5",
            "method6",
            "slug",
            "display_datetime",
        ]

视图

@api_view(["GET"])
def getData(request):
    device_101 = device_101.objects.last()
    device_102 = device_102.objects.last()
    device_103 = device_103.objects.last()
    device_104 = device_104.objects.last()
    device_105 = device_105.objects.last()
    device_106 = device_106.objects.last()
    device_108 = device_108.objects.last()
    device_109 = device_109.objects.last()
    device_110 = device_110.objects.last()
    device_111 = device_111.objects.last()
    device_112 = device_112.objects.last()
    device_113 = device_113.objects.last()
    device_114 = device_114.objects.last()
    device_115 = device_115.objects.last()
    device_116 = device_116.objects.last()
    device_124 = device_124.objects.last()
    device_125 = device_125.objects.last()
    device_126 = device_126.objects.last()
    device_127 = device_127.objects.last()
    device_128 = device_128.objects.last()
    device_129 = device_129.objects.last()
    device_130 = device_130.objects.last()

    list_device = [
        device_101,
        device_102,
        device_103,
        device_104,
        device_105,
        device_106,
        device_108,
        device_109,
        device_110,
        device_111,
        device_112,
        device_113,
        device_114,
        device_115,
        device_116,
        device_124,
        device_125,
        device_126,
        device_127,
        device_128,
        device_129,
        device_130,
    ]

    serialzer_device = Deviceserializer(list_device, many=True)
    serializer_machine = machineserializer(list_machine, many=True)
    serializer_equipment = equipmentserializer(list_equipment, many=True)

    return Response(
        {
            "device": serialzer_device.data,
            "equipment": serializer_equipment.data,
            "machine": serializer_machine.data,
        }
    )

回答

结论:优先排查托管服务商/基础设施问题,同时优化代码中的低效点

一、为什么怀疑托管服务商/基础设施问题?

你的test/页面完全不涉及数据库或复杂逻辑,只是返回简单字符串,但生产环境依然会出现极慢的情况。开发环境响应稳定,生产环境波动极大(从260ms到30-40秒),这种无规律的响应延迟通常和代码本身无关,更可能是以下基础设施问题:

  • 服务器资源不足(CPU/内存过载,导致请求排队)
  • 网络链路问题(子域名解析延迟、跨域请求的网络波动、反向代理配置异常)
  • 数据库连接池耗尽(即使test页面不直接查库,如果数据库连接被其他请求占满,可能导致进程阻塞)
  • 托管平台的自动扩缩容机制触发(比如流量突增时实例启动/切换的延迟)

二、代码中存在的低效点(虽不是主因,但会放大问题)

虽然代码问题不是导致test页面变慢的原因,但会加重生产环境的负载,间接加剧延迟:

  1. 模型save方法的重复调用:
    你在save方法中调用了两次super().save(),第一次保存生成created_datetime,第二次更新display_datetime,这会触发两次数据库写入操作,增加数据库负载。可以修改为仅在首次创建时计算并保存:

    def save(self, *args, **kwargs):
        if not self.pk:  # 仅新建对象时执行
            now = datetime.datetime.now()
            rounded_minute = (now.minute // 5) * 5
            self.display_datetime = now.replace(minute=rounded_minute, second=0, microsecond=0)
        super().save(*args, **kwargs)
    

    这样只需一次数据库写入,减少不必要的开销。

  2. 视图中多次查询objects.last():
    视图中对每个设备模型单独调用objects.last(),发起20+次独立数据库查询,若没有合适索引会触发全表扫描。可以优化为:

    • 确保created_datetime字段添加索引(created_datetime = models.DateTimeField(auto_now_add=True, null=True, db_index=True))
    • 若所有设备都是Device子类,通过批量查询获取最新数据:
      # 假设子类有device_type字段区分设备
      latest_device_ids = Device.objects.values('device_type').annotate(last_id=Max('id')).values_list('last_id', flat=True)
      list_device = Device.objects.filter(id__in=latest_device_ids)
      

    把20+次查询减少到1-2次,大幅降低数据库查询时间。

三、排查步骤建议

  1. 先验证基础设施问题:

    • 在生产环境直接访问服务器IP的test页面,跳过域名解析,看是否依然延迟
    • 查看服务器监控:CPU使用率、内存占用、数据库连接数、请求队列长度
    • 检查托管平台的日志,是否有超时、资源不足的告警
    • 在生产服务器上执行简单SQL查询,测试数据库连接速度
  2. 再优化代码:
    先解决基础设施问题,再处理代码低效点,避免因次要问题浪费排查时间。


内容的提问来源于stack exchange,提问作者webdeveloper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 03:15:43