zabbix的安装与部署(proxy、睿象云)

一、简介

zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案。
zabbix能监视各种网络参数,保证服务器系统的安全运营;并提供灵活的通知机制以让系统管理员快速定位/解决存在的各种问题。
zabbix由2部分构成,zabbix server与可选组件zabbix agent。
zabbix server可以通过SNMP,zabbix agent,ping,端口监视等方法提供对远程服务器/网络状态的监视,数据收集等功能,它可以运行在Linux,Solaris,HP-UX,AIX,Free BSD,Open BSD,OS X等平台上。
Zabbix 软件能够监控众多网络参数和服务器的健康度、完整性。Zabbix 使用灵活的告警机制,允许用户为几乎任何事件配置基于邮件的告警。这样用户可以快速响应服务器问题。Zabbix 基于存储的数据提供出色的报表和数据可视化功能。这些功能使得 Zabbix 成为容量规划的理想选择。
Zabbix 支持主动轮询(polling)和被动捕获(trapping)。Zabbix所有的报表、统计数据和配置参数都可以通过基于 Web 的前端页面进行访问。基于 Web 的前端页面确保您可以在任何地方访问您监控的网络状态和服务器健康状况。适当的配置后,Zabbix 可以在监控 IT 基础设施方面发挥重要作用。无论是对于有少量服务器的小型组织,还是拥有大量服务器的大企业而言,同样适用。

二、安装配置

官网按官网步骤来即可
这里用的是4.0版本

1.添加 Zabbix 软件仓库

RHEL 7:

[root@server1~]# rpm -ivh http://repo.zabbix.com/zabbix/4.0/rhel/7/x86_64/zabbix-release-4.0-1.el7.noarch.rpm

下载之后的到一个zabbix的yum源
由于官网上下载速度较慢,所以用阿里云的链接,repo配置如下

[zabbix]
name=Zabbix Official Repository - $basearch
baseurl=https://mirrors.aliyun.com/zabbix/zabbix/4.0/rhel/7/x86_64/
enabled=1
gpgcheck=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-ZABBIX-A14FE591

[zabbix-non-supported]
name=Zabbix Official Repository non-supported - $basearch
baseurl=https://mirrors.aliyun.com/zabbix/non-supported/rhel/7/x86_64/
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-ZABBIX
gpgcheck=0

2.安装配置Server后端

[root@server1 yum.repos.d]# yum install zabbix-server-mysql  
[root@server1 yum.repos.d]# yum install -y mariadb-server
[root@server1 ~]# systemctl enable --now mariadb.service

3.创建数据库

mysql

字符集utf8和utf8_bin排序规则是Zabbix服务器与MySQL数据库一起正常工作所必需的。

[root@server1~ ] # mysql
mysql> create database zabbix character set utf8 collate utf8_bin;
mysql> create user 'zabbix'@'localhost' identified by 'westos';
mysql> grant all privileges on zabbix.* to 'zabbix'@'localhost';
mysql> quit;

4.导入数据

使用 MySQL 来导入 Zabbix server 的初始数据库 schema 和数据,

cd /usr/share/doc/zabbix-server-mysql-4.0.27/
zcat create.sql.gz | mysql -uzabbix -pwestos zabbix

在这里插入图片描述

5.为 Zabbix server 配置数据库

编辑 zabbix_server.conf 文件以使用已创建的数据库。

# vim /etc/zabbix/zabbix_server.conf
DBHost=localhost
DBName=zabbix
DBUser=zabbix
DBPassword=password

在 DBPassword 参数中输入由 MySQL创建的 Zabbix 数据库密码。

6.启动 Zabbix server 进程

运行以下命令以启动 Zabbix server 进程:

扫描二维码关注公众号,回复: 12569215 查看本文章
systemctl enable --now zabbix-server
netstat -antlp
查询端口是否开启

在这里插入图片描述

7.安装 Agent

运行以下命令以安装 Zabbix agent

yum install zabbix-agent -y
systemctl enable --now zabbix-agent

8.ZABBIX 前端配置

yum install php -y   要看清版本,安装与zabbix匹配的版本,依赖性可以在阿里云里找,要与所安装的php版本相对应
yum install zabbix-web-mysql php-bcmath-5.4.16-46.el7.x86_64.rpm php-mbstring-5.4.16-46.el7.x86_64.rpm -y

对于 RHEL 7 和更高版本,Zabbix 前端的 Apache 配置文件位于 /etc/httpd/conf.d/zabbix.conf。
虽然已经配置了一些 PHP 参数。但是有必要取消 “date.timezone” 注释,并为其 设置正确的时区 。

[root@server1 ~]# vim /etc/httpd/conf.d/zabbix.conf
[root@server1 ~]# systemctl enable --now httpd

在这里插入图片描述

到这里我们后端前端就已经配置完成了,下面开始测试
在网页上访问http://172.25.1.1/zabbix
在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里我们可以看到当转化为中文语言时,会出现中文乱码的问题,下面我们来解决这个问题
下载好的字体文件 simkai.ttf
链接:simkai字体包 提取码: a5dn

[root@server1 ~] # mv /root/simkai.ttf /usr/share/zabbix/assets/fonts
[root@server1 ~]# vim /usr/share/zabbix/include/defines.inc.php

在这里插入图片描述
这里将全文的原来的graphfont换成simkai字体
在这里插入图片描述在这里插入图片描述

三、新建主机

1.安装Agent

在server2上我们安装angent
我们直接将yum源传给server2

[root@server1 yum.repos.d]# scp zabbix.repo server2:/etc/yum.repos.d/
[root@server2 ~]# yum install zabbix-agent.x86_64 -y
[root@server2 ~]# systemctl enable --now zabbix-agent.service 

2.修改配置文件

[root@server2 ~]# vim /etc/zabbix/zabbix_agentd.conf 
[root@server2 ~]# systemctl restart zabbix-agent.service

共修改3个位置,如下图
在这里插入图片描述
在这里插入图片描述
查询以下端口

[root@server2 ~]# netstat -antlp

在这里插入图片描述

3.手动添加主机

当我们查看日志时显示not found,所以我们需要手动在zabbix web 页面添加
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
选择模板信息
在这里插入图片描述
当出现下图这种状态时,查看图形有数据信息说明添加成功,
在这里插入图片描述
在这里插入图片描述

4 自动添加主机

现在我们再配置一台Agent serve3 ,配置方法同server2相同
这里我们直接到添加环节
(一)自动发现
动作–>自动发现–>启动
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

然后我们去主机那查看,我们可以看到server3已经在主机群组中了
在这里插入图片描述
(二)自动注册
我们为了节省资源,就直接将刚才添加的server3删除掉,然后将自动发现的规则停用
现在测试自动注册
动作–>自动注册–>动作主机名–>操作–>与添加到主机群组添加与模块关联
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我们去主机那查看是否添加成功,如果没有出现,重启以下服务即可
在这里插入图片描述

四、使用API

1.API介绍

Zabbix API允许你以编程方式检索和修改Zabbix的配置,并提供对历史数据的访问。它广泛用于:
创建新的应用程序以使用Zabbix;
将Zabbix与第三方软件集成;
自动执行常规任务。
Zabbix API是基于Web的API,作为Web前端的一部分提供。它使用JSON-RPC 2.0协议,这意味着两件事:
该API包含一组独立的方法;
客户端和API之间的请求和响应使用JSON格式进行编码。

2.结构

Zabbix API由许多名义上分组的独立API方法组成。每个方法执行一个特定任务。例如,方法 host.create 隶属于 host 这个API分组 ,用于创建新主机。历史上,API分组有时被称为“类”。

大多数API至少包含四种方法: get, create, update 和 delete ,分别是检索,创建,更新和删除数据,但是某些API提供一套完全不同的一组方法。

3.执行请求

当完成了前端的安装配置后,你就可以使用远程HTTP请求来调用API。为此,需要向 api_jsonrpc.php 位于前端目录中的文件发送HTTP POST请求。例如,如果你的Zabbix前端安装在 http://company.com/zabbix, 那么用HTTP请求来调用 apiinfo.version 方法就如下面这样:

在访问Zabbix中的任何数据之前,你需要登录并获取身份验证令牌。这可以使用该 user.login 方法完成。让我们假设你想要以标准Zabbix Admin用户身份登录。然后,你的JSON请求将如下所示:

[root@server1 ~]# curl -XPOST http://172.25.1.1/zabbix/api_jsonrpc.php -H "Content-Type: application/json-rpc" -d '
{
    "jsonrpc": "2.0",
    "method": "user.login",
    "params": {
        "user": "Admin",
        "password": "zabbix"
    },
    "id": 1,
    "auth": null
}' | python -m json.tool

让我们仔细看看示例请求对象。它具有以下属性:
jsonrpc - API使用的JSON-RPC协议的版本; Zabbix API实现的JSON-RPC版本是2.0;
method - 被调用的API方法名;
params - 将被传递给API方法的参数;
id - 请求的任意标识符;
auth -用户认证令牌; 因为我们还没有一个,它的设置null。
如果你正确提供了凭据,API返回的响应将包含用户身份验证令牌:
在这里插入图片描述

4.检索主机

[root@server1 ~]# vim zabbix.api
curl -XPOST http://172.25.1.1/zabbix/api_jsonrpc.php -H "Content-Type: application/json-rpc" -d '
{
    "jsonrpc": "2.0",
    "method": "host.get",
    "params": {
        "output": [
            "hostid",
            "host"
        ],
        "selectInterfaces": [
            "interfaceid",
            "ip"
        ]
    },
    "id": 1,
    "auth":"09dc3830f5e6780328c9f4a6fc60c503"
}' | python -m json.tool

在这里插入图片描述在这里插入图片描述

5. 删除主机

object host.delete(array hosts)

该方法允许删除主机

参数
(array) 要删除的主机的ID.

curl -XPOST http://172.25.1.1/zabbix/api_jsonrpc.php -H "Content-Type: application/json-rpc" -d '
{
    "jsonrpc": "2.0",
    "method": "host.delete",
    "params": [
        "10275"
    ],
    "id": 1,
    "auth":"09dc3830f5e6780328c9f4a6fc60c503"
}' | python -m json.tool

快速查询hostid ,直接点开主机,在网址中就可以找到
在这里插入图片描述
返回值,响应值
在这里插入图片描述
在WEB页面我们可以看到server3已经成功删除

6.创建主机

描述
对象 host.create(对象/数组 hosts)

这个方法可以用来创建主机.

curl -s -XPOST http://172.25.3.1/zabbix/api_jsonrpc.php -H "Content-Type: application/json-rpc" -d '
{
    "jsonrpc": "2.0",
    "method": "host.create",
    "params": {
        "host": "server3",
        "interfaces": [
            {
                "type": 1,
                "main": 1,
                "useip": 1,
                "ip": "172.25.1.3",
                "dns": "",
                "port": "10050"
            }
        ],
        "groups": [
            {
                "groupid": "2"
            }
        ],
        "templates": [
            {
                "templateid": "10001"
            }
        ]
    },
    "auth": "09dc3830f5e6780328c9f4a6fc60c503",
    "id": 1
}' | python -m json.tool

groupid查询方法
在这里插入图片描述
templateid查询方法:
在这里插入图片描述
返回直
在这里插入图片描述
在web页面查看server3是否添加成功
在这里插入图片描述

五、zabbix server 的nginx监控

1.搭建nginx

链接: nginx包 提取码: vuck

[root@server3 ~]# tar nginx-1.18.0.tar.gz
[root@server3 ~]# tar zxf nginx-1.18.0.tar.gz
[root@server3 nginx-1.18.0]# yum install gcc pcre-devel opensll-devel -y
[root@server3 nginx-1.18.0]# vim auto/cc/gcc
将debug下面注释掉,最小安装,节省资源
[root@server3 nginx-1.18.0]# ./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module --with-file-aio
[root@server3 nginx-1.18.0]# make
[root@server3 nginx-1.18.0]# make install
[root@server3 sbin]# ln -s /usr/local/nginx/sbin/nginx /usr/local/bin/
[root@server3 sbin]# vim /usr/local/nginx/conf/nginx.conf
        location /status {
                stub_status on;
                access_log off;
                allow 127.0.0.1;
                deny all;
}
为了测试,加这个模块
[root@server3 nginx]# nginx
[root@server3 nginx]# nginx -s reload
测试:
[root@server3 nginx]# curl http://127.0.0.1/status
Active connections: 1 
server accepts handled requests
 1 1 1 
Reading: 0 Writing: 1 Waiting: 0 
也可以在其他主机进行压测
[root@Sun_s ~]# ab -c10 -n 1000 http://172.25.1.3/index.html

2.添加nginx的监控配置文件

[root@server3 nginx]# cd /etc/zabbix/zabbix_agentd.d
[root@server3 zabbix_agentd.d]# vim userparameter_nginx.conf
UserParameter=nginx.active,curl -s  http://127.0.0.1/status | grep Active | awk '{print $3}'
UserParameter=nginx.accept,curl -s http://127.0.0.1/status | awk 'NR==3{print $1}'
UserParameter=nginx.handled,curl -s http://127.0.0.1/status | awk 'NR==3{print $2}'
UserParameter=nginx.request,curl -s http://127.0.0.1/status | awk 'NR==3{print $3}'
[root@server3 zabbix_agentd.d]# systemctl restart zabbix-agent.service 

在server1里手动测试以下

[root@server1 ~]# yum install zabbix-get.x86_64 -y
[root@server1 ~]# zabbix_get -s 172.25.1.3 -p 10050 -k "nginx.active"
1
[root@server1 ~]# zabbix_get -s 172.25.1.3 -p 10050 -k "nginx.accept"
1008
[root@server1 ~]# zabbix_get -s 172.25.1.3 -p 10050 -k "nginx.handled"
1009
[root@server1 ~]# zabbix_get -s 172.25.1.3 -p 10050 -k "nginx.request"
1010

3.添加监控项

加入刚才监控配置文件中写入的几个键值:nginx.active nginx.accept nginx.handled nginx.request
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
把刚才添加好的监控项添加到图形里
创建图形
在这里插入图片描述
添加监控项
在这里插入图片描述
在这里插入图片描述
查看图形,当显示出来数据就说明已经配置成功了,刚添加上可能需要等一会数据才能出来
在这里插入图片描述

六、zabbix server的mysql监控

1.配置mysql监控文件

由于之前server1有仓库,为了节省资源,我们直接使用server1
只要让agent可以通过mysql的密码认证,在zabbix下建立隐藏文件,说明具体命令执行的用户、密码、socket:

[root@server1 ~]# mkdir  /var/lib/zabbix
[root@server1 ~]# cd /var/lib/zabbix/
注意这里是隐藏文件
[root@server1 zabbix]# vim .my.cnf
[mysql]
user=root
password=westos
socket=/var/lib/mysql/mysql.sock

[mysqladmin]
user=root
password=westos
socket=/var/lib/mysql/mysql.sock

[root@server1 zabbix]# mysqladmin password westos
[root@server1 zabbix]# systemctl restart zabbix-agent.service 

2.添加模板

在这里插入图片描述
在这里插入图片描述
手动测试
只有有返回值说明就OK了

[root@server1 zabbix]# zabbix_get -s 127.0.01 -p 10050 -k "mysql.ping" 
1

查看图形
在这里插入图片描述在这里插入图片描述
由于自带的mysq模板监控项太少了,所以我们需要手动添加模板

3.从外部导入模板

  • 下载需要的导入工具
  • 链接:percona 提取码: bru2
[root@server1 ~]# rpm -ivh percona-zabbix-templates-1.1.8-1.noarch.rpm
[root@server1 ~]# cd /var/lib/zabbix/percona/templates/
[root@server1 templates]# cp userparameter_percona_mysql.conf /etc/zabbix/zabbix_agentd.d/
[root@server1 templates]# systemctl restart zabbix-agent.service
[root@server1 templates]# cd ..
[root@server1 percona]# cd scripts/
[root@server1 scripts]# vim ss_get_mysql_stats.php 

在这里插入图片描述
手动测试

[root@server1 scripts]# /var/lib/zabbix/percona/scripts/get_mysql_stats_wrapper.sh gg
1
[root@server1 scripts]# zabbix_get -s 127.0.01 -p 10050 -k "MySQL.Key-read-requests"
1

此处可以取到值就说明配置成功,导入模板即可
注意
此处,如果进行过手动测试,会生成一个txt文件,这个文件生成的默认权限是root,因为访问的时候是用zabbix用户访问的
所以要么把文件删除掉,要么修改其权限。操作如下:

[root@server1 scripts]# cd /tmp/
[root@server1 tmp]# ls
localhost-mysql_cacti_stats.txt
systemd-private-4e1607fdb08c4946b000e3456cedfd42-httpd.service-VKKp6Z
systemd-private-4e1607fdb08c4946b000e3456cedfd42-mariadb.service-dSsMvQ
[root@server1 tmp]# chown zabbix.zabbix localhost-mysql_cacti_stats.txt
localhost-mysql_cacti_stats.txt
将权限改为zabbix,不然数据不会变

在这里插入图片描述

  • 现在在web页面导入模板
  • 这个模板是我在网上下载好的,所以直接导入
  • 链接: 模板提取码: wysw
  • 如有需要自行提取
    在这里我们把之前的模板取消链接并清理掉
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述在这里插入图片描述
    我们可以看到添加新模板之后,监控项增加至279个
    在这里插入图片描述
    如果没有看到数据,清等待一会数据就会显示出来。
    在这里插入图片描述

七、zabbix server 的tomcat+jave 监控

1.在server2上搭建tomcat java 服务

链接:tomcat包 提取码: jqj6

[root@server2 ~]# tar zxf apache-tomcat-7.0.37.tar.gz -C /usr/local/
[root@server2 ~]# cd /usr/local/
[root@server2 local]# ln -s apache-tomcat-7.0.37/ tomcat
[root@server2 local]# ls
[root@server2 local]# cd tomcat
[root@server2 tomcat]# cd bin/
[root@server2 bin]# vim catalina.sh     ##创建8888端口
CATALINA_OPTS='-Dcom.sun.management.jmxremote.port=8888
  -Dcom.sun.management.jmxremote.ssl=false
  -Dcom.sun.management.jmxremote.authenticate=false'
[root@server2 bin]# yum install java-1.8.0-openjdk.x86_64 -y  
[root@server2 bin]# ./startup.sh
[root@server2 bin]# netstat -antlp|grep 8888
tcp6       0      0 :::8888                 :::*                    LISTEN      5607/java           

在这里插入图片描述

2.server1安装JAVA网关

仅当您要监视JMX应用程序时才需要安装Java网关。Java网关是轻量级的,不需要数据库。

yum install -y zabbix-java-gateway.x86_64 -y
 cd /etc/zabbix/
 [root@server1 zabbix]# vim /etc/zabbix/zabbix_java_gateway.conf
 [root@server1 zabbix]# systemctl enable --now zabbix-java-gateway.service 
 [root@server1 zabbix]# netstat -antlp| grep :10052
tcp6       0      0 :::10052                :::*                    LISTEN      1913/java           

端口ip
在这里插入图片描述
开启10个监控项
在这里插入图片描述
在server端开启java 网关相关的配置

[root@server1 zabbix]# vim zabbix_server.conf 
[root@server1 zabbix]# systemctl restart zabbix-server.service

在这里插入图片描述在这里插入图片描述
在这里插入图片描述
等待一会,看是否出现,如果没出现,请仔细核对配置文件信息
在这里插入图片描述
查看是否有数据,出现数据配置完成
在这里插入图片描述

八、Zabbix-agent主动模式 (全克隆)

在server3上操作这个全克隆

[root@server3 zabbix]# vim zabbix_agentd.conf
[root@server3 zabbix]# systemctl restart zabbix-agent.service
[root@server3 zabbix]# netstat -antlp | grep :10050

这个选项打开之后,是保留了原来被动复制的三个监控项,使得原来的监控项变少
在这里插入图片描述
全克隆
在这里插入图片描述
在这里插入图片描述
点击批量更新
在这里插入图片描述
把server3原来的模板删除,添加新克隆的模板
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

九、proxy安装配置

为了节省资源,我们将刚才的server3删掉,将server3作为proxy

1.proxy 安装

在server3上操作
先将主机名改成proxy,这样方便做实验,注意给其他主机的解析也要加上proxy
在这里插入图片描述

2.创建数据库

编辑zabbix_proxy.conf 文件以使用已创建的数据库。例如

[root@proxy ~]# systemctl disable --now  zabbix-agent.service 
[root@proxy ~]# yum install -y zabbix-proxy-mysql.x86_64
[root@proxy ~]# yum install mariadb-server.x86_64 -y
[root@proxy ~]# vim /etc/zabbix/zabbix_proxy.conf 
[root@proxy ~]# systemctl enable --now mariadb.service
[root@proxy ~]# mysql
MariaDB [(none)]> create database zabbix_proxy character set utf8 collate utf8_bin;
MariaDB [(none)]> create user 'zabbix'@'localhost' identified by 'westos';
MariaDB [(none)]> grant all privileges on zabbix_proxy.* to 'zabbix'@'localhost';
[root@proxy ~]# vim zabbix_proxy.conf
[root@proxy ~]# systemctl restart zabbix-proxy.service

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

3.导入数据

[root@proxy ~]# cd /usr/share/doc/zabbix-proxy-mysql-4.0.27/
[root@proxy zabbix-proxy-mysql-4.0.27]# zcat schema.sql.gz | mysql -uzabbix -pwestos zabbix_proxy

4. 创建代理

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
这时我们发现server2的监控都灰了,是因为最开始配置的时候server指向的是server1端,所以需要修改配置文件

[root@server2 bin]# vim /etc/zabbix/zabbix_agentd.conf 
将server指向proxy的ip  
[root@proxy ~]#  vim /etc/zabbix/zabbix_proxy.conf 
还有JAVA网关也得指向serve1的ip

server2
在这里插入图片描述
在这里插入图片描述
proxy
在这里插入图片描述
编辑完配置文件记得重启服务
建议使用重启,因为在生产环境中要保证服务的正常运行

[root@server1 zabbix]# zabbix_server -R config_cache_reload
[root@proxy ~]# zabbix_proxy -R config_cache_reload

我们再重新查看状态,已经重新起来了,这就说明已经配置成功
在这里插入图片描述

十、zabbix+睿象云

睿象云
在这里插入图片描述
测试:
当将server2 down 掉 ,因为server2中有一个触发器
server2Agent ping:Up (1)Zabbix agent on server2 is unreachable for 5 minutes
方便做实验

首先将报警媒介的其他选项给停用掉
在这里插入图片描述

1创建监控工具

在Cloud Alert界面创建zabbix应用,并获取 appkey 。
在这里插入图片描述

2在zabbix server端安装CA探针

可以参考zabbix告警集成

  • 获取睿象云 Cloud Alert agent包:
    链接: ca探针包 提取码: k9p3
  • 解压、安装。
[root@server1 ~]# tar zxf ca_zabbix_release-2.1.0.tar.gz
[root@server1 ~]# cd cloudalert/bin/

处填入您新建应用时生成的appkey
在安装过程中根据安装提示,输入zabbix管理/监控/web登陆地址、管理员用户名、密码。
当显示安装成功,就说明已经配置完成
在这里插入图片描述
在这里插入图片描述

3 在睿象云添加策略

CA–>配置–>新建通知
在这里插入图片描述

[root@server2 ~]# systemctl stop zabbix-agent.service

等待一会,在zabbix页面也会出现问题
在这里插入图片描述
查看睿象云的告警位置,有认领流程
在这里插入图片描述
在这里插入图片描述
收到的微信通知
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Sun__s/article/details/112706471