Keepalived + LVS + Nginx 实现高可用 + 负载均衡

目录

Keepalived

Keepalived 是什么(高可用)

安装 Keepalived

LVS

LVS 是什么(负载均衡)

安装 LVS

Keepalived + LVS + Nginx 实现 高可用 + 负载均衡


Keepalived

Keepalived 是什么(高可用)

Keepalived 是一个用于实现 高可用 性(High Availability, HA)的服务,是一款基于 VRRP 协议的高可用软件,常用于主备切换和虚拟IP漂移,在服务故障时自动实现故障转移。

Keepalived 的核心功能

功能说明
VRRPVirtual Router Redundancy Protocol,实现主备切换,保障VIP持续可用
健康检查(check)定时检测真实服务(如 Nginx、LVS、MySQL)是否存活
VIP 漂移将一个虚拟 IP 绑定到当前健康的主节点上,故障时自动转移到备节点
结合 LVS通常与 LVS(Linux Virtual Server)一起部署,提供高可用负载均衡

安装 Keepalived

sudo apt-get update

sudo apt-get install -y keepalived 

查看是否安装成功

keepalived -v

开启开机自启动:

sudo systemctl enable keepalived

Keepalived 常用命令

开启开机自启动:sudo systemctl enable keepalived

禁用开机自启动:sudo systemctl disable keepalived

开启服务:sudo systemctl start keepalived

关闭服务:sudo systemctl stop keepalived

重启服务:sudo systemctl restart keepalived

查看状态:sudo systemctl status keepalived


编辑配置文件

sudo vim /etc/keepalived/keepalived.conf

配置文件参数说明

## 全局配置,用于日志、调试、邮件通知等目的
global_defs {
    ## router_id 是 Keepalived 的 全局标识符
    router_id LVS_DEVEL
}

# 定义一个 VRRP 实例,VI_1 是自定义的实例名称,每一个实例代表一个高可用虚拟路由组。
vrrp_instance VI_1 {
    ## 指定该节点的初始角色,MASTER:主节点,正常情况下负责绑定虚拟IP(VIP)。BACKUP:备用节点,在主节点不可用时接管 VIP。
    # Keepalived 自动通过优先级判断主备,不是硬编码的主备,所以这个只是初始角色。
    state MASTER
    ## 指定绑定 VIP 的网络接口(网卡名),例如 eth0、ens33、enp0s3 等。使用 ip a 查看当前系统的网卡名。
    interface ens33
    ## 虚拟路由器的 ID,用于识别一个 VRRP 实例的组。所有参与该 VRRP 实例(主备)的服务器必须一致。范围:0~255,确保不同服务之间不要冲突。
    virtual_router_id 51
    ## 指定该节点的优先级。数字越大,优先级越高。主节点应配置较高的值(如 100),备用节点配置较低(如 90)。当优先级高的节点恢复时,会自动抢占 VIP
    priority 100
    ## 指定 VRRP 广播间隔时间(秒)。主节点每隔指定的秒发送一次心跳包,默认是 1 秒,一般无需修改
    advert_int 1

    ## 禁用抢占
    # nopreempt                      # 即使此节点优先级更高也不抢占 MASTER

    ## 延迟抢占 VIP
    # 主节点恢复后,希望它稳定运行一段时间再接管 VIP,防止主节点频繁重启时反复抢占,导致服务中断
    # nopreempt 和 preempt_delay 不能同时使用。如果两者都写了,以 nopreempt 为准
    # preempt_delay 10              # 恢复后等待10秒才尝试抢占 MASTER

    ## 状态通知脚本(可选)
    # notify_master "/path/to/script" # 成为 MASTER 时执行脚本
    # notify_backup "/path/to/script" # 成为 BACKUP 时执行脚本
    # notify_fault  "/path/to/script" # 出现故障时执行脚本
    # notify        "/path/to/script" # 所有状态变更时都执行的统一脚本

    ## 本机实际 IP 地址(作为 VRRP 包发送源 IP)
    unicast_src_ip 192.168.189.135
    ## 用于将 Keepalived 的 VRRP 心跳通信改为“单播”(Unicast)模式。不配置的话默认的是“组播”(Multicast)模式。云服务器(如阿里云、腾讯云)中,出于安全限制,组播通常被禁用或不可用。
    unicast_peer {
        192.168.189.136
        192.168.189.137
    }

    ## 用于设置主备之间的认证信息
    authentication {
        ## 认证类型,一般用 PASS(明文密码)
        auth_type PASS
        ## 认证密码(主备节点必须保持一致)
        auth_pass 123456
    }

    ## 指定一个或多个虚拟IP(VIP)。VIP 是客户端访问的目标地址,当主节点故障,VIP 会自动漂移到备节点
    virtual_ipaddress {
        192.168.189.100           # 虚拟IP 1,例如用于 web 服务A
        192.168.189.101           # 虚拟IP 2,例如用于 web 服务B
        192.168.189.102           # 虚拟IP 3,例如用于 mysql 服务

        # 把 VIP 绑定到本机的 loopback 网卡(lo),LVS 的时候使用(只在Master节点生效,所以不推荐使用,推荐使用命令的方式)
        # 192.168.189.100/32 dev lo scope host

    }
}

配置文件实操

  • 主节点:192.168.189.135,优先级为 100
  • 备节点:192.168.189.136,优先级为 90
  • 第三节点:192.168.189.137,优先级为 80

这些参数必须在所有节点一致:vrrp_instance、virtual_router_id、advert_int、authentication、virtual_ipaddress

1. 主节点(192.168.189.135)配置

sudo vim /etc/keepalived/keepalived.conf

vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 51
    priority 100
    advert_int 1

    unicast_src_ip 192.168.189.135
    unicast_peer {
        192.168.189.136
        192.168.189.137
    }

    authentication {
        auth_type PASS
        auth_pass 123456
    }

    virtual_ipaddress {
        192.168.189.100
    }
}

重启 keepalived

sudo systemctl restart keepalived

2. 备节点(192.168.189.136)配置

sudo vim /etc/keepalived/keepalived.conf

vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 51
    priority 90
    advert_int 1

    unicast_src_ip 192.168.189.136
    unicast_peer {
        192.168.189.135
        192.168.189.137
    }

    authentication {
        auth_type PASS
        auth_pass 123456
    }

    virtual_ipaddress {
        192.168.189.100
    }
}

重启 keepalived

sudo systemctl restart keepalived

3. 第三节点(192.168.189.137)配置

sudo vim /etc/keepalived/keepalived.conf

vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 51
    priority 80
    advert_int 1

    unicast_src_ip 192.168.189.137
    unicast_peer {
        192.168.189.135
        192.168.189.136
    }

    authentication {
        auth_type PASS
        auth_pass 123456
    }

    virtual_ipaddress {
        192.168.189.100
    }
}

重启 keepalived

sudo systemctl restart keepalived

测试是否配置成功

测试步骤:查看VIP在哪个节点上?发现在主节点上,把主节点关闭后,发现VIP漂移到备用节点上了

1. 在主节点(192.168.189.135)运行:

ip a | grep 192.168.189.100

输入如下内容,表示 VIP 被绑定到此节点

inet 192.168.189.100/32 scope global ens33

2. 关闭主节点的 Keepalived 服务:

sudo systemctl stop keepalived

3. 在备节点(192.168.189.136)运行:

ip a | grep 192.168.189.100

VIP 会自动漂移到备节点。


开启 keepalived 日志

(所有节点都要执行)

1. 配置 rsyslog 接收 Keepalived 日志

sudo vim /etc/rsyslog.d/keepalived.conf

文件内容如下:

local0.*    /var/log/keepalived.log

重启 rsyslog 服务

sudo systemctl restart rsyslog

2. 执行命令

sudo keepalived --log-console --log-detail --log-facility=local0

重启 Keepalived 服务

sudo systemctl restart keepalived

3. 查看日志

tail -500f /var/log/keepalived.log

LVS

LVS 是什么(负载均衡)

LVS(Linux Virtual Server)是一个运行在 Linux 内核中的负载均衡器,它可以将大量的请求分发到多台后端服务器上,实现网站或服务的 Linux 内核级负载均衡

LVS 的特点

特性说明
高性能内核级处理,效率非常高,适合大规模并发
稳定可靠运行在 Linux 内核中,成熟稳定
支持多种调度算法如轮询(RR)、最少连接(LC)、加权等
透明性高客户端无需感知后端服务器变化
扩展性强可轻松添加或移除后端服务器

LVS 的负载均衡算法

算法名全称说明
rrRound Robin轮询,每台服务器轮流处理请求,适用于服务器性能差不多的情况。
wrrWeighted Round Robin加权轮询,根据服务器权重分配请求,权重大者分配更多请求。
lcLeast Connection最少连接数优先,当前连接最少的服务器优先接收新请求。
wlcWeighted Least Connection加权最少连接,在连接数基础上再加权,适用于连接时长差异较大的情况。
lblcLocality-Based Least Connection基于本地性和最少连接数,适用于缓存服务器,提高命中率。
lblcrLocality-Based Least Connection with Replication类似于 lblc,但支持多个复制服务器。
dhDestination Hashing目的地址哈希,将请求根据目标 IP 哈希分配,适合源地址多样化场景。
shSource Hashing源地址哈希,将同一客户端的请求始终发往同一后端,适用于会话保持。

LVS 负载均衡的转发工作模式 

模式简介优点缺点或要求
NATLVS 作为网关,所有流量都经过 LVS,再转发给后端配置简单LVS 成为瓶颈,占用带宽
DR(Direct Routing)请求从 LVS 发出,但响应由后端服务器直接返回客户端性能高,响应快需要所有机器在同一网段,后端需绑定 VIP(不响应 ARP)
TUN(IP隧道)LVS 和后端服务器可以跨网段跨地域部署可用后端服务器需支持 IP 隧道

安装 LVS

sudo apt-get update
sudo apt-get install -y ipvsadm

编辑配置文件

sudo vim /etc/keepalived/keepalived.conf

配置文件参数说明

LVS 一般和 keepalived 搭配使用,LVS 配置写在 keepalived 的配置文件中

## 全局配置,用于日志、调试、邮件通知等目的
global_defs {
    ## router_id 是 Keepalived 的 全局标识符
    router_id LVS_DEVEL
}

## 定义一个 LVS 虚拟服务(VIP + 端口),192.168.189.100 是虚拟 IP(VIP),80 是端口。
virtual_server 192.168.189.100 80 {
    ## 每 5 秒执行一次健康检查。值越小,检测频率越高,发现异常越快,但系统负担也会稍高。
    delay_loop 5
	## 指定使用什么 负载均衡算法
    lb_algo wrr
	## 指定负载均衡的转发工作模式
    lb_kind DR
    ## 设置客户端 IP 的掩码,用于判定哪些请求来自“同一个客户端子网”。nat_mask 255.255.255.0 表示 LVS 只看客户端 IP 地址的前 24 位(即 a.b.c.*),这意味着来自同一个子网(如 192.168.1.x)的所有客户端请求会被认为是来自同一客户端,并会被转发到同一个 real server。例如:如果两个客户端 IP 分别是 192.168.1.10 和 192.168.1.20,它们被认为来自同一个子网。LVS 会将它们的请求始终转发到同一个后端 real server(在持久连接有效时间内,即 persistence_timeout)。
    nat_mask 255.255.255.0
	## 保持客户端连接的会话粘性,单位是秒,同一客户端在 60 秒内的请求都发送到同一台后端服务器。
    persistence_timeout 60
	## 该虚拟服务处理的是 TCP 协议的请求(如 HTTP、HTTPS、MySQL等)
    protocol TCP

    ## 定义一台真实后端服务器,监听 IP 为 192.168.189.135,端口 80。
    real_server 192.168.189.135 80 {
        ## 权重为 3(配合上面的 wrr 算法使用),3:表示这个服务接收3个请求
        weight 3
		## 健康检查(TCP 方式)
        TCP_CHECK {
		    ## 每次 TCP 连接检测最多等待 3 秒,3秒后就连接超时
            connect_timeout 3
			## 最多尝试连接 3 次
            nb_get_retry 3
			## 重试前延迟时间,每次失败后等待 2 秒再重试
            delay_before_retry 2
			## 检查端口(默认是 real_server 的端口)
            connect_port 80
        }
    }

    ## 定义一台真实后端服务器,监听 IP 为 192.168.189.136,端口 80。
    real_server 192.168.189.136 80 {
	    ## 权重为 2(配合上面的 wrr 算法使用),2:表示这个服务接收2个请求
        weight 2
        TCP_CHECK {
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 2
            connect_port 80
        }
    }

    ## 定义一台真实后端服务器,监听 IP 为 192.168.189.137,端口 8080。
    real_server 192.168.189.137 8080 {
        weight 1
        # 健康检查(HTTP GET 请求)
        HTTP_GET {
            url {
			    ## 检查的路径,例如 /healthz,你需要在该服务器上部署这个路径返回 200,例如:GET http://<real_server_ip>:80/healthz
                path /healthz
				## 响应体的 MD5 值,匹配这个 hash 才算健康,防止假回包。d41d8cd98f00b204e9800998ecf8427e:是空字符串("")的 MD5 值,即后端什么也不返回时的 MD5 值,这个值可以自定义
                digest d41d8cd98f00b204e9800998ecf8427e
            }
			## 每次 TCP 连接检测最多等待 3 秒,3秒后就连接超时
            connect_timeout 3
			## GET 请求失败后重试次数
            nb_get_retry 3
			## 重试前延迟时间,每次失败后等待 2 秒再重试
            delay_before_retry 2
			## 请求的端口
            connect_port 8080
        }
    }
}

HTTP_GET 健康检查 Restful API 示例:

1. 定义一个 get 接口

@RestController
public class HealthCheckController {

    @GetMapping("/healthz")
    public String healthCheck() {
        return "AAABBBCCC";
    }
}

2. 计算返回值的 MD5(用于 digest)

现在后端返回的是 "AAABBBCCC",你可以在 Linux 或 macOS 终端中执行:

echo -n "AAABBBCCC" | md5sum

输出:6207b5df5796e963410d3bc4b6a4218b  - 

把这个值配置在 HTTP_GET 健康检查的 digest 属性中,如下:

HTTP_GET {
    url {
        path /healthz
        digest 6207b5df5796e963410d3bc4b6a4218b
    }
    ......
}

LVS 状态同步

查看状态是否同步

ipvsadm -L --daemon

显示如下:(syncid=0:表示当前的节点没有设置同步ID或没有正常启动连接同步守护进程)

master sync daemon (mcast=ens33, syncid=0, maxlen=1472, group=224.0.0.81, port=8848, ttl=1)

Master 节点开启同步(ens33是实际的物理网络接口名称,不是 lo。同一集群中的 syncid 1 要设置一致)

ipvsadm --start-daemon master --mcast-interface=ens33 --syncid 1

Backup 节点开启同步

ipvsadm --start-daemon backup --mcast-interface=ens33 --syncid 1

Master 节点关闭同步

ipvsadm --stop-daemon master

Backup 节点关闭同步

ipvsadm --stop-daemon backup

Keepalived + LVS + Nginx 实现 高可用 + 负载均衡

  • 主节点:192.168.189.135,优先级为 100
  • 备节点:192.168.189.136,优先级为 90
  • 第三节点:192.168.189.137,优先级为 80

1. 主节点(192.168.189.135)配置

sudo vim /etc/keepalived/keepalived.conf

global_defs {
   router_id LVS_NODE1
}

vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 51
    priority 100
    advert_int 1

    unicast_src_ip 192.168.189.135
    unicast_peer {
        192.168.189.136
        192.168.189.137
    }

    authentication {
        auth_type PASS
        auth_pass 123456
    }

    virtual_ipaddress {
        192.168.189.100
    }
}

virtual_server 192.168.189.100 80 {
    delay_loop 5
    lb_algo rr
    lb_kind DR
    nat_mask 255.255.255.0
    persistence_timeout 60
    protocol TCP

    real_server 192.168.189.135 80 {
        weight 1
        TCP_CHECK {
            connect_timeout 5
            nb_get_retry 3
            delay_before_retry 3
        }
    }

    real_server 192.168.189.136 80 {
        weight 1
        TCP_CHECK {
            connect_timeout 5
            nb_get_retry 3
            delay_before_retry 3
        }
    }

    real_server 192.168.189.137 80 {
        weight 1
        TCP_CHECK {
            connect_timeout 5
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}

重启 keepalived

sudo systemctl restart keepalived

2. 备节点(192.168.189.136)配置

sudo vim /etc/keepalived/keepalived.conf

global_defs {
   router_id LVS_NODE2
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 51
    priority 90
    advert_int 1

    unicast_src_ip 192.168.189.136
    unicast_peer {
        192.168.189.135
        192.168.189.137
    }

    authentication {
        auth_type PASS
        auth_pass 123456
    }

    virtual_ipaddress {
        192.168.189.100
    }
}

virtual_server 192.168.189.100 80 {
    delay_loop 5
    lb_algo rr
    lb_kind DR
    nat_mask 255.255.255.0
    persistence_timeout 60
    protocol TCP

    real_server 192.168.189.135 80 {
        weight 1
        TCP_CHECK {
            connect_timeout 5
            nb_get_retry 3
            delay_before_retry 3
        }
    }

    real_server 192.168.189.136 80 {
        weight 1
        TCP_CHECK {
            connect_timeout 5
            nb_get_retry 3
            delay_before_retry 3
        }
    }

    real_server 192.168.189.137 80 {
        weight 1
        TCP_CHECK {
            connect_timeout 5
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}

重启 keepalived

sudo systemctl restart keepalived

3. 备节点(192.168.189.137)配置

sudo vim /etc/keepalived/keepalived.conf

global_defs {
   router_id LVS_NODE3
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 51
    priority 80
    advert_int 1

    unicast_src_ip 192.168.189.137
    unicast_peer {
        192.168.189.135
        192.168.189.136
    }

    authentication {
        auth_type PASS
        auth_pass 123456
    }

    virtual_ipaddress {
        192.168.189.100
    }
}

virtual_server 192.168.189.100 80 {
    delay_loop 5
    lb_algo rr
    lb_kind DR
    nat_mask 255.255.255.0
    persistence_timeout 60
    protocol TCP

    real_server 192.168.189.135 80 {
        weight 1
        TCP_CHECK {
            connect_timeout 5
            nb_get_retry 3
            delay_before_retry 3
        }
    }

    real_server 192.168.189.136 80 {
        weight 1
        TCP_CHECK {
            connect_timeout 5
            nb_get_retry 3
            delay_before_retry 3
        }
    }

    real_server 192.168.189.137 80 {
        weight 1
        TCP_CHECK {
            connect_timeout 5
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}

重启 keepalived

sudo systemctl restart keepalived

# 如果想要测试负载均衡时即时看到效果,就先去掉这2个属性    nat_mask、persistence_timeout


所有节点都配置完成后,使用 ipvsadm 查看当前的 LVS 配置

sudo ipvsadm -L -n

显示如下内容,表示 LVS 配置成功

IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.189.100:80 rr persistent 60
  -> 192.168.189.135:80           Route   1      3          0         
  -> 192.168.189.136:80           Route   1      3          0         
  -> 192.168.189.137:80           Route   1      3          0 

参数说明:

TCP  192.168.189.100:80 rr

部分含义
TCPLVS 监听的是 TCP 协议(也可能是 UDP)
192.168.189.100:80虚拟 IP 和端口,表示用户访问的目标(VIP:Port)
rr负载均衡算法,这里是 round-robin(轮询调度)

-> 192.168.189.135:80           Route   1      3          0

字段位置字段含义说明
->后端 Real Server表示这是一个转发目标(后端服务器)
192.168.189.135:80Real Server IP 和端口LVS 将请求转发到这里
Route转发方式这里是 DR 模式(直接路由)
1权重 (weight)表示调度器给此 Real Server 分配的权重
3活跃连接数 (active conn)当前连接到此 Real Server 的客户端连接数
0不活跃连接数 (inactive conn)表示已完成但仍保持连接的 TCP 会话(如等待关闭)

如果你看到多个后端的活跃连接数一致(比如每台都是 3),说明 LVS 负载均衡配置是生效的


4. 把 VIP 绑定到本机的 loopback 网卡(lo),(在所有节点上执行)

注意:DR 模式下 VIP 一定是绑定在 lo 上,并加上 /32。(192.168.189.100 ip 已经在 ens33 网卡上了,现在再绑定到 lo 上会出现 ARP 冲突问题,等会我们要解决这个问题)

使用 ip a 命令可以查看每个网卡上绑定的 ip

方式一:(临时的,不推荐)

sudo ip addr add 192.168.189.100/32 dev lo

参数说明:

ip addr add添加一个 IP 地址
192.168.189.100/32要添加的 IP 地址,/32 表示只有这一个 IP(子网掩码是 255.255.255.255
dev lo添加到 lo 网卡上,也就是本机的回环接口

命令执行完成后,显示如下内容,lo 下出现了 192.168.189.100,但是 ens33 之前就存在 192.168.189.100,这样就参数了 ARP 冲突。

启用本地回环网卡 lo 接口(默认应该就是开启状态):

sudo ip link set lo up

方式二:(永久的,推荐)

创建一个新的 systemd 服务文件

sudo vim /etc/systemd/system/vip-setup.service

在文件中添加如下内容:

[Unit]
Description=Setup VIP on lo interface
After=network.target

[Service]
Type=oneshot
ExecStart=/usr/sbin/ip addr add 192.168.189.100/32 dev lo

[Install]
WantedBy=multi-user.target

启动服务、开机自启动

sudo systemctl daemon-reload
sudo systemctl enable vip-setup.service
sudo systemctl start vip-setup.service

5. 处理 ARP 冲突问题(在所有节点上执行)

arp_ignore=1:表示只对目标是本地地址的 ARP 请求进行响应,即只有当请求目标是该机器的某个接口时,才会响应 ARP 请求。

arp_announce=2:表示选择具有最优 IP 地址的接口来回应 ARP 请求,通常避免 lo 上的 IP 与其他真实网卡的 IP 冲突。

all:所有的网络接口(包括 lo、eth0、ens33 等)默认 ARP 策略(全局)

创建配置文件(永久生效的方式)

sudo vim /etc/sysctl.d/99-lvs.conf

文件内容如下:

net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2

重新加载所有 sysctl 配置,包括你刚才创建的 99-lvs.conf

sudo sysctl --system

查看配置是否生效

cat /proc/sys/net/ipv4/conf/lo/arp_ignore
cat /proc/sys/net/ipv4/conf/lo/arp_announce
cat /proc/sys/net/ipv4/conf/all/arp_ignore
cat /proc/sys/net/ipv4/conf/all/arp_announce

6. 配置 Nginx

在所有节点上配置Nginx实例,配置一个普通的可以访问静态页面的80端口(因为我们上面配置文件 real_server 监听的是 80 端口)地址即可。

Nginx 示例配置请查看:Nginx配置


7. 测试 Keepalived + LVS + Nginx 实现 高可用 + 负载均衡

浏览器访问:http://192.168.189.100,可以看到,流量负载到每一台机器上面了,达到了负载均衡的目的。

当我们停掉 2 台机器的时候,发现还有 1 台机器在正常运行,达到了高可用的目的。

注意,节点切换为 Master 的过程中通常会出现短暂的服务不可达现象。这是一主架构的正常现象,因为VIP迁移、ARP 广播、LVS 的连接状态,它们的切换都要时间。想要解决这个问题,使用多主架构(多主热备)的方式即可(当然也会产生其他问题),什么是多主架构:每台服务器既是自己 VIP 的 MASTER,又是其它 VIP 的 BACKUP,这样实现多个 VIP,同时负载均衡、互为备份。。。配置太多了,这里就不再配置了,实际工作中百分之90的加工作5年的程序员不是在大厂都用不上。用到的自行搜索一下吧很简单的,本文就到这里了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

7 号

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值