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

使用Kryo 5.2.0偶发找不到类序列化异常,重启Tomcat临时解决如何处理?

你碰到的异常核心是Kryo实例被多线程并发访问导致内部读取字节流错位,错误的把业务字段值Ethiopian Airlines当成了需要加载的类名触发了类找不到异常,偶发、重启后暂时恢复的特征完全符合多线程资源竞争的表现。

根因定位

  • 最核心的问题是Kryo池的线程安全参数配置错误:Kryo实例本身是线程不安全的,不支持多线程同时操作,你当前池构造的第一个参数KRYO_INSTANCE_THREAD_SAFE如果设置为true,池会允许同一个Kryo实例被多个线程并发调用,导致内部的字节读取指针、状态变量被篡改,读取类名的时候读取到了后续的业务字符串内容,触发异常。
  • 次要潜在问题:你注释了类加载器配置行,Tomcat的Webapp类加载器会在运行时发生上下文切换,Kryo默认使用的类加载器可能无法正确加载业务类。
  • 其他可能问题:Kryo实例使用完未正确归还、序列化和反序列化的Kryo配置不一致也会触发字节流解析错位。

解决方案

  1. 修正Kryo池的线程安全配置,将构造函数第一个参数强制设为false,同时打开类加载器配置:
// 第一个参数表示池内对象是否线程安全,Kryo线程不安全必须设为false
private static final Pool<Kryo> kryoPool = new Pool<Kryo>(false, true, KRYO_POOL_MAXIMUM_CAPACITY) {
        protected Kryo create() {
            final Kryo kryo = new Kryo();
            // 打开类加载器配置,明确指定Web应用的类加载器
            kryo.setClassLoader(Thread.currentThread().getContextClassLoader());
            kryo.setRegistrationRequired(false);
            // 生产环境建议打开该配置,方便排查未注册类的问题
            kryo.setWarnUnregisteredClasses(true);
            kryo.setInstantiatorStrategy(new DefaultInstantiatorStrategy(new StdInstantiatorStrategy()));
            try {
                kryo.register(Class.forName("java.util.Collections$SynchronizedMap"), new SynchronizedCollectionsSerializer());
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            SynchronizedCollectionsSerializer.registerSerializers(kryo);

            return kryo;
        }
    };
  1. 检查Kryo工具类的使用逻辑,确保所有场景下都是borrowObject获取实例,使用完成后在finally块中调用returnObject归还实例,禁止归还后继续操作Kryo实例。
  2. 确认序列化和反序列化的Kryo配置完全一致,包括序列化器、类注册策略、参数配置等,避免两端配置不一致导致的字节流解析错误。
  3. 如果业务允许,建议开启setRegistrationRequired(true),提前注册所有需要序列化的类,既可以提升序列化性能,也能彻底避免类名解析错误的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 04:45:03