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

Newtonsoft.Json在Azure Web App Service中序列化性能异常缓慢问题求助

解决Azure Web App中Newtonsoft.Json大对象序列化性能骤降的问题

针对你遇到的本地与Azure环境序列化性能差异巨大的问题,我整理了几个优先级较高的排查和优化方向,你可以逐一尝试:

1. 优化自定义JsonNaNConverter的性能

你的自定义转换器会处理对象中所有double/float类型的值,当对象规模较大时,转换器的性能开销会被放大。原代码中的类型判断逻辑可以简化——因为CanConvert已经确保了输入类型,无需多次使用as进行可空类型转换:

public class JsonNaNConverter : JsonConverter {
    public override bool CanRead => false;
    public override bool CanWrite => true;

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
        double val = value switch {
            float f => f,
            double d => d,
            _ => (double)value // 针对double?的情况,CanConvert已确保类型安全
        };

        if (double.IsNaN(val) || double.IsInfinity(val)) {
            writer.WriteNull();
            return;
        }
        writer.WriteValue(val);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
        throw new NotImplementedException();
    }

    public override bool CanConvert(Type objectType) {
        return objectType == typeof(double) || objectType == typeof(double?) || objectType == typeof(float);
    }
}

这种写法减少了不必要的类型转换和可空类型判断,能有效降低单值处理的开销。

2. 升级Newtonsoft.Json版本

你当前使用的12.0.1版本是2018年的旧版本,后续的13.x系列针对大对象序列化、内存分配做了大量性能优化。建议升级到最新的稳定版(目前是13.0.3),很多用户反馈升级后大对象序列化性能有显著提升。

3. 检查Azure App Service的运行平台位数

默认情况下,部分Azure App Service计划可能会以32位模式运行。对于处理3MB级别的JSON字符串,32位进程的内存压力更大,GC暂停时间会更长。你可以在Azure Portal中:

  • 进入你的App Service → 配置 → 常规设置
  • 将“平台”从“32位”切换为“64位”,保存后重启应用

4. 避免直接生成大字符串,改用流式序列化

直接调用JsonConvert.SerializeObject会在内存中生成完整的3MB字符串,这会触发多次GC,在Azure环境中可能因为内存碎片导致性能下降。改用流式序列化的方式可以减少内存分配:

#if WRITE_TIMER_LOGS
var swSerializeTime = new System.Diagnostics.Stopwatch();
swSerializeTime.Start();
#endif

using (var stringWriter = new StringWriter())
using (var jsonWriter = new JsonTextWriter(stringWriter))
{
    var serializer = JsonSerializer.Create(serializerSettings);
    serializer.Serialize(jsonWriter, responses);
    jsonString = stringWriter.ToString();
}

#if WRITE_TIMER_LOGS
swSerializeTime.Stop();
#endif

如果你的场景是直接输出到HTTP响应,还可以直接序列化到Response.OutputStream,完全避免生成大字符串。

5. 排查Azure环境的资源瓶颈

虽然你使用的是P2V2计划,但仍需确认是否存在资源限制:

  • 在Azure Portal的App Service → 指标中,查看CPU使用率、内存使用率,如果CPU持续接近100%,可能存在资源节流
  • 启用Application Insights的性能分析,查看序列化过程中的GC暂停时间、JIT编译耗时,定位具体的性能瓶颈

6. 确认编译和部署模式

确保你的应用是用Release模式编译的,并且部署到Azure时没有启用调试模式(Web.config中的debug属性应为false)。调试模式会禁用JIT优化,导致性能大幅下降。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 19:54:07