Elasticsearch8.4.0集群安装(ELK安装part1)

这篇具有很好参考价值的文章主要介绍了Elasticsearch8.4.0集群安装(ELK安装part1)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一,环境准备

由于资源有限,使用VirtulBox虚拟机进行搭建。

搭建集群的环境配置:
本集群使用Red Hat Enterprise Linux release 8.2 (Ootpa)操作系统,1C CPU,4G Memory,大于50G的Disk。

集群安装规划如下:
机器地址     节点名称    节点角色    节点功能
192.168.88.5 node-1    Master,data    主+数据节点
192.168.88.7 node-2    Master,data    主+数据节点
192.168.88.9 node-3    Master,data    主+数据节点

下载安装包:
https://www.elastic.co/cn/elasticsearch/
​当前最新版本为 8.4.0

创建用户:
#groupadd es
#useradd -g es es -m

JDK选择:
在elasticsearch7以上的版本中会自带Open JDK,因此建议用自带的JDK,当然也可以单独安装自定义的JDK。

修改进程最大打开文件数数量为65536,每台都执行:
vi /etc/security/limits.conf
* soft nofile 65536
* hard nofile 65536

查看:
[root@goya ~]# ulimit -a
......
open files                      (-n) 65536
......

修改/etc/sysctl.conf文件,增加配置vm.max_map_count=262144
vi /etc/sysctl.conf
# 最后增加一行:
vm.max_map_count = 262144
# 退出执行
sysctl -p

二,软件安装

安装方式选择:
ES的安装方式有如下几种:(官方参考https://www.elastic.co/guide/en/elasticsearch/reference/8.4/install-elasticsearch.html)
1,压缩文件包
2,RPM命令的方式
3,Docker
本文选择第一种方式。

解压压缩包到软件目录:

上传文件elasticsearch-8.4.0-linux-x86_64.tar到/app/install目录
tar -xvf /app/install/elasticsearch-8.4.0-linux-x86_64.tar -C /opt
chown -R es.es elasticsearch

修改环境变量:

vi /etc/profile
# 做如下修改:
export JAVA_HOME=/app/elasticsearch/jdk
export ES_HOME=/app/elasticsearch
export PATH=$ES_HOME/bin:$ES_HOME/jdk/bin:$PATH

创建数据目录:
mkdir -p /data/elasticsearch
chown es.es  /data/elasticsearch

修改hosts文件:
vi /etc/hosts
192.168.88.5 goya1
192.168.88.7 goya2
192.168.88.9 goya3

三,配置ES

3.1 编辑ES配置文件
$ cp /app/elasticsearch/config/jvm.options /app/elasticsearch/config/jvm.options.bak
$ vi jvm.options
去掉下面这两行的注释,并且根据自己的机器配置更改jvm内存大小
## -Xms4g
## -Xmx4g

3.2 在第一台服务器节点goya1设置集群多节点通信密钥:
es用户下, cd /app/elasticsearch/bin
[es@goya bin]$ ./elasticsearch-certutil ca
证书密码:changeit123(也可以设置为你想要的任何密码)
[es@goya bin]$ ./elasticsearch-certutil cert --ca elastic-stack-ca.p12
证书密码:changeit123(也可以设置为你想要的任何密码)
elastic-stack-ca.p12 就是上一步生成的(默认就在当前目录中),此时在当前目录生成名为 elastic-certificates.p12 的文件,它是单个PKCS#12密钥存储库,其中包括节点证书、节点密钥和CA证书。默认情况下,elasticsearch-certutil 生成没有主机名信息的证书(也就是说,它们没有任何主题可选名称字段)。这意味着可以对集群中的每个节点使用此证书,但您必须关闭主机名验证。
将生成的证书文件移动到 config/certs 目录中
mkdir -p /app/elasticsearch/config/certs
mv /app/elasticsearch/elastic-stack-ca.p12 /app/elasticsearch/elastic-certificates.p12 /app/elasticsearch/config/certs

在第一台服务器节点goya1设置集群多节点 HTTP 证书
[es@goya bin]$ ./elasticsearch-certutil http
warning: ignoring JAVA_HOME=/app/elasticsearch/jdk; using bundled JDK

## Elasticsearch HTTP Certificate Utility

The 'http' command guides you through the process of generating certificates
for use on the HTTP (Rest) interface for Elasticsearch.

This tool will ask you a number of questions in order to generate the right
set of files for your needs.

## Do you wish to generate a Certificate Signing Request (CSR)?

A CSR is used when you want your certificate to be created by an existing
Certificate Authority (CA) that you do not control (that is, you don't have
access to the keys for that CA).

If you are in a corporate environment with a central security team, then you
may have an existing Corporate CA that can generate your certificate for you.
Infrastructure within your organisation may already be configured to trust this
CA, so it may be easier for clients to connect to Elasticsearch if you use a
CSR and send that request to the team that controls your CA.

If you choose not to generate a CSR, this tool will generate a new certificate
for you. That certificate will be signed by a CA under your control. This is a
quick and easy way to secure your cluster with TLS, but you will need to
configure all your clients to trust that custom CA.

Generate a CSR? [y/N]N

## Do you have an existing Certificate Authority (CA) key-pair that you wish to use to sign your certificate?

If you have an existing CA certificate and key, then you can use that CA to
sign your new http certificate. This allows you to use the same CA across
multiple Elasticsearch clusters which can make it easier to configure clients,
and may be easier for you to manage.

If you do not have an existing CA, one will be generated for you.

Use an existing CA? [y/N]y

## What is the path to your CA?

Please enter the full pathname to the Certificate Authority that you wish to
use for signing your new http certificate. This can be in PKCS#12 (.p12), JKS
(.jks) or PEM (.crt, .key, .pem) format.
CA Path: /app/elasticsearch/config/certs/elastic-stack-ca.p12                               
Reading a PKCS12 keystore requires a password.
It is possible for the keystore's password to be blank,
in which case you can simply press <ENTER> at the prompt
Password for elastic-stack-ca.p12:changeit123

## How long should your certificates be valid?

Every certificate has an expiry date. When the expiry date is reached clients
will stop trusting your certificate and TLS connections will fail.

Best practice suggests that you should either:
(a) set this to a short duration (90 - 120 days) and have automatic processes
to generate a new certificate before the old one expires, or
(b) set it to a longer duration (3 - 5 years) and then perform a manual update
a few months before it expires.

You may enter the validity period in years (e.g. 3Y), months (e.g. 18M), or days (e.g. 90D)

For how long should your certificate be valid? [5y] 5y

## Do you wish to generate one certificate per node?

If you have multiple nodes in your cluster, then you may choose to generate a
separate certificate for each of these nodes. Each certificate will have its
own private key, and will be issued for a specific hostname or IP address.

Alternatively, you may wish to generate a single certificate that is valid
across all the hostnames or addresses in your cluster.

If all of your nodes will be accessed through a single domain
(e.g. node01.es.example.com, node02.es.example.com, etc) then you may find it
simpler to generate one certificate with a wildcard hostname (*.es.example.com)
and use that across all of your nodes.

However, if you do not have a common domain name, and you expect to add
additional nodes to your cluster in the future, then you should generate a
certificate per node so that you can more easily generate new certificates when
you provision new nodes.

Generate a certificate per node? [y/N]N  

## Which hostnames will be used to connect to your nodes?

These hostnames will be added as "DNS" names in the "Subject Alternative Name"
(SAN) field in your certificate.

You should list every hostname and variant that people will use to connect to
your cluster over http.
Do not list IP addresses here, you will be asked to enter them later.

If you wish to use a wildcard certificate (for example *.es.example.com) you
can enter that here.

Enter all the hostnames that you need, one per line.
When you are done, press <ENTER> once more to move on to the next step.

goya1
goya2
goya3

You entered the following hostnames.

 - goya1
 - goya2
 - goya3

Is this correct [Y/n]Y  

## Which IP addresses will be used to connect to your nodes?

If your clients will ever connect to your nodes by numeric IP address, then you
can list these as valid IP "Subject Alternative Name" (SAN) fields in your
certificate.

If you do not have fixed IP addresses, or not wish to support direct IP access
to your cluster then you can just press <ENTER> to skip this step.

Enter all the IP addresses that you need, one per line.
When you are done, press <ENTER> once more to move on to the next step.

192.168.88.5
192.168.88.7
192.168.88.9

You entered the following IP addresses.

 - 192.168.88.5
 - 192.168.88.7
 - 192.168.88.9

Is this correct [Y/n]Y

## Other certificate options

The generated certificate will have the following additional configuration
values. These values have been selected based on a combination of the
information you have provided above and secure defaults. You should not need to
change these values unless you have specific requirements.

Key Name: goya1
Subject DN: CN=goya1
Key Size: 2048

Do you wish to change any of these options? [y/N]N

## What password do you want for your private key(s)?

Your private key(s) will be stored in a PKCS#12 keystore file named "http.p12".
This type of keystore is always password protected, but it is possible to use a
blank password.

If you wish to use a blank password, simply press <enter> at the prompt below.
Provide a password for the "http.p12" file:  [<ENTER> for none]changeit123

## Where should we save the generated files?

A number of files will be generated including your private key(s),
public certificate(s), and sample configuration options for Elastic Stack products.

These files will be included in a single zip archive.

What filename should be used for the output zip file? [/app/elasticsearch/elasticsearch-ssl-http.zip]

Zip file written to /app/elasticsearch/elasticsearch-ssl-http.zip

将证书放到cert目录:
cd /app/elasticsearch/
unzip elasticsearch-ssl-http.zip
mv ./elasticsearch/http.p12 ./kibana/elasticsearch-ca.pem ./config/certs

Elasticsearch8.4.0集群安装(ELK安装part1)

# 将证书分发到其他2个节点
cd /app/elasticsearch/config/certs
scp * goya2:/app/elasticsearch/config/certs
scp * goya3:/app/elasticsearch/config/certs

给keystore和truststore设置密码
注解:keystore可以看成一个放key的库,key就是公钥,私钥,数字签名等组成的一个信息。truststore是放信任的证书的一个store。truststore和keystore的性质是一样的,都是存放key的一个仓库,区别在于,truststore里存放的是只包含公钥的数字证书,代表了可以信任的证书,而keystore是包含私钥的。如果在创建证书的过程中加了密码,需要输入这个密码。每个节点都需要。

elasticsearch-keystore add xpack.security.transport.ssl.keystore.secure_password
elasticsearch-keystore add xpack.security.transport.ssl.truststore.secure_password
elasticsearch-keystore add xpack.security.http.ssl.keystore.secure_password
elasticsearch-keystore add xpack.security.http.ssl.truststore.secure_password

修改配置文件elasticsearch.yml:

192.168.88.5(goya1):

# 设置 ES 集群名称
cluster.name: es840-cluster
# 设置集群中当前节点名称
node.name: es-goya01
# 设置数据,日志文件路径
path.data: /data/elasticsearch
path.logs: /app/elasticsearch/logs
#允许连接IP。network.host就是网络主机。0.0.0.0指网络主机的IP地址。但0.0.0.0并不是一个真实的的IP地址,它表示本机中所有的IPV4地址。监听0.0.0.0的端口,就是监听本机中所有IP的端口。
network.host: goya1 #这里如果写成域名就需要/etc/hosts里添加ip域名信息,或者直接写成IP地址。否则启动elasticsearch会报“Failed to bind to xxx”错误。
# 设置网络访问端口
http.port: 9200
# 初始节点
discovery.seed_hosts: ["goya1"]
cluster.initial_master_nodes: ["es-goya01", "es-goya02", "es-goya03"]
# 安全认证
xpack.security.enabled: true
xpack.security.enrollment.enabled: true
xpack.security.http.ssl:
 enabled: true # 注意第一个空格
 keystore.path: /app/elasticsearch/config/certs/http.p12
 truststore.path: /app/elasticsearch/config/certs/http.p12
xpack.security.transport.ssl:
 enabled: true
 verification_mode: certificate
 keystore.path: /app/elasticsearch/config/certs/elastic-certificates.p12
 truststore.path: /app/elasticsearch/config/certs/elastic-certificates.p12
#高级Http配置,( Static , string) 为 HTTP 流量设置此节点的地址。该节点将绑定到该地址,并将其用作其 HTTP 发布地址。接受 IP 地址、主机名或特殊值。仅当您需要对传输和 HTTP 接口进行不同配置时才使用此设置。https://www.elastic.co/guide/en/elasticsearch/reference/8.4/modules-network.html#network-interface-values
http.host: 192.168.88.5
#关闭geoip数据库的更新, 参考https://www.elastic.co/guide/en/elasticsearch/reference/current/geoip-processor.html
ingest.geoip.downloader.enabled: false
xpack.security.http.ssl.client_authentication: none

192.168.88.7/192.168.88.7(goya2/goya3):另外两台类似修改,在node.name、http.host和network.host有区别

# 设置节点名称
node.name: es-goya02
# 设置网络访问主机
network.host: goya2
#HTTP和传输流量设置此节点的地址
http.host: 192.168.88.7

# 设置节点名称
node.name: es-goya03
# 设置网络访问主机
network.host: goya3
#HTTP和传输流量设置此节点的地址
http.host: 192.168.88.9​​​​​​​

备注:另外网上一些文档对其他参数也进行了配置,但本文安装时没有进行设置。
----------------------------------------------
http.cors.enabled: true
http.cors.allow-origin: “*”
#http.cors.enabled    true    是否支持跨域,默认为false, 如果启用了 HTTP 端口,那么此属性会指定是否允许跨源 REST 请求。
#http.cors.allowed.origin    localhost    如果 http.cors.enabled 的值为 true,那么该属性会指定允许 REST。请求来自何处:当设置允许跨域,默认为*,表示支持所有域名,如果我们只是允许某些网站能访问,那么可以使用正则表达式。比如只允许本地地址。
----------------------------------------------
#node.roles
#Elasticsearch中的Node角色以及使用方法(https://blog.csdn.net/microGP/article/details/113884941)
----------------------------------------------
xpack.security.http.ssl:
  enabled: false 开启还是关闭
  verification_mode: certificate如下
   full:它验证所提供的证书是否由受信任的权威机构(CA)签名,并验证服务器的主机名(或IP地址)是否与证书中识别的名称匹配。
   certificate:它验证所提供的证书是否由受信任的机构(CA)签名,但不执行任何主机名验证。
   none:它不执行服务器证书的验证。
  truststore.path: certs/elastic-certificates.p12 信任存储库文件的存放位置
  keystore.path: certs/elastic-certificates.p12 密钥存储库文件的存放位置
----------------------------------------------

分别启动集群3个节点:
elasticsearch -d
查看进程:
[es@goya3 config]$ ps -ef |grep elasticsearch
es          5447       1  7 02:03 pts/0    00:00:31 /app/elasticsearch/jdk/bin/java -Des.networkaddress.cache.ttl=60 -Des.networkaddress.cache.negative.ttl=10 -Djava.security.manager=allow -XX:+AlwaysPreTouch -Xss1m -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djna.nosys=true -XX:-OmitStackTraceInFastThrow -Dio.netty.noUnsafe=true -Dio.netty.noKeySetOptimization=true -Dio.netty.recycler.maxCapacityPerThread=0 -Dlog4j.shutdownHookEnabled=false -Dlog4j2.disable.jmx=true -Dlog4j2.formatMsgNoLookups=true -Djava.locale.providers=SPI,COMPAT --add-opens=java.base/java.io=ALL-UNNAMED -XX:+UseG1GC -Djava.io.tmpdir=/tmp/elasticsearch-11936892576574585328 -XX:+HeapDumpOnOutOfMemoryError -XX:+ExitOnOutOfMemoryError -XX:HeapDumpPath=data -XX:ErrorFile=logs/hs_err_pid%p.log -Xlog:gc*,gc+age=trace,safepoint:file=logs/gc.log:utctime,pid,tags:filecount=32,filesize=64m -Xms1969m -Xmx1969m -XX:MaxDirectMemorySize=1032847360 -XX:G1HeapRegionSize=4m -XX:InitiatingHeapOccupancyPercent=30 -XX:G1ReservePercent=15 -Des.distribution.type=tar --module-path /app/elasticsearch/lib --add-modules=jdk.net -m org.elasticsearch.server/org.elasticsearch.bootstrap.Elasticsearch

设置elasticsearch密码:
部分文档里说启动日志会显示elastic用户默认的密码,但本次安装启动时没有显示,因此尝试自己设置。
更用户的密码(如果集群搭建成功只需要在一个节点上更改即可)
[es@goya1 ~]$ elasticsearch-reset-password -u elastic -i
warning: ignoring JAVA_HOME=/app/elasticsearch/jdk; using bundled JDK
This tool will reset the password of the [elastic] user.
You will be prompted to enter the password.
Please confirm that you would like to continue [y/N]y
Enter password for [elastic]: 123456
Re-enter password for [elastic]: 123456
Password for the [elastic] user successfully reset.

验证安装:
https://192.168.88.5:9200/
https://192.168.88.7:9200/
https://192.168.88.9:9200/
输入用户名和密码elastic/123456

页面输出结果:
{
  "name" : "es-goya01",
  "cluster_name" : "es840-cluster",
  "cluster_uuid" : "vaKjd7lITW6UpEudLMzfzQ",
  "version" : {
    "number" : "8.4.0",
    "build_flavor" : "default",
    "build_type" : "tar",
    "build_hash" : "f56126089ca4db89b631901ad7cce0a8e10e2fe5",
    "build_date" : "2022-08-19T19:23:42.954591481Z",
    "build_snapshot" : false,
    "lucene_version" : "9.3.0",
    "minimum_wire_compatibility_version" : "7.17.0",
    "minimum_index_compatibility_version" : "7.0.0"
  },
  "tagline" : "You Know, for Search"
}

查看集群信息:
[es@goya1 ~]$ curl -k --user elastic:123456 -XGET  https://192.168.88.5:9200/_cat/nodes?v
ip           heap.percent ram.percent cpu load_1m load_5m load_15m node.role   master name
192.168.88.9           21          85   1    0.04    0.05     0.08 cdfhilmrstw -      es-goya03
192.168.88.5            8          86   2    0.04    0.06     0.16 cdfhilmrstw -      es-goya01
192.168.88.7           10          86   2    0.00    0.04     0.11 cdfhilmrstw *      es-goya02

测试高可用:
从上面的节点状态查询结果可以知道,es-goya02是master节点。
现在kill此节点。
[es@goya2 elasticsearch]$ ps -ef |grep elasticsearch
es          1784       1  2 03:28 pts/0    00:00:41 /app/elasticsearch/jdk/bin/java -Des.networkaddress.cache.ttl=60 -Des.networkaddress.cache.negative.ttl=10 -Djava.security.manager=allow -XX:+AlwaysPreTouch -Xss1m -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djna.nosys=true -XX:-OmitStackTraceInFastThrow
......
[es@goya2 elasticsearch]$ kill -9 1784
[es@goya2 elasticsearch]$ ps -ef |grep elasticsearch
es          2106    1665  0 03:56 pts/0    00:00:00 grep --color=auto elasticsearch
重新查询,可以看到master飘到es-goya03节点。
[es@goya2 elasticsearch]$ curl -k --user elastic:123456 -XGET  https://192.168.88.5:9200/_cat/nodes?v
ip           heap.percent ram.percent cpu load_1m load_5m load_15m node.role   master name
192.168.88.9           13          86   1    0.00    0.02     0.02 cdfhilmrstw *      es-goya03
192.168.88.5           18          86   1    0.00    0.00     0.06 cdfhilmrstw -      es-goya01
如果继续kill节点es-goya03,集群将不可用。

至此,es集群安装完毕。文章来源地址https://www.toymoban.com/news/detail-423157.html

到了这里,关于Elasticsearch8.4.0集群安装(ELK安装part1)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 搭建Elasticsearch8.0集群

    PS:下面的机器名和后边要配置的集群节点名字没有任何关系,纯属巧合 ########################################### PS: ES8 自带 jdk ,所以不用配置 ########################################### 新建普通用户 ########################################### 下载、解压、修改属主属组为esuser(root) 新建数据和日志

    2024年02月03日
    浏览(43)
  • Elasticsearch8 集群搭建(一)基础篇

    记录下工作中搭建Elasticsearch8 集群的过程,此篇为第一部分,后续会陆续更新其他部分。 前提: 安全组配置:确保集群内所有服务器在同一安全组内。(或在不同安全组但互相可以通信) 以下步骤需要在每台要安装Elasticsearch的服务器上执行。 1、创建Elasticsearch专属用户 E

    2024年01月18日
    浏览(42)
  • Elasticsearch8节点加入集群失败解决方法

    failed to join {cluster-master2}{DDB9zVg8SQ24a0jD7lno2w}{gLNn_SCQTIely-VWU0yOHA}{poc-cluster-master2}………… 在日志里面可以看到,是因为节点之前使用一个UUID加入了集群,现在使用一个新的UUID加入新的集群,这是不允许的。 在 Elasticsearch 集群中,每个节点都有一个唯一的节点标识符,通常被称

    2024年01月21日
    浏览(50)
  • Elasticsearch8 集群搭建(二)配置篇:(1)节点和集群配置

    安装完Elasticsearch后,需要对其进行配置,包括以下几部分:节点和集群配置、系统配置、安全配置。 此篇记录节点和集群配置的内容,后续将更新系统配置和安全配置。 通过编辑/usr/local/elasticsearch-8.10.2/config/elasticsearch.yml文件进行配置,在集群内每个节点上都要进行配置。

    2024年01月18日
    浏览(38)
  • Elasticsearch8 集群搭建(二)配置篇:(2)系统配置

    此篇记录Elasticsearch8的一些 系统配置。 1、更改文件描述符的限制 Elasticsearch使用了大量的文件描述符,它用于表示系统打开的文件的标识符。文件描述符是非负整数,它在操作系统层面被用来唯一标识一个打开的文件、套接字或其他 I/O 资源。每个进程都有一组文件描述符,

    2024年01月19日
    浏览(43)
  • Redis项目 PART1

    第一部分:含注册登入+商户查询(使用缓存) 使用redis而不用传统的session的原因(session共享问题):每个tomcat中都有一份属于自己的session,假设用户第一次访问第一台tomcat,并且把自己的信息存放到第一台服务器的session中,但是第二次这个用户访问到了第二台tomcat,那么在第

    2024年02月16日
    浏览(39)
  • 动态规划(一) part1

    T1:一个数组 中的最长 升序 子序列 的长度 给你一个整数数组  nums  ,找到其中最长严格递增子序列的长度。 子序列  是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如, [3,6,2,7]  是数组  [0,3,1,6,2,2,7]  的子序列。 解: 1.关键 (1)

    2023年04月19日
    浏览(78)
  • Elasticsearch8 - Docker安装Elasticsearch8.12.2

    最近在学习 ES,所以需要在服务器上装一个单节点的 ES 服务器环境:centos 7.9 目前最新版本是 8.12.2 新增配置文件 elasticsearch.yml 解释一下,前三行是开启远程访问和跨域,最后一行是开启密码访问 Networking | Elasticsearch Guide [8.12] | Elastic 在宿主机创建容器的挂载目录,我的目录

    2024年04月15日
    浏览(50)
  • ELK分析系统----Elasticsearch集群

    掌握Elasticsearch集群的简单使用 Elasticsearch:存储、搜索和分析 Elastcisearch是ELK核心的分布式搜索和引擎。logstash和beats有助于收集,聚合和丰富你的数据并将其存储在Elasticsearch中,使用kibana,可以交互式探索,可视化和共享对数据的见解,并管理和监视堆栈。Elasticsearch是发生

    2023年04月09日
    浏览(40)
  • SwiftUI 布局协议 - Part1

    今年 SwiftUI 新增最好的功能之一必须是布局协议。它不但让我们参与到布局过程中,而且也给了我们一个很好的机会去更好的理解布局在 SwiftUI 中的作用。 早在2019年,我写了一篇文章 SwiftUI 中 frame 的表现 ,其中,我阐述了父视图和子视图如何协调形成最终视图效果。那里描

    2024年02月05日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包