关于log4cplus中AsyncAppender的配置

本文介绍如何在Log4cplus中使用AsyncAppender实现日志记录的异步化,以提高程序处理效率,并探讨其配置方法及风险。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

由于工作用log4cplus来记录日志,最近发现日志量大的时侯严重的影响了程序的处理效率,遂稍微研究了一下log4cplus, 发现所用到的RollingFileAppender是同步的,所以想改成异步的Appender比较下,但所用版本没有异步Appender,遂上官网看看了,发现自log4cplus.1.1.0来增加了AsyncAppender, 这个Appender支持异步的记录日志文件,但作者并没有更新文档(或是我没找到), 不知关于AsyncAppender的配置文件该如何写,稍微研究了下代码并摸索了,发现可以这样写(关于log4cplus的基本用法,google之):

log4cplus.rootLogger=TRACE, A1

log4cplus.appender.A1=log4cplus::AsyncAppender
log4cplus.appender.A1.Appender=log4cplus::RollingFileAppender
log4cplus.appender.A1.Appender.File=xxx.log
log4cplus.appender.A1.Appender.QueueLimit=10000
log4cplus.appender.A1.Appender.ImmediateFlush=false
log4cplus.appender.A1.Appender.MaxFileSize=1000MB
log4cplus.appender.A1.Appender.MaxBackupIndex=5
log4cplus.appender.A1.Appender.layout=log4cplus::PatternLayout
log4cplus.appender.A1.Appender.layout.ConversionPattern=%D{[%Y-%m-%d %H:%M:%S.%q]} [%-5p] [%c{2}] [%F:%L]%m%n


通过以发现AsyncAppender是异步到添加到RollingFileAppender上去的,其中QueueLimit属于表示存在于AsyncAppender队列中未处理的最大事件数量(目前默认为100),如果未处理的日志数量等于这个数个值,新的日志输出将会阻塞,直至未处理的值小于QueueLimit的值。


当然,异步日志的风险是当程序crash时,会丢失所有未输出的日志,对查看程序crash原因会造成一定的影响。


AsyncAppender是一个典型的生产者-消费者模型, 用一个队列来保存未处理的日志,一个线程来记录所有的日志。

18:00:32,438 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - Processing appender named [CONFIG_LOG_FILE] 18:00:32,439 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - About to instantiate appender of type [ch.qos.logback.core.rolling.RollingFileAppender] 18:00:32,464 |-INFO in ch.qos.logback.core.rolling.FixedWindowRollingPolicy@366d8b97 - No compression will be used 18:00:32,467 |-INFO in ch.qos.logback.core.model.processor.ImplicitModelHandler - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property 18:00:32,483 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[CONFIG_LOG_FILE] - Active log file name: /root/logs/nacos/config.log 18:00:32,483 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[CONFIG_LOG_FILE] - File property is set to [/root/logs/nacos/config.log] 18:00:32,484 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - Processing appender named [ASYNC-CONFIG] 18:00:32,484 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - About to instantiate appender of type [ch.qos.logback.classic.AsyncAppender] 18:00:32,486 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [CONFIG_LOG_FILE] to ch.qos.logback.classic.AsyncAppender[ASYNC-CONFIG] 18:00:32,487 |-INFO in ch.qos.logback.classic.AsyncAppender[ASYNC-CONFIG] - Attaching appender named [CONFIG_LOG_FILE] to AsyncAppender. 18:00:32,487 |-INFO in ch.qos.logback.classic.AsyncAppender[ASYNC-CONFIG] - Setting discardingThreshold to 0 18:00:32,487 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - Processing appender named [NAMING_LOG_FILE] 18:00:32,487 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - About to instantiate appender of type [ch.qos.logback.core.rolling.RollingFileAppender] 18:00:32,488 |-INFO in ch.qos.logback.core.rolling.FixedWindowRollingPolicy@feb98ef - No compression will be used 18:00:32,488 |-INFO in ch.qos.logback.core.model.processor.ImplicitModelHandler - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property 18:00:32,489 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[NAMING_LOG_FILE] - Active log file name: /root/logs/nacos/naming.log 18:00:32,489 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[NAMING_LOG_FILE] - File property is set to [/root/logs/nacos/naming.log] 18:00:32,489 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - Processing appender named [ASYNC-NAMING] 18:00:32,489 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - About to instantiate appender of type [ch.qos.logback.classic.AsyncAppender] 18:00:32,489 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [NAMING_LOG_FILE] to ch.qos.logback.classic.AsyncAppender[ASYNC-NAMING] 18:00:32,489 |-INFO in ch.qos.logback.classic.AsyncAppender[ASYNC-NAMING] - Attaching appender named [NAMING_LOG_FILE] to AsyncAppender. 18:00:32,489 |-INFO in ch.qos.logback.classic.AsyncAppender[ASYNC-NAMING] - Setting discardingThreshold to 0 18:00:32,489 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - Processing appender named [REMOTE_LOG_FILE] 18:00:32,489 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - About to instantiate appender of type [ch.qos.logback.core.rolling.RollingFileAppender] 18:00:32,490 |-INFO in ch.qos.logback.core.rolling.FixedWindowRollingPolicy@7654f833 - No compression will be used 18:00:32,490 |-INFO in ch.qos.logback.core.model.processor.ImplicitModelHandler - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property 18:00:32,490 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[REMOTE_LOG_FILE] - Active log file name: /root/logs/nacos/remote.log 18:00:32,490 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[REMOTE_LOG_FILE] - File property is set to [/root/logs/nacos/remote.log] 18:00:32,491 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - Processing appender named [ASYNC-REMOTE] 18:00:32,491 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - About to instantiate appender of type [ch.qos.logback.classic.AsyncAppender] 18:00:32,491 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [REMOTE_LOG_FILE] to ch.qos.logback.classic.AsyncAppender[ASYNC-REMOTE] 18:00:32,491 |-INFO in ch.qos.logback.classic.AsyncAppender[ASYNC-REMOTE] - Attaching appender named [REMOTE_LOG_FILE] to AsyncAppender. 18:00:32,491 |-INFO in ch.qos.logback.classic.AsyncAppender[ASYNC-REMOTE] - Setting discardingThreshold to 0 18:00:32,491 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting level of logger [com.alibaba.nacos.client] to INFO 18:00:32,494 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting additivity of logger [com.alibaba.nacos.client] to false 18:00:32,494 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [ASYNC-CONFIG] to Logger[com.alibaba.nacos.client] 18:00:32,494 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting level of logger [com.alibaba.nacos.common.labels] to INFO 18:00:32,494 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting additivity of logger [com.alibaba.nacos.common.labels] to false 18:00:32,494 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [ASYNC-REMOTE] to Logger[com.alibaba.nacos.common.labels] 18:00:32,494 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting level of logger [com.alibaba.nacos.common.remote.client] to INFO 18:00:32,494 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting additivity of logger [com.alibaba.nacos.common.remote.client] to false 18:00:32,494 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [ASYNC-REMOTE] to Logger[com.alibaba.nacos.common.remote.client] 18:00:32,494 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting level of logger [com.alibaba.nacos.shaded.io.grpc] to INFO 18:00:32,494 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting additivity of logger [com.alibaba.nacos.shaded.io.grpc] to false 18:00:32,494 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [ASYNC-REMOTE] to Logger[com.alibaba.nacos.shaded.io.grpc] 18:00:32,494 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting level of logger [com.alibaba.nacos.client.config] to INFO 18:00:32,494 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting additivity of logger [com.alibaba.nacos.client.config] to false 18:00:32,494 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [ASYNC-CONFIG] to Logger[com.alibaba.nacos.client.config] 18:00:32,494 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting level of logger [com.alibaba.nacos.client.naming] to INFO 18:00:32,494 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting additivity of logger [com.alibaba.nacos.client.naming] to false 18:00:32,494 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [ASYNC-NAMING] to Logger[com.alibaba.nacos.client.naming] 18:00:32,494 |-INFO in ch.qos.logback.core.model.processor.DefaultProcessor@571a01f9 - End of configuration. 18:00:32,495 |-INFO in com.alibaba.nacos.logbackadapter.NacosLogbackConfiguratorAdapterV2@42f33b5d - Registering current configuration as safe fallback point 18:00:33,840 |-INFO in ch.qos.logback.classic.AsyncAppender[ASYNC-CONFIG] - Worker thread will flush remaining events before exiting. 18:00:33,841 |-INFO in ch.qos.logback.classic.AsyncAppender[ASYNC-CONFIG] - Queue flush finished successfully within timeout. 18:00:33,841 |-INFO in ch.qos.logback.classic.AsyncAppender[ASYNC-NAMING] - Worker thread will flush remaining events before exiting. 18:00:33,841 |-INFO in ch.qos.logback.classic.AsyncAppender[ASYNC-NAMING] - Queue flush finished successfully within timeout. 18:00:33,841 |-INFO in ch.qos.logback.classic.AsyncAppender[ASYNC-REMOTE] - Worker thread will flush remaining events before exiting. 18:00:33,841 |-INFO in ch.qos.logback.classic.AsyncAppender[ASYNC-REMOTE] - Queue flush finished successfully within timeout. 18:00:33,847 |-INFO in ch.qos.logback.core.joran.spi.ConfigurationWatchList@d7109be - URL [jar:nested:/app/workflow.jar/!BOOT-INF/classes/!/logback-plus.xml] is not of type file 18:00:33,855 |-INFO in ch.qos.logback.core.joran.util.ConfigurationWatchListUtil@5e0ec41f - Adding [jar:nested:/app/workflow.jar/!BOOT-INF/lib/ruoyi-common-web-2.2.1.jar!/logback-common.xml] to configuration watch list. 18:00:33,855 |-INFO in ch.qos.logback.core.joran.spi.ConfigurationWatchList@d7109be - URL [jar:nested:/app/workflow.jar/!BOOT-INF/lib/ruoyi-common-web-2.2.1.jar!/logback-common.xml] is not of type file 18:00:33,863 |-WARN in ch.qos.logback.core.joran.action.IncludeAction - Could not find resource corresponding to [logback-logstash.xml] 18:00:33,864 |-WARN in ch.qos.logback.core.joran.action.IncludeAction - Could not find resource corresponding to [logback-skylog.xml] 18:00:33,869 |-INFO in ch.qos.logback.classic.model.processor.ConfigurationModelHandlerFull - Registering a new ReconfigureOnChangeTask ReconfigureOnChangeTask(born:1749722433867) 18:00:33,869 |-INFO in ch.qos.logback.classic.model.processor.ConfigurationModelHandlerFull - Will scan for changes in [jar:nested:/app/workflow.jar/!BOOT-INF/classes/!/logback-plus.xml] 18:00:33,869 |-INFO in ch.qos.logback.classic.model.processor.ConfigurationModelHandlerFull - Setting ReconfigureOnChangeTask scanning period to 1 minutes 18:00:33,870 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - Processing appender named [console] 18:00:33,870 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender] 18:00:33,870 |-INFO in ch.qos.logback.core.model.processor.ImplicitModelHandler - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property 18:00:33,872 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - Processing appender named [file_console] 18:00:33,872 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - About to instantiate appender of type [ch.qos.logback.core.rolling.RollingFileAppender] 18:00:33,873 |-INFO in c.q.l.core.rolling.TimeBasedRollingPolicy@256522893 - No compression will be used 18:00:33,874 |-INFO in c.q.l.core.rolling.TimeBasedRollingPolicy@256522893 - Will use the pattern logs/ruoyi-workflow/console.%d{yyyy-MM-dd}.log for the active file 18:00:33,883 |-INFO in c.q.l.core.rolling.DefaultTimeBasedFileNamingAndTriggeringPolicy - The date pattern is 'yyyy-MM-dd' from file name pattern 'logs/ruoyi-workflow/console.%d{yyyy-MM-dd}.log'. 18:00:33,883 |-INFO in c.q.l.core.rolling.DefaultTimeBasedFileNamingAndTriggeringPolicy - Roll-over at midnight. 18:00:33,883 |-INFO in c.q.l.core.rolling.DefaultTimeBasedFileNamingAndTriggeringPolicy - Setting initial period to 2025-06-12T10:00:33.883Z 18:00:33,884 |-INFO in ch.qos.logback.core.model.processor.ImplicitModelHandler - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property 18:00:33,888 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[file_console] - Active log file name: logs/ruoyi-workflow/console.log 18:00:33,888 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[file_console] - File property is set to [logs/ruoyi-workflow/console.log] 18:00:33,888 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - Processing appender named [file_info] 18:00:33,888 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - About to instantiate appender of type [ch.qos.logback.core.rolling.RollingFileAppender] 18:00:33,888 |-INFO in c.q.l.core.rolling.TimeBasedRollingPolicy@148436820 - No compression will be used 18:00:33,888 |-INFO in c.q.l.core.rolling.TimeBasedRollingPolicy@148436820 - Will use the pattern logs/ruoyi-workflow/info.%d{yyyy-MM-dd}.log for the active file 18:00:33,889 |-INFO in c.q.l.core.rolling.DefaultTimeBasedFileNamingAndTriggeringPolicy - The date pattern is 'yyyy-MM-dd' from file name pattern 'logs/ruoyi-workflow/info.%d{yyyy-MM-dd}.log'. 18:00:33,889 |-INFO in c.q.l.core.rolling.DefaultTimeBasedFileNamingAndTriggeringPolicy - Roll-over at midnight. 18:00:33,889 |-INFO in c.q.l.core.rolling.DefaultTimeBasedFileNamingAndTriggeringPolicy - Setting initial period to 2025-06-12T10:00:33.889Z 18:00:33,889 |-INFO in ch.qos.logback.core.model.processor.ImplicitModelHandler - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property 18:00:33,891 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[file_info] - Active log file name: logs/ruoyi-workflow/info.log 18:00:33,891 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[file_info] - File property is set to [logs/ruoyi-workflow/info.log] 18:00:33,891 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - Processing appender named [file_error] 18:00:33,891 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - About to instantiate appender of type [ch.qos.logback.core.rolling.RollingFileAppender] 18:00:33,892 |-INFO in c.q.l.core.rolling.TimeBasedRollingPolicy@224473864 - No compression will be used 18:00:33,892 |-INFO in c.q.l.core.rolling.TimeBasedRollingPolicy@224473864 - Will use the pattern logs/ruoyi-workflow/error.%d{yyyy-MM-dd}.log for the active file 18:00:33,892 |-INFO in c.q.l.core.rolling.DefaultTimeBasedFileNamingAndTriggeringPolicy - The date pattern is 'yyyy-MM-dd' from file name pattern 'logs/ruoyi-workflow/error.%d{yyyy-MM-dd}.log'. 18:00:33,892 |-INFO in c.q.l.core.rolling.DefaultTimeBasedFileNamingAndTriggeringPolicy - Roll-over at midnight. 18:00:33,893 |-INFO in c.q.l.core.rolling.DefaultTimeBasedFileNamingAndTriggeringPolicy - Setting initial period to 2025-06-12T10:00:33.893Z 18:00:33,893 |-INFO in ch.qos.logback.core.model.processor.ImplicitModelHandler - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property 18:00:33,893 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[file_error] - Active log file name: logs/ruoyi-workflow/error.log 18:00:33,893 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[file_error] - File property is set to [logs/ruoyi-workflow/error.log] 18:00:33,894 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - Processing appender named [async_info] 18:00:33,894 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - About to instantiate appender of type [ch.qos.logback.classic.AsyncAppender] 18:00:33,894 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [file_info] to ch.qos.logback.classic.AsyncAppender[async_info] 18:00:33,894 |-INFO in ch.qos.logback.classic.AsyncAppender[async_info] - Attaching appender named [file_info] to AsyncAppender. 18:00:33,894 |-INFO in ch.qos.logback.classic.AsyncAppender[async_info] - Setting discardingThreshold to 0 18:00:33,894 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - Processing appender named [async_error] 18:00:33,894 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - About to instantiate appender of type [ch.qos.logback.classic.AsyncAppender] 18:00:33,894 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [file_error] to ch.qos.logback.classic.AsyncAppender[async_error] 18:00:33,894 |-INFO in ch.qos.logback.classic.AsyncAppender[async_error] - Attaching appender named [file_error] to AsyncAppender. 18:00:33,894 |-INFO in ch.qos.logback.classic.AsyncAppender[async_error] - Setting discardingThreshold to 0 18:00:33,895 |-INFO in ch.qos.logback.classic.model.processor.RootLoggerModelHandler - Setting level of ROOT logger to INFO 18:00:33,895 |-INFO in ch.qos.logback.classic.jul.LevelChangePropagator@25673087 - Propagating INFO level on Logger[ROOT] onto the JUL framework 18:00:33,895 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [async_info] to Logger[ROOT] 18:00:33,895 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [async_error] to Logger[ROOT] 18:00:33,895 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [file_console] to Logger[ROOT] 18:00:33,895 |-INFO in ch.qos.logback.classic.model.processor.RootLoggerModelHandler - Setting level of ROOT logger to INFO 18:00:33,895 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [console] to Logger[ROOT] 18:00:33,896 |-INFO in ch.qos.logback.core.model.processor.DefaultProcessor@7b27e8f4 - End of configuration. 18:00:33,896 |-INFO in org.springframework.boot.logging.logback.SpringBootJoranConfigurator@348ad293 - Registering current configuration as safe fallback point :: Dubbo (v3.2.14) : https://github.com/apache/dubbo :: Discuss group : dev@dubbo.apache.org Spring Boot Version: 3.2.9 Spring Application Name: ruoyi-workflow _ _ __ _ (_) | | / _| | _ __ _ _ ___ _ _ _ ________ _____ _ __| | _| |_| | _____ __ | '__| | | |/ _ \| | | | |______\ \ /\ / / _ \| '__| |/ / _| |/ _ \ \ /\ / / | | | |_| | (_) | |_| | | \ V V / (_) | | | <| | | | (_) \ V V / |_| \__,_|\___/ \__, |_| \_/\_/ \___/|_| |_|\_\_| |_|\___/ \_/\_/ __/ | |___/ 2025-06-12 18:00:34 [main] INFO  o.d.w.RuoYiWorkflowApplication  - Starting RuoYiWorkflowApplication using Java 17.0.2 with PID 1 (/app/workflow.jar started by root in /app) 2025-06-12 18:00:34 [main] INFO  o.d.w.RuoYiWorkflowApplication  - The following 1 profile is active: "prod" 2025-06-12 18:00:34 [main] INFO  c.a.c.n.c.NacosConfigDataLoader  - [Nacos Config] Load config[dataId=ruoyi-workflow.yml, group=ARCHIVES] success 2025-06-12 18:00:34 [main] INFO  c.a.c.n.c.NacosConfigDataLoader  - [Nacos Config] Load config[dataId=datasource.yml, group=ARCHIVES] success 2025-06-12 18:00:34 [main] INFO  c.a.c.n.c.NacosConfigDataLoader  - [Nacos Config] Load config[dataId=application-common.yml, group=ARCHIVES] success 2025-06-12 18:00:41 [main] WARN  o.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContext  - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Unable to start web server 2025-06-12 18:00:41 [main] ERROR o.s.b.d.LoggingFailureAnalysisReporter  - *************************** APPLICATION FAILED TO START *************************** Description: Web application could not be started as there was no org.springframework.boot.web.servlet.server.ServletWebServerFactory bean defined in the context. Action: Check your application's dependencies for a supported servlet web server. Check the configured web application type. 2025-06-12 18:00:41 [Thread-6] WARN  c.a.nacos.common.notify.NotifyCenter  - [NotifyCenter] Start destroying Publisher 2025-06-12 18:00:41 [Thread-6] WARN  c.a.nacos.common.notify.NotifyCenter  - [NotifyCenter] Destruction of the end 2025-06-12 18:00:41 [Thread-4] WARN  c.a.n.c.http.HttpClientBeanHolder  - [HttpClientBeanHolder] Start destroying common HttpClient 2025-06-12 18:00:41 [Thread-4] WARN  c.a.n.c.http.HttpClientBeanHolder  - [HttpClientBeanHolder] Destruction of the end 分析日志给出解决办法 需要nacos如何配置
06-13
<think>我们面对的问题是SpringBoot应用启动失败,具体错误是“Unabletostartwebserver”,因为缺少`ServletWebServerFactory`bean。同时,应用使用了Nacos配置中心。日志显示应用从Nacos加载了几个配置文件(如`ruoyi-workflow.yml`等),但随后在启动Web服务器时失败。根据引用[2],用户提到在pom.xml中曾经排除了Tomcat依赖(但后来注释掉了),这可能是导致问题的原因之一。另外,引用[3]提到引入`javax.servlet-api`依赖也可能是原因之一。结合这些信息,我们可以从以下几个方面分析:1.**依赖问题**:检查项目中是否排除了内嵌Web服务器(如Tomcat)的依赖,或者是否错误地引入了ServletAPI导致冲突。2.**自动配置问题**:SpringBoot的自动配置需要`spring-boot-starter-web`来提供Web相关的自动配置,包括创建`ServletWebServerFactory`bean。如果这个自动配置没有生效,就会导致此错误。3.**Nacos配置问题**:检查Nacos中的配置是否影响了Web服务器的自动配置(例如,是否禁用了Web相关的自动配置)。##解决步骤###1.检查Maven依赖首先,确保在`pom.xml`中包含了`spring-boot-starter-web`依赖,并且没有排除Tomcat。根据引用[2],用户曾经排除了Tomcat,但后来注释掉了,所以需要确认当前实际生效的依赖。检查`pom.xml`中是否有如下依赖,并且没有排除Tomcat:```xml<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>```如果确实需要更换Web服务器(比如使用Jetty),那么需要排除Tomcat并添加Jetty的starter,但必须确保有一个`ServletWebServerFactory`的实现。但如果没有特殊需求,建议使用默认的Tomcat。另外,检查是否引入了`javax.servlet-api`(如引用[3]所示)。如果引入了,应该移除,因为SpringBoot的WebStarter已经包含了ServletAPI。引入独立的ServletAPI可能会导致版本冲突。检查依赖:```xml<!--不应该单独引入,如果存在则移除--><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId></dependency>```###2.检查自动配置确保SpringBoot的自动配置能够正常工作。检查主类(带有`@SpringBootApplication`的类)是否在根包下,并且没有使用`@EnableAutoConfiguration`排除Web自动配置。同时,检查Nacos配置中心的配置(如`application-common.yml`)中是否有影响自动配置的属性。特别关注以下属性:-`spring.main.web-application-type`:如果设置为`NONE`,则会禁用Web服务器的创建。确保没有设置为`NONE`。-`spring.autoconfigure.exclude`:如果排除了Web相关的自动配置类(如`org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration`),则会导致问题。在Nacos中检查这些配置文件,确保没有禁用Web自动配置。###3.检查日志中的配置加载从日志中可以看到,应用从Nacos加载了三个配置文件:-ruoyi-workflow.yml-datasource.yml-application-common.yml我们需要检查这些配置文件,特别是`application-common.yml`,看是否有影响Web服务器自动配置的属性。###4.手动定义ServletWebServerFactory(备用方案)如果上述步骤无法解决问题,可以尝试手动定义`ServletWebServerFactory`bean。但这种方法通常不是必须的,因为自动配置应该会提供这个bean。只有在特殊情况下(例如需要完全自定义Web服务器)才需要这样做。在配置类中添加:```java@BeanpublicServletWebServerFactoryservletWebServerFactory(){returnnewTomcatServletWebServerFactory();//使用Tomcat}```##针对Nacos配置的检查由于应用使用了Nacos配置中心,我们需要确保Nacos上的配置正确。登录Nacos控制台,检查对应命名空间(根据日志中的`group=ARCHIVES`)下的配置文件:1.**ruoyi-workflow.yml**:检查是否有与Web服务器相关的配置。2.**datasource.yml**:通常只包含数据源配置,不太可能影响Web服务器。3.**application-common.yml**:这是通用配置,最有可能包含影响自动配置的属性。在`application-common.yml`中,检查以下属性:```yamlspring:main:web-application-type:none#如果设置为none,则会导致错误,应该删除或改为servletautoconfigure:exclude:-...#如果排除了Web自动配置类,则移除```另外,检查是否有`server.port`等配置,虽然这些不会导致缺少工厂bean,但如果有其他问题也会导致启动失败。##总结步骤1.**检查依赖**:确保`spring-boot-starter-web`存在且未排除Tomcat;移除独立的`javax.servlet-api`依赖。2.**检查Nacos配置**:重点检查`application-common.yml`,确保没有设置`spring.main.web-application-type=none`,也没有排除Web自动配置类。3.**检查启动类**:确保主类位于根包下,没有排除自动配置4.**尝试手动定义**:如果问题依旧,尝试手动定义`TomcatServletWebServerFactory`bean。##相关引用说明-引用[2]中提到用户曾经排除了Tomcat依赖,这会导致缺少`ServletWebServerFactory`,因为自动配置需要Tomcat的类存在。所以务必确保没有排除。-引用[3]中提到的单独引入`javax.servlet-api`可能会导致依赖冲突,从而影响自动配置,所以应该移除。如果按照以上步骤检查,问题应该可以解决。§§相关问题§§1.如何排查SpringBoot自动配置问题?2.Nacos配置中心如何影响SpringBoot应用的启动?3.如何在SpringBoot中更换内嵌的Web服务器(例如从Tomcat换成Jetty)?</think>### Spring Boot 3.2.9启动失败分析与解决方案(Nacos配置场景) #### 问题诊断 根据日志和引用信息,您的应用启动失败核心原因是 **缺少`ServletWebServerFactory` bean**。结合Nacos配置中心的使用,可能的原因包括: 1. **Web依赖配置问题**(关键原因) 引用[2]显示您的`pom.xml`曾排除Tomcat依赖(即使已注释): ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <!-- 曾存在Tomcat排除配置 --> </dependency> ``` 这可能导致: - Maven本地仓库残留旧依赖(即使注释,本地缓存可能仍生效) - 依赖传递冲突影响自动配置 2. **Nacos配置冲突** 日志显示加载了多个配置: ``` Load config[dataId=ruoyi-workflow.yml...] Load config[dataId=datasource.yml...] Load config[dataId=application-common.yml...] ``` 若这些配置包含以下属性,会禁用Web服务器: ```yaml spring: main: web-application-type: none # 错误配置 ``` 3. **Servlet API冲突** 引用[3]提到单独引入`javax.servlet-api`会导致与Spring Boot内嵌Tomcat的依赖冲突[^3]。 --- #### 解决方案(分步骤操作) ##### 1. 验证并修复依赖(立即生效) **步骤:** ```bash # 清理Maven本地缓存(关键步骤) mvn dependency:purge-local-repository # 确认依赖树无冲突 mvn dependency:tree | grep 'tomcat\|servlet' ``` **修正`pom.xml`:** ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <!-- 确保无任何exclusions --> </dependency> <!-- 移除冲突的servlet-api依赖 --> <!-- 删除此项 ↓↓↓ --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> </dependency> ``` ##### 2. 检查Nacos配置(针对prod环境) 在Nacos控制台检查以下配置: ```yaml # application-common.yml 或 ruoyi-workflow.yml spring: main: web-application-type: servlet # 必须为servlet(默认值) # 确保无禁用自动配置项 spring.autoconfigure.exclude: # 此列表应为空 ``` ##### 3. 添加显式Bean定义(备用方案) 在启动类中添加: ```java import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.context.annotation.Bean; @SpringBootApplication public class RuoYiWorkflowApplication { public static void main(String[] args) { SpringApplication.run(RuoYiWorkflowApplication.class, args); } // 显式定义Web服务器工厂Bean @Bean public ServletWebServerFactory servletWebServerFactory() { return new TomcatServletWebServerFactory(); } } ``` ##### 4. 验证Nacos配置加载顺序 在`bootstrap.yml`中明确指定配置优先级: ```yaml spring: cloud: nacos: config: group: ARCHIVES # 明确配置加载顺序 shared-configs[0]: data-id: application-common.yml refresh: true shared-configs[1]: data-id: datasource.yml refresh: true shared-configs[2]: data-id: ruoyi-workflow.yml refresh: true ``` --- #### 预防措施 1. **依赖管理**: - 使用`mvn dependency:analyze`检查依赖冲突 - Spring Boot 3.x需用Jakarta EE 9+(勿混用javax.servlet) 2. **Nacos配置规范**: ```yaml # 在Nacos中配置默认Web端口 server: port: 8080 # 确保存在 ``` 3. **日志诊断**: 启用调试日志: ```yaml # application-prod.yml logging: level: org.springframework.boot: DEBUG ``` > **关键结论**:问题根源是依赖配置与Nacos配置的交互异常。按步骤操作后,应用应正常启动。若仍失败,检查`spring.factories`文件是否包含`ServletWebServerFactoryAutoConfiguration`[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值