ELK基本部署

作者: 唯爱熊 | 来源:发表于2019-10-26 18:52 被阅读0次

    ELK简介

    什么是ELK?通俗来讲,ELK是由Elasticsearch、Logstash、Kibana 三个开源软件组成的一个组合体,这三个软件当中,每个软件用于完成不同的功能,ELK又称ELKstack。
    官网 https://www.elastic.co/ , ELK主要优点有如下几个:
    1、处理方式灵活:elasticsearch是实时全文索引,具有强大的搜索功能
    2、配置相对简单:elasticsearch全部使用JSON接口,logstash使用模块配置,kibana的配置文件部分更简单
    3、检索性能高:基于优秀的设计,虽然每次查询都是实时,但是也可以达到百亿级数据的查询秒级响应
    4、集群线性扩展:elasticsearch和logstash都可以灵活线性扩展
    5、前端操作绚丽:kibana的前端设计比较绚丽,而且操作简单

    Elasticserch

    elasticsearch是一个高度可扩展全文搜索和分析引擎,基于Apache Lucene 构建,能对大容量的数据进行接近实时的存储、搜索和分析操作,可以处理大规模日志数据,比如Nginx、Tomcat、系统日志等功能。

    Logstash

    数据收集引擎。它支持动态的从各种数据源搜集数据,并对数据进行过滤、分析、丰富、统一格式等操作,然后存储到用户指定的位置;支持普通log、自定义json格式的日志解析。

    Kibana

    数据分析和可视化平台。通常与 Elasticsearch 配合使用,对其中数据进行搜索、分析和以统计图表的方式展示。

    ELK部署环境准备

    这里建议内存至少3G.


    背景信息

    . 操作系统: CentOS 7.6
    .elasticsearch版本:Elasticsearch-6.8.1
    .logstash版本: Logstash 6.8.1
    .kibana版本:kibana-6.8.1-x86_64
    .插件:elasticsearch-head

    安装前准备

    1.关闭防火墙
    1.1查看防火墙的状态

    [root@elasticsearch1 ~]# systemctl status firewalld.service
    ● firewalld.service - firewalld - dynamic firewall daemon
       Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
       Active: active (running) since Fri 2019-10-25 15:53:56 CST; 32s ago
         Docs: man:firewalld(1)
     Main PID: 7564 (firewalld)
       CGroup: /system.slice/firewalld.service
               └─7564 /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopid
    
    Oct 25 15:53:56 web01 systemd[1]: Starting firewalld - dynamic firewall daemon...
    Oct 25 15:53:56 web01 systemd[1]: Started firewalld - dynamic firewall daemon.
    

    .如果防火墙的状态是inactive,则防火墙为关闭状态。
    .如果防火墙的状态参数为active,则防火墙为开启状态本实例为开启状态,这里需要关闭防护墙。
    1.2关闭防火墙。如果防火墙为关闭状态可以忽略此步骤。
    .如果您想临时关闭防火墙,运行命令systemctl stop firewalld。
    .如果您想永久关闭防火墙,运行命令systemctl disable firewalld。
    2.关闭selinux
    2.1运行命令getenforce查看SELinux的当前状态

    [root@elasticsearch1 ~]# getenforce
    Enforcing
    

    .如果SELinux状态参数是Disabled, 则SELinux为关闭状态。
    .如果SELinux状态参数是Enforcing,则SELinux为开启状态。本示例中SELinux为开启状态,因此需要关闭SELinux。
    2.1.1关闭SELinux。如果SELinux为关闭状态可以忽略此步骤。
    .如果您想临时关闭SELinux,运行命令setenforce 0。
    .如果您想永久关闭SELinux,运行命令vi /etc/selinux/config编辑SELinux配置文件。回车后,把光标移动到SELINUX=enforcing这一行,按i键进入编辑模式,修改为SELINUX=disabled, 按Esc键,然后输入:wq并回车来保存并关闭SELinux配置文件。
    3.重启系统使设置生效

    Elasticsearch部署

    因为elasticsearch服务运行需要java环境,因此两台elasticsearch服务器需要安装Java环境。

    安装JDK

    注意:CentOS7默认是安装了jdk的,如果需要高版本可以使用以下步骤,这里使用yum安装jdk。两个节点都需要 安装。
    方法一:yum安装下载好的JDK包,将下载好的软件包上传到服务器进行安装,首先卸载自带的jdk;再进行安装。
    下载地址:https://pan.baidu.com/s/1VK1iCnvouppZ06jsVBOaRw 提取码:lofc

    [root@elasticsearch1 ~]# rpm -qa |grep jdk |xargs yum -y remove {}\;
    [root@elasticsearch1 ~]#yum -y localinstall jdk-8u211-linux-x64.rpm
    [root@elasticsearch1 ~]#java -version
    java version "1.8.0_211"
    Java(TM) SE Runtime Environment (build 1.8.0_211-b12)
    Java HotSpot(TM) 64-Bit Server VM (build 25.211-b12, mixed mode)
    

    方法二:源码安装JDK,将下载的软件包上传到服务器进行安装。
    下载地址:https://pan.baidu.com/s/1AAPyPzhdclNNCb0m6ooVYQ 提取码:x18u

    [root@elasticsearch1 ~]#tar xf jdk-8u211-linux-x64.tar.gz -C /usr/local/
    [root@elasticsearch1 ~]#ln -s /usr/local/jdk1.8.0_211 /usr/local/java
    [root@elasticsearch1 ~]#sed -i.ori '$a export JAVA_HOME=/usr/local/java \nexport PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH \nexport CLASSPATH=.$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$JAVA_HOME/lib/tools.jar' /etc/profile
    [root@elasticsearch1 ~]# source /etc/profile
    [root@elasticsearch1 ~]#java -version
    java version "1.8.0_211"
    Java(TM) SE Runtime Environment (build 1.8.0_211-b12)
    Java HotSpot(TM) 64-Bit Server VM (build 25.211-b12, mixed mode)
    

    安装Elasticsearch

    两台节点都需要安装elasticsearch,使用yum安装会很慢,所以先下载下来传到服务器进行安装,官网下载地址:https://www.elastic.co/cn/downloads/past-releases#elasticsearch
    本文所使用的包下载:https://pan.baidu.com/s/1djYOs3PQjtq16VkPMETAWg 提取码:b15v

    将下载的elasticsearch包上传到服务器进行安装。
    [root@elasticsearch1 ~]# yum -y localinstall elasticsearch-6.8.1.rpm
    [root@elasticsearch2 ~]# yum -y localinstall elasticsearch-6.8.1.rpm
    
    
    配置elasticsearch,linux-elk2配置一个相同的节点,通过组播进行通信,如果无法通过组播查询,修改成单播即可。
    [root@elasticsearch1 ~]# vim /etc/elasticsearch/elasticsearch.yml
    cluster.name: ELK-Cluster    #ELK的集群名称,名称相同即属于是同一个集群
    node.name: elasticsearch1    #本机在集群内的节点名称
    path.data: /elk/data    #数据存放目录
    path.logs: /elk/logs    #日志保存目录
    bootstrap.memory_lock: true    #服务启动的时候锁定足够的内存,防止数据写入swap
    network.host: 10.0.0.55   #监听的IP地址
    http.port: 9200    #服务监听的端口
    discovery.zen.ping.unicast.hosts: ["10.0.0.55", "10.0.0.56"]    #单播配置一台即可
    
    
    修改内存限制,内存锁定需要进行配置需要2g以上内存,否则会导致无法启动elasticsearch。
    [root@elasticsearch1~]# vim /usr/lib/systemd/system/elasticsearch.service
    # 在[Service]下加入下面这行内容
    LimitMEMLOCK=infinity
    [root@elasticsearch1~]# systemctl daemon-reload
    [root@elasticsearch1 ~]# vim /etc/elasticsearch/jvm.options
    -Xms2g
    -Xmx2g     #最小和最大内存限制,为什么最小和最大设置一样大?参考:https://www.elastic.co/guide/en/elasticsearch/reference/current/heap-size.html
    
    
    创建数据目录和日志目录及权限修改
    [root@elasticsearch1~]# mkdir -p /elk/{data,logs}
    [root@elasticsearch1 ~]# chown elasticsearch.elasticsearch /elk/ -R
    
    
    启动elasticsearch及检查端口是否处于监听状态
    [root@elasticsearch1 ~]# systemctl start elasticsearch
    [root@elasticsearch1 ~]# netstat -nltup |grep java
    tcp6       0      0 10.0.0.55:9200          :::*                    LISTEN      25947/java          
    tcp6       0      0 10.0.0.55:9300          :::*                    LISTEN      25947/java         
    将配置文件copy到elasticsearch2上面并进行修改,配置启动等
    [root@elasticserch2 ~]# scp /etc/elasticsearch/elasticsearch.yml 10.0.0.56:/etc/elasticsearch/elasticsearch.yml
    [root@elasticserch2 ~]# grep ^[a-Z] /etc/elasticsearch/elasticsearch.yml 
    cluster.name: ELK-Cluster
    node.name: elasticsearch2
    path.data: /elk/data
    path.logs: /elk/logs
    bootstrap.memory_lock: true
    network.host: 10.0.0.56
    http.port: 9200
    discovery.zen.ping.unicast.hosts: ["10.0.0.55", "10.0.0.56"]
    [root@elasticserch2 ~]# vim /usr/lib/systemd/system/elasticsearch.service
    在[Service]下加入下面这行内容
    LimitMEMLOCK=infinity
    [root@elasticserch2 ~]# systemctl daemon-reload
    [root@elasticserch2 ~]# vim /etc/elasticsearch/jvm.options
    -Xms2g
    -Xmx2g
    [root@elasticserch2 ~]# mkdir -p /elk/{data,logs}
    [root@elasticserch2 ~]# chown elasticsearch.elasticsearch /elk/ -R
    [root@elasticserch2 ~]# systemctl start elasticsearch
    [root@elasticserch2 ~]# netstat -lntp|grep java
    tcp6       0      0 10.0.0.56:9200          :::*                    LISTEN      7548/java           
    tcp6       0      0 10.0.0.56:9300          :::*                    LISTEN      7548/java    
    

    通过浏览器访问elasticsearch端口



    安装elasticsearch插件head

    我们不可能经常通过命令来查看集群的信息,所以就使用到了插件 –head。插件是为了完成不同的功能,官方提供了一些插件但大部分是收费的,另外也有一些开发爱好者提供的插件,可以实现对elasticsearch集群的状态监控与管理配置等功能。head:主要用来做集群管理的插件

    安装方式有如下三种

    1.npm安装方式

    • 需要nodejs环境
    • 需要连接国外源

    下载地址:https://github.com/mobz/elasticsearch-head
    1.安装

    安装npm和git
    [root@linux-elk1 ~]# yum -y install npm git
    
    安装elasticsearch-head插件
    [root@elasticserch1 ~]# cd /usr/local/src/
    [root@elasticserch1 src]# git clone git://github.com/mobz/elasticsearch-head.git
    [root@elasticserch1 src]# cd elasticsearch-head/
    [root@elasticserch1 elasticsearch-head]# npm install grunt -save --registry=https://registry.npm.taobao.org
    [root@elasticserch1 elasticsearch-head]# ll node_modules/grunt    #确定该目录有生成文件
    总用量 24
    drwxr-xr-x. 2 root root   19 4月   6 2016 bin
    -rw-r--r--. 1 root root 7111 4月   6 2016 CHANGELOG
    drwxr-xr-x. 4 root root   47 7月   4 09:21 lib
    -rw-r--r--. 1 root root 1592 3月  23 2016 LICENSE
    drwxr-xr-x. 5 root root   50 7月   4 09:21 node_modules
    -rw-r--r--. 1 root root 4108 7月   4 09:21 package.json
    -rw-r--r--. 1 root root  878 2月  12 2016 README.md
    [root@elasticserch1 elasticsearch-head]# npm install --registry=https://registry.npm.taobao.org    #执行安装
    [root@elasticserch1 elasticsearch-head]# npm run start &    #后台启动服务
    [root@elasticserch1 ~]# ss -nlt |grep 9100
    LISTEN     0      128          *:9100                     *:* 
    
    补充说明
    由于上面npm安装时候超级慢,使用taobao源同样慢,这里将已安装的打成了包,可以直接下载使用即可
    下载地址:https://pan.baidu.com/s/16zDlecKVfmkEeInPcRx9NQ   提取码:h890
    [root@linux-elk1 ~]# yum -y install npm
    [root@linux-elk1 ~]# cd /usr/local/src/
    [root@linux-elk1 src]# ls
    elasticsearch-head.tar.gz
    [root@linux-elk1 src]# tar xvzf elasticsearch-head.tar.gz
    [root@linux-elk1 src]# cd elasticsearch-head/
    [root@linux-elk1 elasticsearch-head]# npm run start &
    
    
    修改elasticsearch服务配置文件,开启跨域访问支持,然后重启elasticsearch服务
    [root@elasticserch1 ~]# vim /etc/elasticsearch/elasticsearch.yml
    http.cors.enabled: true     #最下方添加
    http.cors.allow-origin: "*"
    

    为了方便管理elasticsearch-head插件,编写一个启动脚本

    [root@elasticserch1 ~]# vim /usr/bin/elasticsearch-head
    #!/bin/bash
    #desc: elasticsearch-head service manager
    #date: 2019
    
    data="cd /usr/local/src/elasticsearch-head/; nohup npm run start > /dev/null 2>&1 & "
    
    function START (){
        eval $data && echo -e "elasticsearch-head start\033[32m     ok\033[0m"
    }
    
    function STOP (){
        ps -ef |grep grunt |grep -v "grep" |awk '{print $2}' |xargs kill -s 9 > /dev/null && echo -e "elasticsearch-head stop\033[32m      ok\033[0m"
    }
    
    case "$1" in
        start)
            START
            ;;
        stop)
            STOP
            ;;
        restart)
            STOP
            sleep 3
            START
            ;;
        *)
            echo "Usage: elasticsearch-head (start|stop|restart)"
            ;;
    esac
    
     [root@elasticserch1 ~]# chmod +x /usr/bin/elasticsearch-head
    

    2.通过浏览器访问9100,将链接地址修改为elasticsearch地址。



    3.测试提交数据


    4.验证索引是否存在

    5.查看数据


    6.master和slave的区别

    Master的职责:
    统计各node节点状态信息、集群状态信息统计、索引的创建和删除、索引分配的管理、关闭node节点等
    Savle的职责:
    同步数据、等待机会称为Master

    2.docker安装

    Head插件在5.0以后安装方式发生了改变,需要nodejs环境支持,或者直接使用别人封装好的docker镜像
    插件官方地址
    https://github.com/mobz/elasticsearch-head

    使用docker部署elasticsearch-head

    docker pull alivv/elasticsearch-head
    docker run --name es-head -p 9100:9100 -dit elivv/elasticsearch-head
    

    3.google浏览器插件

    • 修改文件名为zip后缀
    • 解压目录
    • 拓展程序-开发者模式-打开已解压的目录
    • 连接地址修改为ES的IP地址

    Logstash部署

    Logstash 是一个开源的数据收集引擎,可以水平伸缩,而且logstash是整个ELK当中拥有最多插件的一个组件,其可以接收来自不同来源的数据并同意输出到指定的且可以是多个不同目的地。官网下载地址:https://www.elastic.co/cn/downloads/past-releases#logstash

    安装JDK

    方法与之前的安装方法一致,这里不再重复,请参考之前的步骤操作即可!

    安装logstash

    [root@logstash ~]# wget https://artifacts.elastic.co/downloads/logstash/logstash-6.8.1.rpm
    [root@logstash ~]# yum -y localinstall logstash-6.8.1.rpm
    #给Logstash目录授权
    [root@logstash ~]# chown -R logstash.logstash /usr/share/logstash/
    

    kibana部署

    Kibana是一个通过调用elasticsearch服务器进行图形化展示搜索结果的开源项目。官网下载地址:https://www.elastic.co/cn/downloads/past-releases#kibana

    安装kibana

    [root@kibana ~]# wget https://artifacts.elastic.co/downloads/kibana/kibana-6.8.1-x86_64.rpm
    [root@kibana ~]# yum -y localinstall kibana-6.8.1-x86_64.rpm
    [root@kibana ~]# vim /etc/kibana/kibana.yml 
    [root@kibana ~]# grep ^[a-Z] /etc/kibana/kibana.yml 
    server.port: 5601    #监听端口
    server.host: "192.168.1.55"    #监听地址
    elasticsearch.hosts: ["http://192.168.1.55:9200"]    #elasticsearch服务器地址
    i18n.locale: "zh-CN"    #修改为中文
    

    启动kibana

    [root@kibana ~]# systemctl start kibana
    [root@kibana ~]# systemctl enable kibana
    Created symlink from /etc/systemd/system/multi-user.target.wants/kibana.service to /etc/systemd/system/kibana.service.
    [root@kibana ~]# ss -nlt  |grep 5601
    LISTEN     0      128    10.0.0.57:5601                     *:*        
    

    查看状态

    通过logstash收集nginx的访问日志

    这里为了方便测试在logstash这台服务器上安装nginx。
    1.安装nginx并设置默认首页

    [root@logstash ~]# yum -y install nginx
    [root@logstash ~]# echo "<h1>whelcom to nginx server</h1>" > /usr/share/nginx/html/index.html
    [root@logstash ~]# systemctl start nginx 
    [root@logstash ~]# curl localhost
    <h1>whelcom to nginx server</h1>
    

    2.设置nginx日志为json格式

    [root@logstash ~]# vim /etc/nginx/nginx.conf
    user  nginx;
    worker_processes  1;
    
    error_log  /var/log/nginx/error.log warn;
        include       /etc/nginx/mime.types;
        default_type  application/octet-stream;
    
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
    
        access_log  /var/log/nginx/access.log  main;
        log_format access_json '{"@timestamp":"$time_iso8601",'
                '"host":"$server_addr",'
                '"clientip":"$remote_addr",'
                '"size":$body_bytes_sent,'
                '"responsetime":$request_time,'
                '"upstreamtime":"$upstream_response_time",'
                '"upstreamhost":"$upstream_addr",'
                '"http_host":"$host",'
                '"url":"$uri",'
                '"domain":"$host",'
                '"xff":"$http_x_forwarded_for",'
                '"referer":"$http_referer",'
                '"status":"$status"}';
        access_log  /var/log/nginx/access_json.log  access_json;
    [root@logstash /var/log/nginx]# nginx -t
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful
    [root@logstash /var/log/nginx]# systemctl restart nginx
    [root@logstash /var/log/nginx]# ls
    access_json.log  access.log  error.log
    

    3.访问测试并查看日志文件是否生成



    4.配置logstash配置文件

    [root@logstash ~]# cd /etc/logstash/conf.d/
    [root@logstash conf.d]#conf.d]# cat nginx_log.conf 
    input {
      file {
        path => "/var/log/nginx/access_json.log"       #日志存放路径目录
        type => "nginx_log"                            #日志类型
        start_position => "beginning"                  #从一开始就收集
        stat_interval => "3"                           #每个三秒收集一次
      }
    }
    output {
        elasticsearch {                                #输出到ES中
          hosts => ["10.0.0.55:9200"]                  #ES的主机名端口
          index => "%{type}_%{+YYYY.MM.dd}"            #输出的日志文件名
        }
    }
    #生成logstash.service启动文件
    [root@logstash ~]# /usr/share/logstash/bin/system-install /etc/logstash/startup.options systemd
    #启动logstash
    [ root@logstash ]# systemctl start logstash.service
    

    5.访问elasticsearch插件查看数据




    6.在kibana添加索引模式




    7.kibana验证收集的日志数据

    收集Tomcat日志

    收集Tomcat服务器的访问日志以及Tomcat错误日志进行实时统计,在kibana页面进行搜索展示,每台Tomcat服务器需要安装logstash负责收集日志,然后将日志发给elasticsearch进行分析,在通过kibana在前端展示。

    部署tomcat

    注意:这里新建一台服务器将jdk,logstash和Tomcat全部安装在这台服务新的服务器上,这里只需额外展示安装Tomcat,其他与之前的安装的一样。
    1.下载并安装Tomcat

    [root@tomcat ~]# wget http://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-9/v9.0.27/bin/apache-tomcat-9.0.27.tar.gz
    [root@tomcat ~]# mv apache-tomcat-9.0.27.tar.gz /usr/local/
    [root@tomcat ~]# cd /usr/local/
    [root@tomcat /usr/local]# tar zxf apache-tomcat-9.0.27.tar.gz
    [root@tomcat /usr/local]# ln -s /usr/local/apache-tomcat-9.0.27 /usr/local/tomcat
    

    2.设置默认首页

    [root@tomcat /usr/local]# cd tomcat/webapps/
    [root@tomcat /usr/local/tomcat/webapps]# mkdir web
    [root@tomcat /usr/local/tomcat/webapps]# echo "<h1>Welcome to Tomcat</h1>"  > /usr/local/tomcat/webapps/web/index.html
    

    3.设置Tomcat日志格式为json

    [root@tomcat /usr/local/tomcat]# vim /usr/local/tomcat/conf/server.xml
            <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
                   prefix="localhost_access_log" suffix=".log"
                   pattern="{&quot;clientip&quot;:&quot;%h&quot;,&quot;ClientUser&quot;:&quot;%l&quot;,&quot;authenticated&quot;:&quot;%u&quot;,&quot;AccessTime&quot;:&quot;%t&quot;,&quot;method&quot;:&quot;%r&quot;,&quot;status&quot;:&quot;%s&quot;,&quot;SendBytes&quot;:&quot;%b&quot;,&quot;Query?string&quot;:&quot;%q&quot;,&quot;partner&quot;:&quot;%{Referer}i&quot;,&quot;AgentVersion&quot;:&quot;%{User-Agent}i&quot;}"/>
    

    4.启动tomcat,并进行访问测试生成日志

    [root@tomcat /usr/local/tomcat]# /usr/local/tomcat/bin/startup.sh
    Using CATALINA_BASE:   /usr/local/tomcat
    Using CATALINA_HOME:   /usr/local/tomcat
    Using CATALINA_TMPDIR: /usr/local/tomcat/temp
    Using JRE_HOME:        /usr
    Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
    Tomcat started.
    [root@tomcat /usr/local/tomcat]# netstat -lntp|grep 8080
    tcp6       0      0 :::8080                 :::*                    LISTEN      13070/java       
    

    5.验证日志是否为json格式,http://www.kjson.com/

    配置logstash收集Tomcat日志

    注意:如果是需要收集别的服务器上面的tomcat日志,那么在所需要收集的服务器上面都得安装logstash。
    1.配置logstash

    [root@tomcat ~]#  vim /etc/logstash/conf.d/tomcat.conf
    input {
        file {
            path => "/usr/local/tomcat/logs/localhost_access_log.*.log"
            type => "tomcat-access-log"
            start_position => "beginning"
            stat_interval => "2"
        }
    }
    
    output {
        elasticsearch {
            hosts => ["10.0.0.55:9200"]
            index => "logstash-tomcat-132-accesslog-%{+YYYY.MM.dd}"
        }
        file {
            path => "/tmp/logstash-tomcat-132-accesslog-%{+YYYY.MM.dd}"
        }
    }
    

    2.授权,检测配置的文件语法并启动logstash

    #配置权限
    root@tomcat /etc/logstash/conf.d]# chown -R logstash.logstash /usr/share/logstash/
    [root@tomcat /etc/logstash/conf.d]# chown logstash.logstash /usr/local/tomcat/logs/ -R
    #语法检测
    [root@tomcat /etc/logstash/conf.d]# /usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/tomcat.conf -t
    #启动
    [root@tomcat ~]# /usr/share/logstash/bin/system-install /etc/logstash/startup.options systemd
    [root@tomcat ~]# systemctl start logstash
    

    3.访问elasticsearch界面验证插件




    4.在kibana设置索引模式




    5.kibana验证收集的日志数据

    相关文章

      网友评论

        本文标题:ELK基本部署

        本文链接:https://www.haomeiwen.com/subject/saduvctx.html