• 记一坑


    同事新一项目,大概率启动出现

    ConcurrentModificationException


    他自己研究认为是
    archaius 包冲突导致

    直接把包给排除干掉


    因为其他项目都是一样的依赖包,感觉问题的根源不在这,而且把这个包去掉可能会影响项目的其他功能(配置刷新)



    排查的第一步还是看报错信息,报错是在HashTable里面的next方法。

    大致的报错原因是因为HashTable对象中的modCount值与其迭代器快照中的值不同,简单来说就是在获取迭代器后,又对源HashTable做了修改

    初看,应该是一个并发问题没跑了

    接着通过断点的方式,找到了其时间范围前后对系统属性做了设置的地方(因为获取迭代器的地方,包装的就是系统属性的)
    找到了两个地方

    第一个地方就是同事认为有问题的
    archaius
    包中的
    ArchaiusAutoConfiguration
        protected static void configureArchaius(
                ConfigurableEnvironmentConfiguration envConfig, ConfigurableEnvironment env,
                List<AbstractConfiguration> externalConfigurations) {
            if (initialized.compareAndSet(false, true)) {
                String appName = env.getProperty("spring.application.name");
                if (appName == null) {
                    appName = "application";
                    log.warn("No spring.application.name found, defaulting to 'application'");
                }
                System.setProperty(DeploymentContext.ContextKey.appId.getKey(), appName);
    
                ConcurrentCompositeConfiguration config = new ConcurrentCompositeConfiguration();
    
                // support to add other Configurations (Jdbc, DynamoDb, Zookeeper, jclouds,
                // etc...)
                if (externalConfigurations != null) {
                    for (AbstractConfiguration externalConfig : externalConfigurations) {
                        config.addConfiguration(externalConfig);
                    }
                }
                config.addConfiguration(envConfig,
                        ConfigurableEnvironmentConfiguration.class.getSimpleName());
    
                defaultURLConfig = new DynamicURLConfiguration();
                try {
                    config.addConfiguration(defaultURLConfig, URL_CONFIG_NAME);
                }
                catch (Throwable ex) {
                    log.error("Cannot create config from " + defaultURLConfig, ex);
                }
    
                // TODO: sys/env above urls?
                if (!Boolean.getBoolean(DISABLE_DEFAULT_SYS_CONFIG)) {
                    SystemConfiguration sysConfig = new SystemConfiguration();
                    config.addConfiguration(sysConfig, SYS_CONFIG_NAME);
                }
                if (!Boolean.getBoolean(DISABLE_DEFAULT_ENV_CONFIG)) {
                    EnvironmentConfiguration environmentConfiguration = new EnvironmentConfiguration();
                    config.addConfiguration(environmentConfiguration, ENV_CONFIG_NAME);
                }
    
                ConcurrentCompositeConfiguration appOverrideConfig = new ConcurrentCompositeConfiguration();
                config.addConfiguration(appOverrideConfig, APPLICATION_PROPERTIES);
                config.setContainerConfigurationIndex(
                        config.getIndexOfConfiguration(appOverrideConfig));
    
                addArchaiusConfiguration(config);
            }
            else {
                // TODO: reinstall ConfigurationManager
                log.warn(
                        "Netflix ConfigurationManager has already been installed, unable to re-install");
            }
        }

    初始化的时候设置了@appId的系统属性

    第二个地方是
    NioEventLoop
        static {
            String key = "sun.nio.ch.bugLevel";
            String bugLevel = SystemPropertyUtil.get("sun.nio.ch.bugLevel");
            if (bugLevel == null) {
                try {
                    AccessController.doPrivileged(new PrivilegedAction<Void>() {
                        public Void run() {
                            System.setProperty("sun.nio.ch.bugLevel", "");
                            return null;
                        }
                    });
                } catch (SecurityException var3) {
                    logger.debug("Unable to get/set System Property: sun.nio.ch.bugLevel", var3);
                }
            }
    
            int selectorAutoRebuildThreshold = SystemPropertyUtil.getInt("io.netty.selectorAutoRebuildThreshold", 512);
            if (selectorAutoRebuildThreshold < 3) {
                selectorAutoRebuildThreshold = 0;
            }
    
            SELECTOR_AUTO_REBUILD_THRESHOLD = selectorAutoRebuildThreshold;
            if (logger.isDebugEnabled()) {
                logger.debug("-Dio.netty.noKeySetOptimization: {}", DISABLE_KEY_SET_OPTIMIZATION);
                logger.debug("-Dio.netty.selectorAutoRebuildThreshold: {}", SELECTOR_AUTO_REBUILD_THRESHOLD);
            }
    
        }

    最后通过设置默认的

    sun.nio.ch.bugLevel系统属性

    暂时解决了这个问题
  • 相关阅读:
    一道小学数学题
    Ubuntu下使用git提交代码至GitHub
    C#几个小知识点
    C#中巧用#if DEBUG 进行调试
    使用 HPC Pack 为 Azure 中的 Windows HPC 工作负荷创建和管理群集的选项
    使用 Chef 自动执行 Azure 虚拟机部署
    在 Azure 中管理 Windows 虚拟机的可用性
    什么是 Azure 中的虚拟机规模集?
    从 Azure 下载 Windows VHD
    如何使用 Packer 在 Azure 中创建 Windows 虚拟机映像
  • 原文地址:https://www.cnblogs.com/gabin/p/14677527.html
Copyright © 2020-2023  润新知