面试时不会LVS技术?看完这篇文章,对面试官说LVS包会的啊!

0. 引言

随着互联网技术的快速发展,使多媒体网络服务器面对的访问数量快速增加,服务器需要具备提供大量并发访问服务的能力,因此对于大负载的服务器来讲, CPU、I/O处理能力很快会成为瓶颈。

由于单台服务器的性能总是有限的,简单的提高硬件性能并不能真正解决这个问题。为此,必须采用多服务器负载均衡才能满足大量并发访问的需要。

1. LVS介绍

1.1 什么是LVS?

Linux虚拟服务器(Linux Virtual Server,简称LVS)是一种基于Linux操作系统的负载均衡解决方案。它通过将请求分发到多个后端服务器上,实现高可用性和可扩展性。其他负载均衡服务器还有Nginx,Haproxy,F5,Netscale等。

1.2 技术术语

名称简称说明
客户端IPCIP客户端的IP地址
调度器(Director Server)DS前端负载均衡器节点
虚拟IP(Virtual IP)VIP向外部面向用户请求,作为用户请求的目标IP地址
控制器服务器IP(Director Server IP)DIP用于与内部主机通讯的IP地址
真实服务器(Real Server)RS处于内部提供服务的主机
真实服务器IP(Real Server IP)RIP内部服务器的IP地址
持久连接同一时间段内的同一个来源的服务请求 调度到 RS 上

2. LVS的三个模式

根据LVS使用模式的不同,其原理也有所不同

2.1 NAT模式

2.1.1 简介

NAT(Network Address Translation)即网络地址转换,其作用是通过数据报头的修改,使得位于企业内部的私有IP地址可以访问外网,以及外部用用户可以访问位于公司内部的私有IP主机。

2.1.2 原理

便于快速掌握术语具体的含义,列出下方表格(仅展示一次)

名称术语
WebRS、RIP
调度器DS、eth0(DIP)、eth1(VIP)
互联网用户CIP

在这里插入图片描述

​ 第一步,用户访问公司调度器的外网地址,相对于真实服务器而言,调度器的IP又称VIP,用户通过访问VIP,即可连接后端的真实服务器,而这一切对用户而言都是透明的,用户以为自己访问的就是真实服务器,但他并不知道自己访问的VIP仅仅是一个调度器,也不清楚后端的真实服务器到底在哪里、有多少真实服务器

第二步,用户将请求发送至124.126.147.168,此时LVS将根据预设的算法选择后端的一台真实服务器(192.168.0.1~192.168.0.3),将数据请求包转发给真实服务器,并且在转发之前LVS会修改数据包中的目标地址以及目标端口,目标地址与目标端口将被修改为选出的真实服务器IP地址以及相应的端口

# 源地址 和 源端口保持不变
# 目标地址:VIP --> 选出的真实服务器的IP
# 目标端口:DS的端口 --> 选出的真实服务器的端口

​ 第三步,真实的服务器将响应数据包返回给LVS调度器,调度器在得到响应的数据包后将源地址和源端口修改为VIP及调度器相应的端口,修改完成后,由调度器将响应数据包发送回终端用户

# 源地址 --> VIP
# 源端口 --> DS对应端口
# 目标地址 和 目标端口 :客户端IP 未做改变

另外,由于LVS调度器有一个连接Hash表,该表中会记录连接请求及转发信息,当同一个连接的下一个数据包发送给调度器时,从该Hash表中可以直接找到之前的连接记录,并根据记录信息选出相同的真实服务器及端口信息

2.3 TUN模式

2.3.1 简介

在LVS(NAT)模式的集群环境中,由于所有的数据请求及响应的数据包都需要经过LVS调度器转发,如果后端服务器的数量大于10台,则调度器就会成为整个集群环境的瓶颈

因此LVS(TUN)的思路就是将请求与响应数据分离,让调度器仅处理数据请求,而让真实服务器响应数据包直接返回给客户端

2.3.2 原理

在这里插入图片描述

IP隧道(IP Tunning)是一种数据包封装技术,它可以将原始数据包封装并添加新的包头,从而实现将一个目标为调度器的VIP地址的数据包封装,通过隧道转发给后端的真实服务器

LVS(TUN)模式要求真实服务器可以直接与外部网络连接,真实服务器在收到请求数据包后直接给客户端主机响应数据

客户端向VIP发出服务请求,调度器通过某种算法选出对应的RS,并转发数据包

DS在转发之前,在原数据包的基础上,封装新的源地址:DIP,目的地址:RIP

RS收到数据包后,解开DS的封装,并响应客户端的请求,发送响应数据包(源地址:DIP,目的地址:CIP)

整个过程中,数据包的端口均保持不变

2.2 DR模式

2.2.1 简介

在LVS(TUN)模式下,需要DS与RS之间创建隧道连接,这同样会增加服务器的负担。

与LVS(TUN)类似,DR模式也叫直接路由模式,该模式中LVS依然仅承担数据的入站请求以及根据算法选出合理的真实服务器,最终由后端真实服务器负责将响应数据包发送返回给客户端。

2.2.2 原理

在这里插入图片描述

直接路由模式(DR模式)要求调度器与后端服务器必须在同一个局域网内,VIP地址需要在调度器与后端所有的服务器间共享

由于多台计算机都设置了同样一个VIP地址,而调度器的VIP地址需要对外可见,因为客户端需要把服务请求发送到调度器上

而后端的服务器的VIP地址必须配置在Non-ARP的网络设备上,即网络设备并不会向外广播自己的MAC及对应的IP地址,因此服务器的VIP对外界是不可见的,但服务器可以接受目标地址:VIP的网络请求,并在回应数据包时将源地址设置为该VIP地址

客户端向DS的VIP发出服务请求,DS响应请求,并根据算法,将请求转发到后端的RS

转发之前,DS修改数据包的源MAC:DIP ;目MAC: RIP

RS收到数据包后,发送响应数据包给客户端(源IP:VIP 目IP:CIP ; 源MAC:DIP-MAC 目MAC:CIP-MAC)

在这里插入图片描述

3. LVS的十种调度算法

不管实际环境中采用的是哪种模式,调度算法进行调度的策略与算法都是LVS的核心技术

3.1 静态调度算法

3.1.1 rr:轮询

轮询调度(Round Robin 简称RR)算法:按依次循环的方式将请求调度到不同的服务器上,该算法最大的特点就是实现简单。轮询算法假设所有的服务器处理请求的能力都是一样的,调度器会将所有的请求平均分配给每个真实服务器。

3.1.2 WRR:加权轮询

加权轮询(Weight Round Robin 简称WRR)算法:主要是对轮询算法的一种优化与补充,LVS会考虑每台服务器的性能,并给每台服务器添加一个权值,如果服务器A的权值为1,服务器B的权值为2,则调度器调度到服务器B的请求会是服务器A的两倍。权值越高的服务器,处理的请求越多。

3.1.3 DH:目标地址散列调度

目标地址散列调度(Destination Hashing 简称DH)算法:先根据请求的目标IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且并未超载,将请求发送到该服务器,否则返回空。

3.1.4 SH:源地址散列调度

源地址散列调度(Source Hashing 简称SH)算法:先根据请求的源IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且并未超载,将请求发送到该服务器,否则返回空。

3.2 动态调度算法

3.2.1 LC:最小连接调度

最小连接调度(Least Connections 简称LC)算法:把新的连接请求分配到当前连接数最小的服务器。最小连接调度是一种动态的调度算法,它通过服务器当前活跃的连接数来估计服务器的情况。调度器需要记录各个服务器已建立连接的数目,当一个请求被调度到某台服务器,其连接数加1;当连接中断或者超时,其连接数减1。

3.2.2 WLC:加权最少连接

加权最少连接(Weight Least Connections 简称WLC)算法:是最小连接调度的超集,各个服务器相应的权值表示其处理性能。服务器的默认权值为1,系统管理员可以动态地设置服务器的权值。加权最小连接调度在调度新连接时尽可能使服务器的已建立连接数和其权值成比例。调度器可以自动检测真实服务器的负载情况,并动态地调整其权值。

3.2.3 LBLC:基于局部的最少连接调度

基于局部的最少连接调度(Locality-Based Least Connections 简称LBLC)算法:是针对目标IP地址的负载均衡调度,先根据请求的目标IP地址找出该目标IP地址最近使用的服务器,若该服务器是可用的且没有超载,将请求发送到该服务器;若服务器不存在,或者该服务器超载且有服务器处于一半的工作负载,则使用 “最少连接” 的原则选出一个可用的服务器,将请求发送到服务器。

(目前主要用于Cache集群系统,因为Cache集群客户请求报文的目标IP地址是变化的)

(LBLC算法维护从一个目标IP地址到一台服务器的映射)

3.2.4 LBLCR:带复制的基于局部性的最少连接

带复制的基于局部性的最少连接(Locality-Based Least Connections with Replication 简称LBLCR)算法:是针对目标IP地址的负载均衡,它与LBLC算法不同之处是它要维护从一个目标IP地址到一组服务器的映射。算法按 ”最小连接“ 原则从服务器组中选出一台服务器,若服务器没有超载,将请求发送到该服务器;若服务器超载,则按 “最小连接” 原则从整个集群中选出一台服务器,将该服务器加入到服务器组中,将请求发送到该服务器。同时,当服务器组有一段时间没有被修改,将最忙的服务器从服务器组中删除,以降低复制的程度。

(同样主要用于Cache集群系统中)

3.2.5 SED:最短期望延迟调度

最短的期望的延迟调度(Shortest Expected Delay 简称SED)算法:尽可能让权重高的优先接收请求,不再考虑非活动状态,把当前处于活动状态的数目+1,通过算法计算当前连接数最少的节点,而后将新的请求调度至该节点。

3.2.6 NQ:最少队列调度

最少队列调度(Never Queue 简称NQ)算法:SED 算法存在的问题是,由于某台服务器的权重较小,比较空闲,甚至接收不到请求,而权重大的服务器会很忙,而 NQ 算法是说不管权重多大都会被分配到请求。简单来说,就是无需队列,如果有台 RS 的连接数为 0 会直接分配过去,后续分配采用 SED 算法。

4. ipvsadm 参数

4.1 介绍

ipvsadm是一个用于配置和管理Linux内核中IPVS模块的命令行工具。它允许管理员通过命令行界面动态地配置负载均衡规则,包括添加、删除和修改虚拟服务、服务器池、调度算法等。

4.2 目录信息

程序名:ipvsadm 服务名:ipvsadm.service

目录说明
/usr/sbin/ipvsadm主程序
/usr/sbin/ipvsadm-save规则保存工具
/usr/sbin/ipvsadm-restore规则重载工具
/etc/sysconfig/ipvsadm-config配置文件
/etc/sysconfig/ipvsadmipvs调度规则文件

4.3 VIP相关

语法格式

ipvsadm -A|E -t|u|f service-address [-s scheduler] [-p [timeout]]
参数说明
A添加
E修改
tTCP服务
uUDP服务
fFirewall mask 火墙标记 是一个数字
s指定调度算法,默认为WLC(加权最少连接)
p设置持久连接超时
ipvsadm -A -t 192.168.0.100:443 -s rr

4.4 VIP+RIP相关

语法格式

ipvsadm -a|e -t|u|f service-address -r realserver-address [-g|i|m] [-w weight]
参数说明
a添加realserver
e更改realserver
tTCP协议
uUDP协议
f火墙标签
rRS地址
gDR模式
iTUN模式
mNAT模式
w设置权重
Z清空计数器
C清空LVS策略
L查看LVS策略
n不做解析
–rate输出速率信息
ipvsadm -a -f 192.168.0.100:443 -r 192.168.0.20:443 -m
ipvsadm -a -f 192.168.0.100:443 -r 192.168.0.20:443 -m -w 2

ipvsadm -Ln ; ipvsadm -C 

5.LVS实战

5.1 NAT模式部署

5.1.1 部署图

在这里插入图片描述

5.1.2 开始部署
客户端
vim /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
id=eth0
type=ethernet
interface-name=eth0

[ipv4]
address1=172.25.254.10/24,172.25.254.100
method=manual

nmcli connection reload
nmcli connection up eth0
调度器
vim /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
id=eth0
type=ethernet
interface-name=eth0

[ipv4]
address1=172.25.254.10/24
method=manual

vim /etc/NetworkManager/system-connections/eth1.nmconnection
[connection]
id=eth1
type=ethernet
interface-name=eth1

[ipv4]
address1=192.168.0.100/24
method=manual

nmcli connection reload
nmcli connection up eth0
nmcli connection up eth1

# 打开路由内核功能
echo net.ipv4.ip_forward=1 >> /etc/sysctl.conf;sysctl -p

# 安装  IPVS  管理工具  
dnf install ipvsadm -y

# 添加策略,分配权重,使用轮询算法(可根据个人需求选择不同算法)
ipvsadm -A -t 192.168.0.100:80 -s rr # VIP
ipvsadm -a -t 192.168.0.100:80 -r 192.168.0.10:80 -m # VIP + 服务器IP
ipvsadm -a -t 192.168.0.100:80 -r 192.168.0.10:80 -m # VIP + 服务器IP

# 查看策略
ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.0.100:80 rr
  -> 192.168.0.10:80              Masq    1      0          0         
  -> 192.168.0.20:80              Masq    1      0          0         

服务器
# Server1
vim /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
id=eth0
type=ethernet
interface-name=eth0

[ipv4]
address1=192.168.0.10/24,192.168.0.100
method=manual

# Server2
vim /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
id=eth0
type=ethernet
interface-name=eth0

[ipv4]
address1=192.168.0.20/24,192.168.0.100
method=manual

# 均使网卡配置生效
nmcli connection reload
nmcli connection up eth0

yum install httpd -y	# 安装HTPP服务
systemctl stop firewalld;systemctl mask firewalld	# 关闭防火墙并防止其他应用启动防火墙
grubby --update-kernel ALL--args selinux=0	# 关闭SELinux

# 修改HTTP的默认页面
echo Server - 192.168.0.10 > /var/www/html/index.html # Server1
echo Server - 192.168.0.20 > /var/www/html/index.html # Server2

# HTTP服务立即启动且开机自启
systemctl enable --now httpd.service
5.1.3 测试
[root@Client ~]# for i in {1..10}; do curl 192.168.0.100; done
Server - 192.168.0.20
Server - 192.168.0.10
Server - 192.168.0.20
Server - 192.168.0.10
Server - 192.168.0.20
Server - 192.168.0.10
Server - 192.168.0.20
Server - 192.168.0.10
Server - 192.168.0.20
Server - 192.168.0.10

# 修改策略,使用算法:WRR
ipvsadm -E -t 192.168.0.100:80 -s wrr
ipvsadm -e -t 192.168.0.100:80 -r 192.168.0.10:80 -m -w 1
ipvsadm -e -t 192.168.0.100:80 -r 192.168.0.20:80 -m -w 2
ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.0.100:80 wrr
  -> 192.168.0.10:80              Masq    1      0          0         
  -> 192.168.0.20:80              Masq    2      0          0 

[root@Client ~]# for i in {1..10}; do curl 192.168.0.100; done
Server - 192.168.0.20
Server - 192.168.0.10
Server - 192.168.0.20
Server - 192.168.0.20
Server - 192.168.0.10
Server - 192.168.0.20
Server - 192.168.0.20
Server - 192.168.0.10
Server - 192.168.0.20
Server - 192.168.0.20
# 算法和权重均成功生效

5.2 DR模式部署

5.2.1 部署图

在这里插入图片描述

5.2.2 开始部署
客户端
# 假设网卡名字为eth0
vim /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
id=eth0
type=ethernet
interface-name=eth0

[ipv4]
address1=172.25.254.200/24,172.25.254.100
method=manual

nmcli connection reload
nmcli connection up eth0 
路由器
# 打开路由内核功能
echo net.ipv4.ip_forward=1 >> /etc/sysctl.conf;sysctl -p

# 假设(NAT)网卡名字为eth0
vim /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
id=eth0
type=ethernet
interface-name=eth0

[ipv4]
address1=172.25.254.100/24
method=manual

# 假设(仅主机)网卡名字为eth1
vim /etc/NetworkManager/system-connections/eth1.nmconnection
[connection]
id=eth1
type=ethernet
interface-name=eth1

[ipv4]
address1=192.168.0.100/24
method=manual

# 使配置的网卡生效
nmcli connection reload
nmcli connection up eth0
nmcli connection up eth1
调度器
# 假设(仅主机)网卡名字为eth0
vim /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
id=eth0
type=ethernet
interface-name=eth0

[ipv4]
address1=192.168.0.50/24,192.168.0.100
method=manual

# 设置VIP
ip addr add dev lo 192.168.0.200/32 # 注意掩码 32,临时添加VIP,重启后失效

# 安装  IPVS  管理工具  
dnf install ipvsadm -y

# 添加策略,分配权重,使用轮询算法(可根据个人需求选择不同算法)
ipvsadm -A -t 192.168.0.200:80 -s rr # VIP
ipvsadm -a -t 192.168.0.200:80 -r 192.168.0.10:80 -g -w 1 # VIP + 服务器IP
ipvsadm -a -t 192.168.0.200:80 -r 192.168.0.20:80 -g -w 2 # VIP + 服务器IP

# 查看策略
ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.0.200:80 rr
  -> 192.168.0.10:80              Route   1      0          0         
  -> 192.168.0.20:80              Route   2      0          0   

# 使配置的网卡生效
nmcli connection reload
nmcli connection up eth0      
服务器
# 假设为HTTP服务器,端口:80
# Server1 : 假设(仅主机)网卡名字为 eth0
vim /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
id=eth0
type=ethernet
interface-name=eth0

[ipv4]
address1=192.168.0.10/24,192.168.0.100
method=manual

# Server2 : 假设(仅主机)网卡名字为 eth0
vim /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
id=eth0
type=ethernet
interface-name=eth0

[ipv4]
address1=192.168.0.20/24,192.168.0.100
method=manual


yum install httpd -y	# 安装HTPP服务
ip addr add dev lo 192.168.0.200/32	# 配置VIP
systemctl stop firewalld;systemctl mask firewalld	# 关闭防火墙并防止其他应用启动防火墙
grubby --update-kernel ALL--args selinux=0	# 关闭SELinux

# 修改HTTP的默认页面
echo Server - 192.168.0.10 > /var/www/html/index.html # Server1
echo Server - 192.168.0.20 > /var/www/html/index.html # Server2

# 创建Non-ARP环境 临时配置,重启失效
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce

# 使配置的网卡生效,使得HTTP服务立即启动且开机自启
nmcli connection reload
nmcli connection up eth0
systemctl enable --now httpd.service
5.2.3 测试
[root@Client ~]# for i in {1..10}; do curl 192.168.0.200; done
Server - 192.168.0.20
Server - 192.168.0.10
Server - 192.168.0.20
Server - 192.168.0.10
Server - 192.168.0.20
Server - 192.168.0.10
Server - 192.168.0.20
Server - 192.168.0.10
Server - 192.168.0.20
Server - 192.168.0.10
# 两台服务器权重不同,但算法是RR,故权重此时不会生效

6.LVS扩展

6.1 防火墙标签解决轮询错误

  • 同时开放多个端口(80、443等)时,默认控制是分开轮询的,这样会出现一个轮询错误的问题
  • 当访问80时,轮询到RS1;下次访问443,依然轮询到RS1(实际应轮询到RS2)
6.1.1 问题展示
# RS均安装Mod_ssl 并重启apache 开放两个端口
yum install mod_ssl -y
systemctl restart httpd

# 设置两组策略
ipvsadm -C
ipvsadm -A -t 192.168.0.100:80 -s rr
ipvsadm -a -t 192.168.0.100:80 -r 192.168.0.10:80 -m
ipvsadm -a -t 192.168.0.100:80 -r 192.168.0.20:80 -m

ipvsadm -A -t 192.168.0.100:443 -s rr
ipvsadm -a -t 192.168.0.100:443 -r 192.168.0.10:443 -m
ipvsadm -a -t 192.168.0.100:443 -r 192.168.0.20:443 -m

ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.0.100:80 rr
  -> 192.168.0.10:80              Masq    1      0          0         
  -> 192.168.0.20:80              Masq    1      0          0         
TCP  192.168.0.100:443 rr
  -> 192.168.0.10:443             Masq    1      0          0         
  -> 192.168.0.20:443             Masq    1      0          0 

# 测试问题
[root@Client ~]# curl http://192.168.0.100;curl -k https://192.168.0.100
Server - 192.168.0.10	# 请求发送正确
Server - 192.168.0.10	# 请求应发送给 192.168.0.20 服务器
6.1.2 解决方法
# 调度器中设置端口标签,将端口80和443视为一个整体
iptables -t mangle -A PREROUTING -d 192.168.0.100 -p tcp -m multiport --dports 80,443 -j MARK --set-mark 1314

# 修改策略
ipvsadm -C
ipvsadm -A -f 1314 -s rr
ipvsadm -a -f 1314 -r 192.168.0.10 -m
ipvsadm -a -f 1314 -r 192.168.0.20 -m
6.1.3 测试
[root@Client ~]# curl http://192.168.0.100;curl -k https://192.168.0.100
Server - 192.168.0.20	# 请求发送正确
Server - 192.168.0.10	# 请求发送正确

6.2 LVS持久连接

当客户填写表单时,退出一段时间后,再次访问RS,会被调度到另一个RS上,导致客户填写的表单丢失

6.2.1 解决方法

进行调度时,不管用什么算法,只要是相同源IP发送的服务请求,就把此IP的访问记录记录(源IP — RS)在内存中

只要此IP在一定时间(默认360s)内,再次发送服务请求,则根据内存中的访问记录调度到同一台RS上

一但超出时间后,再次发送服务请求,则根据算法调度到其他RS上

# 调度器
ipvsadm -E -f 1314 -s rr -p 1

6.3 LVS Fullnet 模式

在这里插入图片描述

特点:

  • VIP属于公网,RIP、DIP属于私网,且不在同一网络中,故RIP的网关不会指向DIP
  • RS收到请求后,需要响应给DIP,然后由VIP将响应报文发送给Client
  • 请求和响应均需要由RS处理
  • 支持端口映射

6.4 LVS新增算法

以下为LVS 4.15内核之后,新增的算法

FO

FO(Weighted Fai Over)调度算法:常用作灰度发布 在此FO算法中,遍历虚拟服务所关联的真实服务器链表,找到还未过载的且权重最高的真实服务器,进行调度。当服务器承接大量链接,我们可以对此服务器进行过载标记,那么调度器就不会把链接调度到有过载标记的主机中

OVF

基于真实服务器的活动连接数量和权重值实现。将新连接调度到权重值最高的真实服务器,直到其活动连接数量超过权重值,之后调度到下一个权重值最高的真实服务器,在此OVF算法中,遍历虚拟服务相关联的真实服务器链表,找到权重值最高的可用真实服务器。一个可用的真实服务器需要同时满足以下条件: 未过载;真实服务器当前的活动连接数量小于其权重值;其权重值不为零

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值