欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 维修 > log4j2配置异步模式、结构化日志以及接入skywalking监控系统

log4j2配置异步模式、结构化日志以及接入skywalking监控系统

2025/6/19 19:21:38 来源:https://blog.csdn.net/qq_45942092/article/details/148686024  浏览:    关键词:log4j2配置异步模式、结构化日志以及接入skywalking监控系统

日志文件选用

目前项目里采用的是 log4j2 ,选择原因如下

Java 选择日志方案

选择日志方案
选择日志门面
SLF4J 2.x
SLF4J 1.x
直接使用实现API
选择具体实现
Logback
Log4j2
JUL

SLF4J 1.x与SLF4J 2.x比对

以下是 Spring Boot 2.x(基于 SLF4J 1.x)与 Spring Boot 3.x(基于 SLF4J 2.x)的详细对比

特性Spring Boot 2.x (SLF4J 1.x)Spring Boot 3.x (SLF4J 2.x)
SLF4J 版本SLF4J 1.7.x(如 1.7.36)SLF4J 2.0.x(如 2.0.7)
Java 版本要求Java 8-17Java 17+
默认日志实现LogbackLogback(适配 SLF4J 2.x)
模块化支持部分支持(需额外配置)完全支持(JPMS,module-info.java)
性能优化常规实现零分配日志记录器、Lambda 延迟求值
结构化日志需依赖第三方库(如 Logstash encoder)原生支持 StructuredArguments
API 风格传统 if (logger.isInfoEnabled())支持 Lambda 表达式(logger.info(() -> …))
桥接器版本兼容 SLF4J 1.x 桥接器需升级到 SLF4J 2.x 桥接器
虚拟线程支持不支持(Java 19+ 虚拟线程需手动适配)原生支持虚拟线程(Logback 1.4.x 优化线程上下文管理)
日志参数绑定仅支持基础类型占位符({})支持复杂对象绑定(logger.info(“User: {}”, userObj))
MDC 性能基于 ThreadLocal 的 MDC(存在线程切换开销)优化 MDC 存储结构(减少高并发场景下的上下文切换损耗)
日志门面扩展扩展接口有限(需自定义 Appender)新增 SPI 扩展点(如 LoggerContextFactory)
类加载隔离依赖传统类加载器(多模块环境可能冲突)兼容模块化类加载器(减少依赖冲突)
安全管理器支持部分支持(需手动配置 SecurityManager)增强安全管理器适配(原生支持 Java SecurityManager)

SLF4J 2.x 的核心价值

  • 面向未来的日志标准

    • 虚拟线程/云原生/Serverless友好设计

    • 结构化日志原生支持(OpenTelemetry集成)

  • 三重性能突破

    • 内存占用降低30%(对比SLF4J 1.x)

    • 异步吞吐提升5倍(对比Logback原生异步)

    • GC压力减少40%


Spring Boot 日志配置:

Spring Boot
自动配置
Logback
SLF4J 2.x

Logback:

  • 无需额外配置,默认提供 SLF4J 2.x + Logback

Log4j2:

  • 排除 spring-boot-starter-logging 依赖,
  • 添加 spring-boot-starter-log4j2 依赖
  • 添加 disruptor 依赖
  • 排查依赖冲突
    mvn dependency:tree -Dincludes="org.slf4j,ch.qos.logback,org.apache.logging.log4j,log4j"
    
特别注意:nacos导致log4j2不输出日志

当自定义日志文件名称(log4j2-dev.xml)或者自定义日志文件地址(classpath:log/log4j2-dev.xml)时,日志不生效!

因为nacos 默认日志文件名以及地址为 classpath:nacos-log4j2.xml

原因分析:

1、在 com.alibaba.nacos.client.logging 有一段逻辑如下

     //大致意思为 // nacos会尝试加载 `ch.qos.logback.classic.Logger` 这个类, // 加载成功的话, 说明项目使用的是 logback 日志框架, // 加载不到的话, 就是使用 log4j2private NacosLogging() {try {Class.forName("ch.qos.logback.classic.Logger");nacosLogging = new LogbackNacosLogging();isLogback = true;} catch (ClassNotFoundException e) {nacosLogging = new Log4J2NacosLogging();}}

2、进入到 Log4J2NacosLogging 中,可以看到默认的日志文件地址为 classpath:nacos-log4j2.xml

3、 进入到 Log4J2NacosLoggingloadConfiguration() 方法中。

4、从代码中看到, nacos 会重新加载日志的配置,如果在项目 resources 下没有配置 nacos-log4j2.xml文件,则会加载 com.alibaba.nacos.client 自带的nacos-log4j2.xml文件。

5、然而 com.alibaba.nacos.client 自带的配置文件没有设置日志的 Root,就会报下面的错误,导致log4j2不输出日志,日志文件配置也就失效了!


WARN No Root logger was configured, creating default ERROR-level Root logger with Console appender
如何解决 nacos 导致 log4j2 不输出日志的问题

如果想更换文件名或者地址,必须在 Nacos初始化 之前更新日志文件目录

  • 方法一:更改 nacos 默认的加载地址

    (1)使用JVM参数

    
    # 在启动命令中加入:
    -Dnacos.logging.config=classpath:log/log4j2-dev.xml

    (2)必须在SpringApplication.run之前配置

    public static void main(String[] args) {System.setProperty("nacos.logging.config", "classpath:log/log4j2-dev.xml");SpringApplication.run(UrlShortenerDomainApplication.class, args);}
    
  • 方法二:禁用nacos绑定的日志启用,转为log4j2自身的日志加载

    (1)使用JVM参数

    
    # 在启动命令中加入:
    -Dnacos.logging.default.config.enabled=false

    (2)在SpringApplication.run之前设置

    
    public static void main(String[] args) {System.setProperty("nacos.logging.default.config.enabled", "false");SpringApplication.run(UrlShortenerDomainApplication.class, args);
    }

logback与log4j2比对表格

特性Log4j2 (v2.x+)Logback (v1.4.x+)
项目背景Apache 基金会维护,Log4j 的升级版SLF4J 官方实现,由 Log4j 创始人开发
性能⭐⭐⭐⭐⭐
异步日志吞吐量更高(LMAX Disruptor 技术)
⭐⭐⭐⭐
同步日志性能优异,
异步略低于 Log4j2,
可自定义配置自研的MpscArrayQueue(基于 JCTools)
配置格式XML/JSON/YAML/PropertiesXML/Groovy
异步机制✅ LMAX Disruptor
• 无锁环形队列
• 线程绑定优化
⚠️ BlockingQueue
• ArrayBlockingQueue
• 易发生竞争
自动重载配置✅ 支持热更新✅ 支持热更新
异步日志✅ 内置高性能异步(AsyncLogger)✅ 需依赖 logback-classic 实现
过滤机制✅ 强大(复合过滤器、脚本支持)✅ 基础过滤(ThresholdFilter 等)
输出格式✅ 自定义 Layout(支持 PatternLayout 等)✅ 类似 Log4j2,兼容性强
多路输出✅ 灵活 Appender 组合✅ 类似 Log4j2(Appender 嵌套)
依赖管理无依赖(核心独立)依赖 SLF4J API
插件扩展✅ 模块化插件系统❌ 扩展性较弱
云原生支持✅ 更好的 Docker/K8s 集成⚠️ 需手动适配
漏洞风险⚠️ 曾曝出高危漏洞(如 Log4Shell)✅ 相对安全
虚拟线程支持✅ 原生支持
• 异步日志自动兼容虚拟线程
• 线程局部变量(ThreadLocal)优化
⚠️ 需手动适配
• 同步日志模式可能阻塞虚拟线程
• MDC(映射诊断上下文)需手动适配
GraalVM 原生镜像✅ 官方支持
• 提供原生镜像配置文件模板
• 反射/资源可配置化
⚠️ 实验性支持
• 需手动配置反射规则
• 动态类加载可能导致运行时错误
结构化日志✅ 原生JSON模板布局
• 零序列化开销
• 直接注入自定义字段
⚠️ 依赖logstash-encoder
• JSON序列化额外开销
• 反射性能损耗
依赖传递❌ 需手动排除冲突依赖✅ 天然兼容 SLF4J 零配置
社区活跃度⭐⭐⭐⭐(Apache 支持)⭐⭐⭐(维护较慢)

选型决策树

Yes
No
Yes
No
Yes
No
Yes
No
新项目选型
需要虚拟线程/GraalVM?
Log4j2
日志量>10万/日?
Logback
现存系统优化
出现虚拟线程阻塞?
迁移至Log4j2
GC停顿>20ms?
保持Logback+异步队列优化

📌 结论:

  • 新项目首选 Log4j2(虚拟线程/GraalVM/云原生三优势)
  • 兼容性优先场景可选 Logback(需规避虚拟线程阻塞问题)
  • 两者均可通过 log4j-to-slf4j/logback-to-log4j 互相桥接

Log4j2 异步日志记录

AsyncLogger依赖disruptor框架,因此需要在classpath路径下需要额外添加disruptor的jar包。AsyncLogger有两种方式全异步方式和混合同步异步方式。

(1)全异步方式,需要设置系统属性,指定log4j2.contextSelector值为org.apache.logging.log4j.core.async.AsyncLoggerContextSelector,配置文件中使用< Logger>或< Root>标签

(2)混合同步异步方式无需设置系统属性log4j2.contextSelector,在配置文件中使用< AsyncLogger>或< AsyncRoot>标签代替< Logger>或< Root>标签。

引入依赖

        <disruptor.version>3.4.4</disruptor.version><dependency><groupId>com.lmax</groupId><artifactId>disruptor</artifactId><version>${disruptor.version}</version></dependency>

完整的xml配置:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" monitorInterval="0" shutdownTimeout="30"><!-- 配置内容 --><!--日志级别从低到高通常为:ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF--><!-- 1. 核心优化参数 --><Properties><!-- 路径变量 --><!--日志文件名称:这里spring.application.name表示工程名称--><Property name="APP_NAME" value="${spring:spring.application.name}"/><Property name="LOG_DIR">logs/${APP_NAME}</Property><Property name="LOG_FILENAME">${APP_NAME}</Property><Property name="LOG_METRICS_DIR">${LOG_DIR}/${APP_NAME}-metrics</Property><Property name="LOG_METRICS">${APP_NAME}-metrics</Property><!--文件打印格式--><Property name="LOG_PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} ➤ %msg%n</Property><!--控制台打印日志格式--><Property name="COLOUR_LOG_PATTERN">%style{%d{yyyy-MM-dd HH:mm:ss.SSS}}{blue} %style{[%t]}{cyan} %highlight{%-5level} %highlight{%logger{36}} ➤ %m%n</Property><!-- 禁用不必要功能 --><Property name="log4j2.disableSmtp">true</Property><!--插件扫描机制被禁用--><!-- <Property name="log4j2.disableOsgi">true</Property>--><!-- Log4j2 避免设置 includeLocation=true (性能下降5-10倍) --><Property name="INCLUDE_LOCATION">false</Property>   <!-- 禁用栈帧获取 --><!-- 开启线程上下文继承 ,如果不开启会导致log4j2异步子线程无法获取TraceId--><Property name="log4j2.isThreadContextMapInheritable">true</Property><!--(1)全异步方式,需要设置系统属性,指定log4j2.contextSelector值为org.apache.logging.log4j.core.async.AsyncLoggerContextSelector,配置文件中使用<Logger>或<Root>标签(2)混合同步异步方式无需设置系统属性log4j2.contextSelector,在配置文件中使用<AsyncLogger>或<AsyncRoot>标签代替<Logger>或<Root>标签。--><Property name="log4j2.contextSelector">org.apache.logging.log4j.core.async.AsyncLoggerContextSelector</Property><!-- 性能关键参数 --><!-- Disruptor 环形缓冲区大小--><Property name="RING_BUFFER_SIZE">262144</Property>  <!-- 256K 环形缓冲 --><!--  AsyncAppender 队列大小      --><Property name="ASYNC_QUEUE_SIZE">131072</Property>  <!-- 128K 安全队列 --><!-- AsyncLogger 默认缓冲区大小 会被 RING_BUFFER_SIZE 覆盖--><Property name="log4j2.DirectAsyncQueueSize">131072</Property>  <!-- 128K 环形缓冲 --><!-- 队列满策略:Discard:直接丢弃新日志DiscardAdvanced:智能丢弃(默认)(先丢弃低级别日志 (INFO/DEBUG))Block:阻塞生产者线程CallerRuns:在生产者线程同步写入--><Property name="log4j2.AsyncQueueFullPolicy">DiscardAdvanced</Property> <!-- 队列满策略 --><!-- 配置DiscardAdvanced策略的阈值 --><Property name="log4j2.DiscardThreshold">0.8</Property> <!-- 队列使用率低于80%时不丢弃 --><!-- 等待策略配置 --><!-- 可选值:Sleeping:低CPU占用,默认策略Blocking:使用锁,吞吐量稳定Yielding:平衡型,适合常规应用BusySpin:最高性能,独占CPU核心PhasedBackoff:混合策略,自动切换--><Property name="log4j2.AsyncLogger.WaitStrategy">Yielding</Property><!-- 如果你选择PhasedBackoff策略,需要额外配置 --><!-- <Property name="log4j2.AsyncLogger.PhasedBackoffSpinThreshold">10000</Property>--><!-- <Property name="log4j2.AsyncLogger.PhasedBackoffLockThreshold">1000</Property>--><!--ScriptEngine 禁用配置,防止日志注入攻击--><Property name="log4j2.disableScriptEngine" value="true"/></Properties><!-- 2. Appender 配置 --><Appenders><!-- 控制台输出 (同步) --><Console name="CONSOLE" target="SYSTEM_OUT"><PatternLayout pattern="${COLOUR_LOG_PATTERN}"/></Console><!-- 高性能文件输出 (异步专用) --><RollingFile name="FILE_ASYNC"fileName="${LOG_DIR}/${LOG_FILENAME}.log"filePattern="${LOG_DIR}/${LOG_FILENAME}-%d{yyyy-MM-dd}.%i.log.gz"immediateFlush="false"> <!-- 批处理写入 --><!-- 结构化日志 可去官网具体查看:https://logging.apache.org/log4j/2.x/manual/json-template-layout.html#event-template-resolver-exception--><!-- <JsonTemplateLayout eventTemplateUri="classpath:log/LogstashJson.json"/>--><!-- 文本格式--><PatternLayout pattern="${LOG_PATTERN}"/><!-- 滚动策略优化 --><Policies><SizeBasedTriggeringPolicy size="500 MB"/> <!-- 大文件减少IO --><TimeBasedTriggeringPolicy modulate="true" interval="1"/> <!-- 自然时间滚动 --></Policies><!-- 异常日志限流 系统遭遇突发异常(如网络波动、数据库连接失败)时,避免同一异常被频繁记录(如每秒数百次),导致日志文件暴增或 IO 资源被耗尽, 看需求是否开启--><Filters><!-- 仅处理 ERROR 级别日志 --><ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="NEUTRAL"/><!-- 限流配置:突发200条,持续每秒3条 (180条/分钟)  --><BurstFilter level="ERROR" rate="3" maxBurst="200" onMatch="ACCEPT" onMismatch="DENY"/></Filters></RollingFile><!-- 百万日志监控Appender (可选) --><RollingFile name="METRICS"fileName="${LOG_METRICS_DIR}/${LOG_METRICS}.log"filePattern="${LOG_METRICS_DIR}/${LOG_METRICS}-%d{yyyy-MM-dd}.log.gz"immediateFlush="false"><!-- 结构化指标输出 --><!-- <JsonTemplateLayout eventTemplateUri="classpath:log/LogstashJson.json"/>--><!-- 文本日志格式:%m%n = 只输出原始消息 + 换行 --><PatternLayout pattern="${LOG_PATTERN}"/><Policies><TimeBasedTriggeringPolicy modulate="true" interval="1"/></Policies><!-- 过滤器:仅接受 WARN 及以上级别的日志 --><ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY"/></RollingFile></Appenders><!-- 3. 异步日志器配置 --><Loggers><!-- 根日志器 (高性能异步) --><!-- <AsyncRoot>与AsyncLogger使用日志框架内置的优化线程池(如 Disruptor 队列)--><!-- <Root>+<Async>附录器 先经 Root 同步处理,再由附录器转为异步--><AsyncRoot level="INFO"includeLocation="${INCLUDE_LOCATION}"><!-- 生产环境配置 --><AppenderRef ref="FILE_ASYNC"/><!--  开发环境开启控制台--><AppenderRef ref="CONSOLE"/><!-- 百万日志性能监控 --><AppenderRef ref="METRICS"/></AsyncRoot><!--        关键性能类专用日志器--><!--通过日志配置中的 <AsyncLogger> 可以监控任意指定的类(包括自定义核心类),只需修改 name 属性为目标类的全限定名,并结合日志框架的特性即可实现。Log4j2 的日志器名称匹配采用层级结构,规则如下:全限定名(如com.service.UserService):精确匹配指定类的日志器。部分名称(如UserService):匹配所有以该名称结尾的类。例如:com.service.UserServicecom.monitor.UserServiceUserService(默认包下的类)包路径(如com.service):匹配该包及其子包下的所有类。--><!--        <AsyncLogger name="com.service.PerfService" --><!--                     level="DEBUG"--><!--                     includeLocation="${INCLUDE_LOCATION}"--><!--                     additivity="false">--><!--            <AppenderRef ref="FILE_ASYNC"/> &lt;!&ndash; 输出到专用性能日志文件 &ndash;&gt;--><!--        </AsyncLogger>--><!-- 虚拟线程监控器 --><AsyncLogger name="VirtualThreadMonitor"level="TRACE"includeLocation="${INCLUDE_LOCATION}"additivity="false"><AppenderRef ref="METRICS"/></AsyncLogger></Loggers>
</Configuration>

配置结构化日志

{"service": "${spring:spring.application.name}","environment": "${spring:spring.profiles.active:-dev}","timestamp": {"$resolver": "timestamp","pattern": {"format": "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"}},"level": {"$resolver": "level","field": "name"},"logger_name": {"$resolver": "logger","field": "name"},"thread_name": {"$resolver": "thread","field": "name"},"message": {"$resolver": "message","stringified": true},"mdc": {"$resolver": "mdc","default": {}},"exception": {"$resolver": "exception","field": "stackTrace","stackTrace": {"maxDepth": 100,"stringified": true}},"source": {"class": {"$resolver": "source","field": "className"},"file": {"$resolver": "source","field": "fileName"},"line": {"$resolver": "source","field": "lineNumber"}}
}

以下是详细解释:

  1. 缓冲区大小配置
属性名称说明
RING_BUFFER_SIZE262144Disruptor 环形缓冲区大小
• 256K 条目容量 (262144 = 256 × 1024)
• 适用于 AsyncLogger 的全局设置
ASYNC_QUEUE_SIZE131072AsyncAppender 队列大小
• 128K 条目容量 (131072 = 128 × 1024)
• 用于 包装器的独立队列
log4j2.DirectAsyncQueueSize65536AsyncLogger 默认缓冲区大小
• 64K 条目容量 (65536)
• 系统级默认值,会被 RING_BUFFER_SIZE 覆盖

📌 关键区别:

  • RING_BUFFER_SIZE 控制全局 AsyncLogger 缓冲区

  • ASYNC_QUEUE_SIZE 控制单个 AsyncAppender 队列

  • 最终生效值 = 显式配置 > 全局属性 > 默认值(4092)

  1. 队列满策略配置
属性名称说明
log4j2.AsyncQueueFullPolicyDiscardAdvanced队列满处理策略
• Discard:直接丢弃新日志
• DiscardAdvanced:智能丢弃(默认)
• Block:阻塞生产者线程
• CallerRuns:在生产者线程同步写入
log4j2.DiscardThreshold0.8智能丢弃阈值
• 仅在 DiscardAdvanced 时生效
• 队列使用率 ≤ 80% 时不丢弃任何日志
• >80% 时优先丢弃低级别日志 (INFO/DEBUG)
  1. 高性能等待策略
属性名称说明
log4j2.AsyncLogger.WaitStrategyYielding线程等待策略
• Sleeping:低CPU占用,默认策略
• Blocking:使用锁,吞吐量稳定
• Yielding:平衡型,适合常规应用
• BusySpin:最高性能,独占CPU核心
• PhasedBackoff:混合策略,自动切换

⚙️ 策略选择建议:

  • 常规服务器:Yielding (当前配置)

  • 低延迟交易系统:BusySpin

  • 资源受限环境:Sleeping

使用
策略
等待
使用
策略
等待
AsyncLogger
RING_BUFFER_SIZE
AsyncQueueFullPolicy
DiscardThreshold
WaitStrategy
AsyncAppender
ASYNC_QUEUE_SIZE

最佳实践建议

  1. 缓冲区大小

    • 生产环境推荐:RING_BUFFER_SIZE=262144 (256K)

    • 内存敏感场景:131072 (128K) 足够

  2. 队列满策略

<!-- 智能丢弃 + 80%缓冲保留 -->
<Property name="log4j2.AsyncQueueFullPolicy">DiscardAdvanced</Property>
<Property name="log4j2.DiscardThreshold">0.8</Property>
  1. 等待策略
<!-- 常规服务器用 Yielding,交易系统用 BusySpin -->
<Property name="log4j2.AsyncLogger.WaitStrategy">Yielding</Property>

💡 性能提示:256K缓冲区 + Yielding策略 + DiscardAdvanced 的组合可在高吞吐(>100k logs/s)场景下保持稳定,同时避免日志丢失风险。

接入skywalking

引入依赖

    <skywalking.log4j.version>9.4.0</skywalking.log4j.version><dependency><groupId>org.apache.skywalking</groupId><artifactId>apm-toolkit-log4j-2.x</artifactId><version>${skywalking.log4j.version}</version><!--与skywalking-agent版本一致--></dependency><dependency><groupId>org.apache.skywalking</groupId><artifactId>apm-toolkit-trace</artifactId><version>${skywalking.log4j.version}</version></dependency>

skywalking打印日志格式

        <!-- Skywalking 打印日志格式 --><Property name="SKYWALKING_TRACE_PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level [%traceId] %logger{36} - %msg%n</Property><!-- SW_CTX中包含 traceId--><!-- SW_CTX: [$serviceName,$instanceName,$traceId,$traceSegmentId,$spanId]--><Property name="SKYWALKING_SW_CTX_PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level [%sw_ctx] %logger{36} - %msg%n</Property>

Appender 配置

    <!-- Appender 配置 --><Appenders><!--skywalking grpc 日志收集--><GRPCLogClientAppender name="grpc"><!-- 文本格式--><!-- <PatternLayout pattern="${SKYWALKING_SW_CTX_PATTERN}"/>--><!-- json格式--><JsonTemplateLayout eventTemplateUri="classpath:log/SkyWalkingJson.json"/></GRPCLogClientAppender></Appenders>

日志器配置

    <!-- 3. 日志器配置 --><Loggers><Root level="INFO"includeLocation="false"><!--  开发环境开启控制台--><AppenderRef ref="CONSOLE"/><!-- Skywalking 集成 (可选)  --><AppenderRef ref="grpc"/></Root></Loggers>

官网说skywalking支持AsyncLoggerContextSelector

原话为:

Support -Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector in gRPC log report.

但我用异步去上传时,日志Log就会有些缺失

ERROR 2025-06-13 02:20:30.692 SkywalkingAgent-11-ConfigurationDiscoveryService-0 ConfigurationDiscoveryService : ConfigurationDiscoveryService execute fail. 
org.apache.skywalking.apm.dependencies.io.grpc.StatusRuntimeException: INTERNAL: Encountered end-of-stream mid-frame

不知道是不是SkyWalking 代理与 OAP 服务器版本不匹配 导致的

本地版本

  • aop: apache-skywalking-apm-bin_10.2.0
  • agent: apache-skywalking-apm-9.4.0

Skywalking日志文档: https://skywalking.apache.org/docs/skywalking-java/next/en/setup/service-agent/java-agent/application-toolkit-log4j-2.x/

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词