带有ELK的SpringBoot项目启动异常

简介: 本文基于ELK框架构建SpringBoot应用,实现Elasticsearch查询与日志管理。启动报错“Process finished with exit code 1”,经排查为ES启用xpack安全认证(SSL+用户密码)后,SpringBoot未配置相应连接参数所致。通过自定义ElasticConfig集成SSL上下文、证书指纹校验及基础认证,成功解决连接关闭异常,确保ELK组件协同工作。

注:本文的项目使用ELK框架,实现两个功能:

1.Elasticsearch实现查询

2.ELK实现日志管理

在编写完带有ELK的SpringBoot项目后,启动发现控制台无输出直接

Process finished with exit code 1

springboot启动异常1.png

为了找到原因,尝试了给启动类try catch的方式:

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        try {
            SpringApplication.run(DemoApplication.class, args);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

结果输出:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'taskController': Unsatisfied dependency expressed through field 'taskService': Error creating bean with name 'taskService': Unsatisfied dependency expressed through field 'esTaskRepository': Error creating bean with name 'esTaskRepository' defined in com.test.simpleLoginRegister.repository.EsTaskRepository defined in @EnableElasticsearchRepositories declared on ElasticsearchRepositoriesRegistrar.EnableElasticsearchRepositoriesConfiguration: Failed to instantiate [org.springframework.data.elasticsearch.repository.support.SimpleElasticsearchRepository]: Constructor threw exception
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:788)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:768)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:146)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:509)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1445)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:523)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:339)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:347)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:337)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.instantiateSingleton(DefaultListableBeanFactory.java:1155)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingleton(DefaultListableBeanFactory.java:1121)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:1056)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:987)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:627)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:318)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1361)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1350)
    at com.test.simpleLoginRegister.SpringTestApplication.main(SpringTestApplication.java:11)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'taskService': Unsatisfied dependency expressed through field 'esTaskRepository': Error creating bean with name 'esTaskRepository' defined in com.test.simpleLoginRegister.repository.EsTaskRepository defined in @EnableElasticsearchRepositories declared on ElasticsearchRepositoriesRegistrar.EnableElasticsearchRepositoriesConfiguration: Failed to instantiate [org.springframework.data.elasticsearch.repository.support.SimpleElasticsearchRepository]: Constructor threw exception
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:788)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:768)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:146)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:509)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1445)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:523)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:339)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:347)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:337)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1609)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1555)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:785)
    ... 22 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'esTaskRepository' defined in com.test.simpleLoginRegister.repository.EsTaskRepository defined in @EnableElasticsearchRepositories declared on ElasticsearchRepositoriesRegistrar.EnableElasticsearchRepositoriesConfiguration: Failed to instantiate [org.springframework.data.elasticsearch.repository.support.SimpleElasticsearchRepository]: Constructor threw exception
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1812)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:601)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:523)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:339)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:347)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:337)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1609)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1555)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:785)
    ... 35 more
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.elasticsearch.repository.support.SimpleElasticsearchRepository]: Constructor threw exception
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:222)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.lambda$instantiateClass$5(RepositoryFactorySupport.java:657)
    at java.base/java.util.Optional.map(Optional.java:260)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.instantiateClass(RepositoryFactorySupport.java:657)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.getTargetRepositoryViaReflection(RepositoryFactorySupport.java:622)
    at org.springframework.data.elasticsearch.repository.support.ElasticsearchRepositoryFactory.getTargetRepository(ElasticsearchRepositoryFactory.java:80)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:377)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$4(RepositoryFactoryBeanSupport.java:350)
    at org.springframework.data.util.Lazy.getNullable(Lazy.java:135)
    at org.springframework.data.util.Lazy.get(Lazy.java:113)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:356)
    at org.springframework.data.elasticsearch.repository.support.ElasticsearchRepositoryFactoryBean.afterPropertiesSet(ElasticsearchRepositoryFactoryBean.java:69)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1859)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1808)
    ... 44 more
Caused by: org.springframework.dao.DataAccessResourceFailureException: Connection is closed
    at org.springframework.data.elasticsearch.client.elc.ElasticsearchExceptionTranslator.translateExceptionIfPossible(ElasticsearchExceptionTranslator.java:111)
    at org.springframework.data.elasticsearch.client.elc.ElasticsearchExceptionTranslator.translateException(ElasticsearchExceptionTranslator.java:65)
    at org.springframework.data.elasticsearch.client.elc.ChildTemplate.execute(ChildTemplate.java:73)
    at org.springframework.data.elasticsearch.client.elc.IndicesTemplate.doExists(IndicesTemplate.java:179)
    at org.springframework.data.elasticsearch.client.elc.IndicesTemplate.exists(IndicesTemplate.java:171)
    at org.springframework.data.elasticsearch.repository.support.SimpleElasticsearchRepository.createIndexAndMappingIfNeeded(SimpleElasticsearchRepository.java:93)
    at org.springframework.data.elasticsearch.repository.support.SimpleElasticsearchRepository.<init>(SimpleElasticsearchRepository.java:87)
    at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:67)
    at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:483)
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:209)
    ... 57 more
Caused by: java.lang.RuntimeException: Connection is closed
    at org.springframework.data.elasticsearch.client.elc.ElasticsearchExceptionTranslator.translateException(ElasticsearchExceptionTranslator.java:64)
    ... 66 more
Caused by: org.apache.http.ConnectionClosedException: Connection is closed
    at org.elasticsearch.client.RestClient.extractAndWrapCause(RestClient.java:924)
    at org.elasticsearch.client.RestClient.performRequest(RestClient.java:304)
    at org.elasticsearch.client.RestClient.performRequest(RestClient.java:292)
    at co.elastic.clients.transport.rest_client.RestClientHttpClient.performRequest(RestClientHttpClient.java:91)
    at co.elastic.clients.transport.ElasticsearchTransportBase.performRequest(ElasticsearchTransportBase.java:144)
    at co.elastic.clients.elasticsearch.indices.ElasticsearchIndicesClient.exists(ElasticsearchIndicesClient.java:682)
    at org.springframework.data.elasticsearch.client.elc.IndicesTemplate.lambda$doExists$2(IndicesTemplate.java:179)
    at org.springframework.data.elasticsearch.client.elc.ChildTemplate.execute(ChildTemplate.java:71)
    ... 65 more
Caused by: org.apache.http.ConnectionClosedException: Connection is closed
    at org.apache.http.nio.protocol.HttpAsyncRequestExecutor.endOfInput(HttpAsyncRequestExecutor.java:356)
    at org.apache.http.impl.nio.client.InternalRequestExecutor.endOfInput(InternalRequestExecutor.java:132)
    at org.apache.http.impl.nio.DefaultNHttpClientConnection.consumeInput(DefaultNHttpClientConnection.java:261)
    at org.apache.http.impl.nio.client.InternalIODispatch.onInputReady(InternalIODispatch.java:87)
    at org.apache.http.impl.nio.client.InternalIODispatch.onInputReady(InternalIODispatch.java:40)
    at org.apache.http.impl.nio.reactor.AbstractIODispatch.inputReady(AbstractIODispatch.java:114)
    at org.apache.http.impl.nio.reactor.BaseIOReactor.readable(BaseIOReactor.java:162)
    at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent(AbstractIOReactor.java:337)
    at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents(AbstractIOReactor.java:315)
    at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:276)
    at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:104)
    at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:591)
    at java.base/java.lang.Thread.run(Thread.java:833)

检查发现问题出自在ES上,回忆ES的配置过程,发现ES启用了 xpack 安全性和 SSL,因此需要在 Spring Boot 的配置文件中添加相应的设置。

Spring Boot 配置

如果ELK架构是正常运行的,建议依据Logstash的配置来编写Spring Boot 配置

比如我的Logstash配置的结构,可以依据Logstash配置了什么选项,然后去Spring Boot进行 配置:

output {
  elasticsearch {
    hosts => ["localhost:9200"]
    user => ""
    password => ""
    ssl_enabled => true
    ssl_verification_mode => full
    ca_trusted_fingerprint => ""
    index => "app-logs-%{+YYYY.MM.dd}"
  }

}

配置参考(仅参考,与上文的Logstash配置不是对应关系):

1.在 application.ymlapplication.properties 中添加以下配置:

使用 application.yml

# Elasticsearch配置
spring:
  elastic:
    host: localhost:9200
    user: elastic
    password: 123
    fingerprint: 123
# 禁用默认的自动配置
data:
  elasticsearch:
    enabled: false

使用 application.properties

# Elasticsearch配置
spring.elastic.host=localhost:9200
spring.elastic.user=elastic
spring.elastic.password=123
spring.elastic.fingerprint=123
# 禁用默认的自动配置
data.elasticsearch.enabled=false

编写ElasticConfig

@Configuration
public class ElasticConfig extends ElasticsearchConfiguration {

    @Value("${spring.elastic.host}")
    private String host;

    @Value("${spring.elastic.user}")
    private String user;

    @Value("${spring.elastic.password}")
    private String password;

    @Value("${spring.elastic.fingerprint}")
    private String fingerprint;

    @Override
    public ClientConfiguration clientConfiguration() {
        SSLContext sslContext;
        try {
            sslContext = buildSslContext();
        } catch (Exception e) {
            throw new RuntimeException("Failed to create SSL context", e);
        }

        HttpHeaders headers = new HttpHeaders();
        headers.setBasicAuth(user, password);

        return ClientConfiguration.builder()
                .connectedTo(host)
                .usingSsl(sslContext)
                .withDefaultHeaders(headers)
                .withBasicAuth(user, password)
                .withSocketTimeout(60_000)
                .build();
    }

    private SSLContext buildSslContext() throws Exception {
        return SSLContextBuilder.create()
                .loadTrustMaterial(new TrustSelfSignedStrategy() {
                    @Override
                    public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                        if (chain == null || chain.length == 0) {
                            throw new CertificateException("Certificate chain is empty");
                        }

                        // 只验证叶子证书(第一个证书)
                        X509Certificate leafCert = chain[0];
                        try {
                            String actualFingerprint = getSha256Fingerprint(leafCert);
                            if (!fingerprint.equalsIgnoreCase(actualFingerprint)) {
                                throw new CertificateException("Certificate fingerprint mismatch. Expected: "
                                        + fingerprint + ", Actual: " + actualFingerprint);
                            }
                        } catch (NoSuchAlgorithmException | CertificateEncodingException e) {
                            throw new CertificateException("Failed to calculate fingerprint", e);
                        }
                        return true;
                    }
                })
                .build();
    }

    private String getSha256Fingerprint(X509Certificate cert)
            throws NoSuchAlgorithmException, CertificateEncodingException {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        byte[] der = cert.getEncoded();
        md.update(der);
        byte[] digest = md.digest();
        return bytesToHex(digest);
    }

    private String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }
}
相关实践学习
以电商场景为例搭建AI语义搜索应用
本实验旨在通过阿里云Elasticsearch结合阿里云搜索开发工作台AI模型服务,构建一个高效、精准的语义搜索系统,模拟电商场景,深入理解AI搜索技术原理并掌握其实现过程。
ElasticSearch 最新快速入门教程
本课程由千锋教育提供。全文搜索的需求非常大。而开源的解决办法Elasricsearch(Elastic)就是一个非常好的工具。目前是全文搜索引擎的首选。本系列教程由浅入深讲解了在CentOS7系统下如何搭建ElasticSearch,如何使用Kibana实现各种方式的搜索并详细分析了搜索的原理,最后讲解了在Java应用中如何集成ElasticSearch并实现搜索。 &nbsp;
相关文章
|
7天前
|
人工智能 自然语言处理 搜索推荐
蚂蚁百宝箱正式发布AI构建能力:自然语言一键生成企业级智能体,助力业务创新提效
5月21日,蚂蚁百宝箱上线全新AI构建能力,支持自然语言一键生成智能体、营销活动与场景化Skill,深度融合行业资产与工程化能力,零代码、高可用、可交付。新用户注册即赠海量tokens,速体验!
147 2
|
25天前
|
人工智能 API iOS开发
阿里云/本地零基础喂饭级部署 Hermes Agent / OpenClaw +配置免费大模型API+集成Obsidian CLI,让AI用你的知识库创作
2026年,个人知识库的价值已从“个人备忘”升级为“AI创作资产”——Obsidian凭借本地Markdown存储、双向链接、标签体系,成为知识管理的首选工具,但长期以来存在一个核心痛点:AI Agent(如OpenClaw)无法高效复用这些精心整理的知识。传统方案需将笔记向量化存入向量数据库,不仅丢失笔记结构与关系,还存在检索不透明、维护复杂等问题。
444 0
|
26天前
|
缓存 安全 搜索推荐
[004][缓存模块]Caffeine缓存自定义:构建灵活的Spring Boot缓存管理器
本文介绍Spring Boot中Caffeine缓存的灵活定制方案:通过自定义`FlexibleCaffeineCacheManager`,支持按缓存名(如users/products)独立配置过期策略、容量等参数,兼顾全局默认与个性化需求;结合线程安全创建器、属性合并机制及无缝Spring集成,实现高性能、易扩展、零侵入的本地缓存管理。(239字)
93 2
|
4月前
|
数据采集 人工智能 自然语言处理
Agentic Search: AI驱动的下一代企业搜索
Agentic Search是阿里云OpenSearch推出的AI搜索新范式,以智能体(Agent)为核心,融合深度检索、多步推理、工具调用与多模态理解,实现从“被动响应”到“主动执行”的跃迁。支持对话、规划、自适应三模式,覆盖问答、研究、客服、报告生成等全场景,助力企业知识库升级为动态业务引擎。
1264 2
Agentic Search: AI驱动的下一代企业搜索
|
20天前
|
存储 人工智能 前端开发
不写框架、不用 npm,我用 AI Coding 做了一个家庭记忆站
大佬勿进!新手向,手把手带你从零做站点:妈妈再也不用担心我会忘记和她之间的温馨小故事了。
184 3
|
20天前
|
JSON 测试技术 API
别再卷提示词了,真正的护城河是你的私有Skill库
本文揭示AI工程化新趋势:提示词工程师岗位正快速消亡,真正壁垒在于构建私有Skill库。Skill将高频决策固化为可复用、带容错的低代码资产,深度绑定业务逻辑与私有配置,难以复制。文章对比OpenClaw、Cursor、Claude Code策略,提供从0到1建设路径,并指出三年后团队核心竞争力源于对业务的理解与Skill化沉淀。
|
5月前
|
监控 Java Serverless
1TB数据,ES却收到了2TB?揪出那个客户端中的“隐形复读机”
揭秘日志服务中的“隐形复读机”:客户端因非抢先认证导致数据重复发送,带宽消耗翻倍。通过优化鉴权配置或使用Serverless监控,可轻松定位并节省50%流量成本。
733 4
|
5天前
|
人工智能 监控 前端开发
学习AI Agent编程-第二天-LangGraph ReAct模式实现
本文介绍了LangChain中ReAct(推理-行动)模式的实践应用:通过“会议室申请”流程,演示LLM如何循环执行“决策→调用工具→评估结果→调整策略”,实现多步任务自动化。代码涵盖流程定义、工具函数与多轮会话测试,验证了其在空闲检查、报备审批、异常处理等场景的可靠性。(239字)
131 7
学习AI Agent编程-第二天-LangGraph ReAct模式实现
|
10天前
|
机器学习/深度学习 自然语言处理 C++
大模型应用:大模型实测对比:1.8B vs 6B,本地部署的极限拉扯与真实体感.119
本文对比Qwen1.5-1.8B与ChatGLM2-6B两大中文大模型:前者轻量易部署,CPU即可运行,代码简洁,但易幻觉、指令遵循弱;后者参数量大,中文理解与逻辑更强,但需GPU、加载复杂。二者代表“小而美”与“大而全”的典型路径。
189 2
大模型应用:大模型实测对比:1.8B vs 6B,本地部署的极限拉扯与真实体感.119
|
18天前
|
运维 Java 开发者
[015][web模块]基于Spring Boot的HTTP客户端日志与默认配置实战
本文详解基于Spring Boot的HTTP客户端统一配置方案,支持RestTemplate、RestClient与WebClient三种客户端,实现无侵入的日志记录(请求/响应头、状态码)、默认请求头注入(如X-Request-Id)、非2xx异常自动转换及链路追踪支持,全部通过Customizer与Filter机制自动装配,开箱即用,提升微服务调用可观测性与开发效率。(239字)
150 5
[015][web模块]基于Spring Boot的HTTP客户端日志与默认配置实战

热门文章

最新文章