系统级优化

以下优化仅供参考,具体根据实际情况来定。(误犯

系统级调优

系统级调优分为硬件调优和kernel调优。

硬件调优的主要对象为(4大子系统)

  • CPU
  • Memory
  • IO
  • Networking

CPU调优方法

CPU中包括了三部分:用户空间(User Space)、内核空间(Kernel Space)、硬件

CPU中的名词

CPU是一个7X24小时的员工, 每时每刻都有工作在做(进程、线程),工作太多了就会有一张工作清单(运行
队列
),由老板(进程调度)来决定他该干什么,他需要和老板沟通以便得到老板的想法并及时调整自己的
工作(上下文切换),停止一个工作转而执行另一个工作,部分工作做完以后还需要及时向老板汇报(
),所以CPU除了做自己该做的工作以外,还有大量时间和精力花在沟通和汇报上。

查看cpu硬件信息的常见命令

# cat /proc/cpuinfo
# lscpu

在实际调优中, 我们更需要的是采集CPU当前的实时运行数据,常见的命令有:

  • top
  • uptime
  • vmstat
  • mpstat
  • sar
怎么样才认为需要对CPU进行优化

一般来说User Time的使用率大概是65%~70%

System Time的使用率:30%~35%

Idle的使用率:0%~5%

如果CPU的Idle值非常低(非常接近0%), 运行队列也比较大(负载过高), 则说明CPU有点忙不过来了

如果 User time 过高,则考虑用户空间程序(也就是本服务器跑的应用程序,如nginx,php,tomcat,mysql
等)是否有优化的空间

如果 System Time 过高

  • %iowait 高,这时要重点关注磁盘IO的相关操作,是否存在不合理的文件写操作,日志写操作,数据
    库写操作等;
  • %soft或%cs高,网卡流量是否较大,可不可以精简数据,代码在是否在多线程操作上存在不合适的中
    断操作等
  • %steal 高,这种情况一般发生在有虚拟化的, 这时要查看宿主机是否资源超限;

如果一切都是正常的, 但就是CPU忙不过来,成为了瓶颈。这个时候我们就需要优化了。

怎么优化

横向扩展:看是否将应用的一部分负载转移到其他服务器(LB,分表分库,读写分离等)

纵向扩展:换更好的CPU(可了解SMP、NUMA、MPP架构)

微调

微调的方法主要包括
  • 进程优先级调整,将重要的进程优先级调高,以占用更多的CPU资源
  • cpu亲和性
进程优先级

优先级高的进程能够优先分配资源,跑得快,花费的时间少(高负载的情况下,效果更明显)

注意:只有管理员才能把优先级往高调,普通用户只能调自己的,并且只能往低调,调低后还不能再调高

cpu的亲和性

可以人为的控制进程去到指定的内核上

taskset命令可以将进程绑核,格式为 taskset -p -c cpu-list pid ,其中cpu-list是数字化的cpu列表,从0开始。多个不连续的cpu可用逗号连接,连续的可用 - 连接,比如0,2,5-11等 。

[root@localhost ~]# taskset -c 2 sh /tmp/1.sh &			// 在2核上运行这个进程
[1] 20676

[root@localhost ~]# ps -eo psr,command,pid |grep 1.sh |grep -v grep
  2 sh /tmp/1.sh                 20676 				//查看那个进程在哪个核上
  
[root@localhost ~]#  taskset -p -c 3  20676(此处是pid)		//把该进程转到3核上

使用mpstat查看多核心cpu中每个计算核心的统计数据

[root@localhost ~]# mpstat 2 -P ALL   //-P 参数接数字代表查看的CPU核数, -P 接ALL代表查看所有核的信息
定义中断亲和性

在这里插入图片描述

从上可知ens33网卡的中断都在cpu0上,现在把它转到cpu1上

注意19为上图中第1列对应的IRQ信号
[root@localhost ~]# echo 2 > /proc/irq/19/smp_affinity

内存的调优

内存的作用: 内存是连接CPU和其他设备(DISK)的通道,起到缓冲和数据交换作用。
内存的特点: 存储数据速度快, 但是数据不是永久存放的, 断电则数据丢失。

内存使用LRU算法,当内存满了,新的数据进来,会把最近最少使用的数据丢掉 。

内存包括物理内存和虚拟内存(swap)

增加虚拟内存swap的目的是为了增强物理内存的性能, 但是过多的使用swap也不一定好。
物理内存不够用时,会用到虚拟内存swap(注意: 不是绝对的, 不要用free命令看到有使用过swap就认为内存不够了)

可用free命令查看内存的使用状态
[root@localhost ~]# free
		total	 used 	free	 shared	 buff/cache	 available
Mem: 	997980   773616 69400 	 4704	 154964		 44112
Swap:	2047996  633924 1414072

total:  物理内存总量
used:  内存使用量包括(buff/cache)
free:  未分配使用的内存量
shared:共享内存
buffer:块设备缓存
cache: 文件缓存
available:可以给新进程的内存可用量(重点关注)

使用 sar -B 命令可以得到内存的相关信息

主要看前面4列:

列名说明
pgpgin/s每秒从磁盘到内存的数据,单位为KB.(CPU在内存取不到数据,就要从磁盘取到内存中 的cache)
pgpgout/s每秒从内存到磁盘的数据,单位为KB (脏数据积累到buffer区域一定比率后会写到磁 盘)
fault/s每秒的(major+minor)的page faults之和,也就是cpu从内存取数据的hit+miss次数 之和
majflt/s每秒的major page faults数, 也就是cpu从内存取数据的miss次数

可通过以下条件判断内存是否出现瓶颈

  • free 命令看到的 available 值很小
  • vmstat 命令看到的 si,so 较多
  • sar -B 命令通过 fault/s 和 majflt/s ,算出命中率不高
内存优化思路与方法

如果内存真的出现了瓶颈,那么最好的优化方法仍然是

  • 横向拓展 看是否将应用的一部分负载转移到其它服务器(LB,分表分库,读写分离等)
  • 纵向拓展 换更好的内存,加更大的内存
  • 微调

内存能微调的地方主要就是: 修改内核参数

内核参数修改

对于运维工程师来说,修改操作系统的内核参数就能达到优化操作系统的目的。

查看内核参数
[root@localhost ~]# sysctl -a
在centos7中有1000多个内核参数
[root@localhost ~]# sysctl -a |grep ip_forward
net.ipv4.ip_forward = 1
这个参数对应的/proc路径为/proc/sys/net/ipv4/ip_forward
修改内核参数的方法

临时修改

方法1:
[root@localhost ~]# echo 1 > /proc/sys/net/ipv4/ip_forward

方法2:
[root@localhost ~]# sysctl -w net.ipv4.ip_forwaed=1

永久生效

在 /etc/sysctl.conf 配置文件里加上要修改的内核参数与值
net.ipv4.ip_forward = 1

修改保存后,记得要用 sysctl -p 使之生效

与内存优化有关的内核参数
[root@localhost ~]# cat /proc/sys/vm/swappiness
30
swappiness表示使用swap分区的使用程度, 可以适当调整.
swappiness趋向于0表示尽可能使用物理内存空间.
swappiness趋向于100表示积极使用swap.
基本调优规则为: 如果物理内存够大,那么就尽量不要使用swap,以提高性能.可以把此参数调小如
swappiness=10.

[root@localhost ~]# sysctl -a |grep min_free
vm.min_free_kbytes = 45056
内存最小的free预留值。调太大,会造成可用内存减小。调太小,可能会造成系统急用内存时没有足够的
预留。不建议调整它。
[root@localhost ~]# cat /proc/sys/vm/dirty_background_ratio
10
[root@localhost ~]# cat /proc/sys/vm/dirty_ratio
30

这两个参数合起来理解就是:
内存脏数据到 dirty_background_ratio定义 的10%时,就会触发数据写到磁盘(但是这个过程是异步的,也就是说还是会有别的应用程序的脏数据能继续写到内存), 如果应用程序往内存里写的比内存往磁
盘里写得快,还是有可能达到 dirty_ratio 定义的30%时,那么就要让写脏数据的应用程序等待,直
到它降低到30%以下, 再继续写。  

理解了上面两个参数的意思,再来看优化思路:

  1. dirty_background_ratio
    将值调大的优点:
    提高写入磁盘效率(因为一次写的数据量大,写的次数少)
    将值调大的缺点:
    有可能一次写的数据量过大,造成磁盘IO峰值
  2. dirty_ratio
    在应用程序写内存繁忙时,可以把dirty_ratio值调大,可以缓解应用程序的等待。但是调太大可能会造成内存中过量的脏数据。

磁盘IO调优

IO子系统是速度最慢的,所以容易成为整个系统的瓶颈

IO的优化可从以下几点考虑
  • 换更好的磁盘,专业的存储设备与存储卡
  • raid(raid5,raid10等)
  • lvm(条带化)
  • 分布式存储
  • IO调度算法
  • 合适的文件系统
IO的实时信息查看
使用 iostat  -kx -d  -dev  sda  2  查看磁盘IO状态

avgrq-sz:平均请求数据的大小

avgqu-sz:平均请求队列的长度,队列长度越短越好

await:排队加服务的时间

r_await:centos7中的这一列表示读请求的await

w_await:centos7中的这一列表示写请求的await

svctm:服务的时间

%util:磁盘带宽使用百分比(统计时间内所有处理IO时间除以总共统计时间),百分比越高,磁盘越忙

如果%util一直在100%状态,await等待时间长,avgqu-sz请求队列长,这些都能说明磁盘IO满负荷,可能存在瓶颈。

IO调度算法

常见的有3种算法:

noop:按照时间前后处理

cfq:完全公平队列

deadline:截止时间调度程序(如果IO等待过长超过特定值,会优先处理)

查看当前sda磁盘默认的调度算法

[root@localhost ~]# cat /sys/block/sda/queue/scheduler
noop [deadline] cfq

修改调度算法

[root@localhost ~]# echo noop > /sys/block/sda/queue/scheduler
[root@localhost ~]# cat /sys/block/sda/queue/scheduler
[noop] deadline cfq
如果要永久修改,可考虑将修改的命令加到/etc/rc.local里  

NETWORK优化

网络监测是所有子系统里最复杂的,有太多的因素在里面。比如:延迟、阻塞、冲突、丢包等,更复杂的是与网络协议相关的调整

网络排查思路

如果CPU,mem,IO都没问题,然后网络连接,模式,没有IP冲突,流量大但都是正常流量(没有被攻击),怎么优
化?

  • 业务级
  • 加带宽
  • 微调
如果网络不通或时通时不通,可以从下面几点排错
一、查看网卡是否连接ok
[root@localhost ~]# mii-tool  ens33(网卡名)
ens33: negotiated 1000baseT-FD flow-control, link ok

二、查看网卡的工作模式和修改
[root@localhost ~]# ethtool ens33
此状态下注意网卡的速率和自动协商

[root@localhost ~]# ethtool -s ens33 speed 10 duplex half autoneg off
把网卡改成10M/s的速率,半双工,关闭自动协商
[root@localhost ~]# ethtool -s ens33 speed 1000 duplex full autoneg on
把网卡改成1000M/s的速率,全双工,打开自动协商

三、用 arp-scan 这类小工具扫描内网机器, 查看是否有IP冲突的机器
[root@localhost ~]# yum install arp-scan
需要epel源
[root@localhost ~]# arp-scan -l --interface ens33
查看局域网内所有机器的IP和MAC地址的对应
[root@localhost ~]# arp -a -n
查看所有和本机联系过并且仍然保存在arp缓存列表里的机器的IP和MAC地址的对应
[root@localhost ~]# ip neigh
类似arp -a -n

四、检测网卡的当前负载
[root@localhost ~]# sar -n DEV 2
注意下面几项
rxpck/s 每秒收到的数据包数
txpck/s 每秒发送的数据包数
rxpck/s 每秒收到的kb
txpck/s 每秒发送的kb

五、iptraf工具可以查看本机网络吞吐量,速率等,支持文字图形界面,很直观
[root@localhost ~]# yum install iptraf-ng 	     本地镜像yum源
[root@localhost ~]# iptraf-ng					 直接打开,选择你要查看统计数据
[root@localhost ~]# iptraf-ng -d eth0 			 直接看eth0的统计数据

六、netperf 运行在 client/server 模式下,比iptraf能更多样化的测试终端的吞吐量。
测试方法:服务器和客户端都要安装此软件
在服务器上
[root@localhost ~]# netserver
Starting netserver with host 'IN(6)ADDR_ANY' port '12865' and family AF_UNSPEC
[root@localhost ~]# netstat -ntlup |grep 12865 --端口为12865
tcp 0 0 :::12865 :::*
LISTEN 18366/netserver

在客户端上
[root@localhost ~]# netperf -H 10.1.1.8 -l 30
	接服务端IP,一次测试时间为30秒
MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 10.1.1.8
(10.1.1.8) port 0 AF_INET
[root@localhost ~]# netperf -H 10.1.1.8 -l 30
Recv Send Send
Socket Socket Message Elapsed
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec
87380 16384 16384 30.39 87.39    --这里的87.39的单位是10^6bits,所以要算每秒多少MB就应该$[87*1000000/8/1024/1024]算得多少MB/s大概为10M多/s(因为百M局域网理论值为12.5MB/s)
三次握手

这里使用大白话介绍

第一次:客户端向服务端发送了连接请求

第二次:服务器收到了客户端的请求并回应客户端你还在线吗

第三次:客户端回复我还在线

(想深入了解可以百度)

这里说下syn_flood攻击(洪水攻击)

SYN_Flood (SYN洪水) 是一种典型的DDos攻击

syn_flood基本诊断

  • 服务器连接突然不够用了,大量客户反映无法连接服务器
  • 服务器比平常多出大量的SYN_RCVD状态的连接
# ss -s   
# netstat -n |grep ^tcp |awk '{print $NF}' |sort |uniq -c |awk BEGIN'{print "状态\t\t连接数"} {print $2"\t"$1}'

可以使用上述命令查看


应急处理

可以考虑写shell脚本使用iptables将攻击嫌疑IP给禁止,过一段时间再解禁。但这种做法容易把正常客户给禁掉,只用于应急处理

写一个脚本文件
#!/bin/bash

touch /tmp/denyiplist.txt
netstat -nt |awk '$NF~"SYN_RECV" {print $0}' | grep :80 |awk -F: '{print $8}' |sort |uniq -c |awk '$1>10 {print $2}' |while read ip
do
		grep $ip /tmp/denyiplist.txt &> /dev/null
		if [ $? -ne 0 ];then
		iptables -A INPUT -p tcp --dport 80 -s $ip -j REJECT
		echo "$ip" >> /tmp/denyiplist.txt
at now + 1 days << EOF
iptables -D INPUT -p tcp --dport 80 -s $ip -j REJECT
sed -i "/$ip/"d /tmp/denyiplist.txt
EOF
		fi
done

调整内核参数做微调(syn_flood相关)

net.ipv4.tcp_synack_retries = 1
默认为5,改小(1-2),极端就暂时改为0,表示减小服务器回应syn+ack包的重试次数。
此值过小也会带来风险:正常的SYN因网络原因丢失,不重试的话会造成真正的客户连接无法成功

net.ipv4.tcp_max_syn_backlog = 4096
可以适当调大,此参数表示服务器维护的半连接的队列长度,加大此值,可以支持更多的半连接.但同时也要注意,此值太大也会消耗服务器资源

net.ipv4.tcp_syncookies = 1
改此值为1后,tcp会使用一种特殊的cookies的方法来处理连接.(防syn_flood有一定效果,但是高负载并且没有受到syn_flood攻击,建议关闭)
数据传输

相关知识点:长连接与短连接, 超时重传,快速重传,流量控制,拥塞控制(慢启动,拥塞避免,拥塞发生,快速恢复); 相关状态: ESTABLISHED

这里主要说长短连接

但长连接也有要考虑的问题: 如果连接不断开,而很长没有新的数据传输了,这个连接又占用资源了。所以需要隔一定的时间会自动断开,但这个时间默认比较长,所以可以适当优化。

net.ipv4.tcp_keepalive_time = 1800
默认为7200秒(两小时),server在7200秒没有收到客户端数据传输,会发送探测包确认它是否
alive.
可适当调小,如调成1800秒

net.ipv4.tcp_keepalive_probes = 3
默认9次,表示server需要9次探测client是否alive,9次都没回应,就断开这个tcp连接。可以适当调小

net.ipv4.tcp_keepalive_intvl = 75
75秒,表示server探测的时间间隔。适当调小
四次挥手

可以做以下优化

net.ipv4.ip_local_port_range = 1024  65535  tcp对外连接分配的端口号范围,可以把随机
端口全部分配给它  

net.ipv4.tcp_timestamps = 1 默认为1,不用调,主要是配合下面的tw_reuse和rw_recycle使用的(打开tw_reuse和rw_recycle必须要打开这个参数)

net.ipv4.tcp_tw_reuse = 1 默认为0,改为1表示打开time_wait状态连接的快速重用(针对client)

net.ipv4.tcp_tw_recycle = 1 默认为0,改为1表示打开time_wait状态连接的快速回收(针对server)

net.ipv4.tcp_max_tw_buckets = 40960 服务能维护的最大time_wait数量,在内存足够可以再适当调大

net.ipv4.tcp_fin_timeout = 30 默认为60,表示FIN-WAIT-2状态的时间,适当调小
双网卡绑定

可通过绑定多张网卡来实现HA和LB,实现带宽的增加(多网卡物理上要同网段)

注意: 如果使用vmware workstation版本来测试的话,在做网卡切换时有可能会造成虚拟机死机等情况

1、开启NetworkManager服务
[root@localhost ~]# systemctl start NetworkManager

2、将要绑定的两个网卡的连接先删除(如果网卡正在使用,是不能绑定成team的)
[root@localhost ~]# nmcli connection show
NAME					 UUID 					TYPE				DEVICE	
Wired connection 1 		 3*********				802-3-ethernet		eth1
eth0					 ed********				802-3-ethernet		eth0
virbr0					 6*********				bridge				virbr0

[root@localhost ~]# nmcli connection delete  3***  ed****   
查看是否删干净,没有的话,继续在delete

3、创建team网卡,并指定模式为activebackup
[root@localhost ~]# nmcli connection add type team con-name team0 ifname team0 config '{"runner":{"name":"activebackup"}}'
指定team0网卡的ip,gateway,非dhcp模式,dns指向等(你还可以指定其它属性,可以使用nmcli
connection show team0来查看所有属性)
[root@localhost ~]# nmcli connection modify team0 ipv4.addresses "192.168.1.7/24" ipv4.gateway
"192.168.1.1" ipv4.method manual ipv4.dns "114.114.114.114"

4、把要绑定成team的两张网卡加入team中。并启动team0网卡
[root@localhost ~]#  nmcli connection add type team-slave con-name team0-port1 ifname eth0  master team0
[root@localhost ~]# nmcli connection add type team-slave con-name team0-port2 ifname eth1  master team0
[root@localhost ~]# nmcli connection up team0

5、查看绑定是否ok
[root@localhost ~]# ifconfig team0

[root@localhost ~]#  teamdctl team0 state --查看team的绑定状态
....
	active port: eth0 --这里显示的是主网卡
	
6、测试activebackup模式
把主网卡ifconfig eth0 down掉,发现仍然连接ok

7、把activebackup模式换成roundrobin模式
# nmcli connection show team0 |grep team.config
team.config: 					{"runner":{"name":"activebackup"}}

修改为roundrobin
# nmcli connection modify team0 team.config '{"runner":{"name":"roundrobin"}}'

确认为roundrobin
# nmcli connection show team0 |grep team.config
team.config:					 {"runner":{"name":"roundrobin"}}

启动网卡,这里不用down掉再up,直接up就可以
# nmcli connection up team0

# teamdctl team0 state
setup:
	runner: roundrobin 变成了roundrobin模式了
	
8、测试roundrobin模式
使用iptraf-ng看到两个网卡流量平均,如果down掉一个,另一个网卡会仍然正常工作

小结:架构中防止单点故障的场景:

  • 服务器单点故障 HA
  • 网卡单点故障 网卡bond或team
  • 磁盘单点故障 raid,分布式存储
  • 线路 iscsi双线路,光纤双线路,双心跳

CGroup资源限制

docker中会用到cgroup实现进程级的资源限制与隔离。

Cgroups是control groups的缩写,是Linux内核提供的一种可以限制、记录、隔离进程组(process
groups)所使用的物理资源(如:cpu,memory,IO等等)的机制.

Cgroup作用:

1、资源隔离
2、基于进程的资源限制
3、共有9大子系统

  • blkio 限制每个块设备的输入输出控制。例如:磁盘,光盘以及usb
  • cpu 限制使用cpu比例
  • cpuacct 产生cgroup任务的cpu资源报告。
  • cpuset 多核心的cpu时为cgroup任务分配单独的cpu和内存
  • devices 允许或拒绝对设备的访问。
  • freezer 暂停和恢复cgroup任务。
  • memory 设置内存限制以及产生内存资源报告。
  • net_cls 标记每个网络包。
  • ns 名称空间子系统

安装及开启服务

# yum install libcgroup\*
# systemctl start cgconfig
# systemctl enable cgconfig
限制进程使用CPU

使用CPU子系统创建2个group分组

# vim /etc/cgconfig.conf
group lesscpu {
cpu{
cpu.shares=200;
}
} g
roup morecpu {
cpu{
cpu.shares=800;
}
} #
systemctl restart cgconfig

准备一个脚本

#!/bin/bash
a=1
while true
do
a=$[$a+1]
done

将要运行的应用程序分配到指定分组(请使用单核CPU机器,三个终端验证)

终端1# cgexec -g cpu:lesscpu sh /tmp/1.sh
终端2# cgexec -g cpu:morecpu sh /tmp/1.sh
终端3# top

PS: 如果主机有多CPU,为了验证效果,可以进行如下操作

# lscpu
将1核cpu禁用的做法
# echo 0 > /sys/devices/system/cpu/cpu0/online
如果有8个核,将1-7核CPU都禁用的做法
# for i in {1..7}; do echo 0 > /sys/devices/system/cpu/cpu$i/online; done
限制内存使用
只限制物理内存
# vim /etc/cgconfig.conf
group lessmem {
	memory{
	memory.limit_in_bytes=268435456; 物理内存限制256M
	}
} 
# systemctl restart cgconfig

创建一个挂载目录,将tmpfs挂载

# mkdir /mnt/mem_test
# mount -t tmpfs /dev/shm /mnt/mem_test
# df -h |tail -1
/dev/shm 488M 488M 0 100% /mnt/mem_test 确认大小为内存一半

tmpfs是内存临时文件系统,为物理内存的一半大小,优点:速度快。缺点:数据不能持久化保存

第1次测试,写200M, 没有超过256M限制,成功

# cgexec -g memory:lessmem dd if=/dev/zero of=/mnt/mem_test/file bs=1M  count=200

第2次测试,写400M,有超过256M限制(但不能超过挂载大小),成功

# cgexec -g memory:lessmem dd if=/dev/zero of=/mnt/mem_test/file bs=1M count=400
注意:文件名没变,如果变了,就是新写一个文件,会和第1次写的一起占空间

结果: 超过物理内存限制的会占用swap虚拟内存空间,请使用free命令对比

tmpfs应用场景

如果内存够大,需要对小量文件快速进行读写 (安全性要求不高),就可以使用tmpfs

限制总内存场景

# vim /etc/cgconfig.conf
group poormem{
	memory{
		memory.limit_in_bytes=268435456; 物理内存限制256M
		memory.memsw.limit_in_bytes=268435456; 总内存限制,物理+SWAP
		}
	}
# systemctl restart cgconfig

# cgexec -g memory:poormem dd if=/dev/zero of=/mnt/mem_test/file bs=1M count=200
成功
# cgexec -g memory:poormem dd if=/dev/zero of=/mnt/mem_test/file bs=1M count=400
Killed 直接报killed,说明被限制成功

系统级调优小结:
比较难调,涉及的知识点比较底层。在架构不能动的情况,应用级已经优化过了,只能系统级进行压榨,可以考虑适当做调整。

以上优化仅供参考,具体根据实际情况来定。(误犯

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

柒哥fu.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值