深入理解Linux文件系统与日志分析

文件是存储在硬盘上的,硬盘的最小存储单位叫做“扇区”(sector),每个扇区存储512字节。
一般连续八个扇区组成一个"块"(block),一个块是4K大小,是文件存取的最小单位。操作系统读取硬盘的时候,是一次性连续读取多个扇区,即一个块一个块的读取的。
文件数据包括实际数据与元信息(类似文件属性)。文件数据存储在“块”中,存储文件元信息(比如文件的创建者、创建日期、文件大小、文件权限等)的区域就叫做inode。因此,一个文件必须占用一个 inode,并且至少占用一个 block。
inode不包含文件名。文件名是存放在目录当中的。Linux 系统中一切皆文件,因此目录也是一种文件。
每个inode都有一个号码,操作系统用inode号码来识别不同的文件。Linux系统内部不使用文件名,而使用inode号码来识别文件。 对于系统来说,文件名只是inode号码便于识别的别称,文件名和inode号码是一一对应关系,每个inode号码对应一个文件名。
所以,当用户在Linux系统中试图访问一个文件时,系统会先根据文件名去查找它对应的inode号码;通过inode号码,获取inode信息;根据inode信息,看该用户是否具有访问这个文件的权限;如果有,就指向相对应的数据block,并读取数据。

inode和block概述

  • 文件数据包括元信息与实际数据

  • 文件存储在硬盘上,硬盘最小存储单位是“扇区”,每个扇区存储512字节

  • block(块)

  • 连续的八个扇区组成一个block(4K)

  • 是文件存取的最小单位

  • inode(索引节点)

  • 中文译名为“索引节点”,也叫i节点

  • 用于存储文件元信息

inode包含文件的元信息

  • 文件的字节数

  • 文件拥有者的User ID

  • 文件的Group ID

  • 文件的读、写、执行权限

  • 文件的时间戳

  • .....

ls -i命令查看文件名对应的inode号码

例:ls -i aa.txt

用stat命令可以查看某个文件的inode信息

例: stat aa.txt

用户通过文件名打开文件时,系统内部的过程

  1. 系统找到这个文件名对应的inode号码

  1. 通过inode号码获取inode信息

  1. 根据inode信息,找到文件数据所在的block,读出数据

Linux系统文件三个重要的时间属性

  • atime(access time)

  • 最后一次改变文件或目录(属性)的时间

  • 当修改文件的权限或者属性的时候,就会更新这个时间,ctime并不是create time,更像是change time,只有当更新文件的属性或者权限的时候才会更新这个时间,但是更改内容的话是不会更新这个时间。

  • ctime(change time)

  • 最后一次访问文件或目录的时间

  • 当使用这个文件的时候就会更新这个时间。

  • mtime(modify time)

  • 最后一次修改文件或目录(内容)的时间

  • 当修改文件的内容数据的时候,就会更新这个时间,而更改权限或者属性,mtime不会改变,这就是和ctime的区别。

由于 inode 号码与文件名分离,导致Linux 系统具备以下几种特有的现象:

1.文件名包含特殊字符,可能无法正常删除。这时直接删除 inode,能够起到删除文件的作用;

2.移动文件或重命名文件,只是改变文件名,不影响 inode 号码;

3.打开一个文件以后,系统就以 inode 号码来识别这个文件,不再考虑文件名。

4.使用 vi 编辑器修改文件数据保存后,会生成一个新的 inode 号码

find ./ -inum 52305140 -exec rm -i {} \;       ---查找inode删除
#删除特殊字符
find ./ -inum 50464299 -delete       ---查找inode删除,只适用于文件

inode的大小

inode也会消耗硬盘空间
  • 每个inode的大小

  • 一般是128字节或256字节

格式化文件系统时确定inode的总数
使用df -i命令可以查看每个硬盘分区的inode总数和已经使用的数量
inode节点耗尽故障处理

#使用fdisk创建分区/dev/sdb1,分区大小4M即可 创建一个ext4的
fdisk /dev/sdb
mkfs.ext4 /dev/sdb1
mkdir /test
mount /dev/sdb1 /mnt
df -i
#模拟inode节点耗尽故障
for ((i=1; i<=7680; i++));do touch /test/file$i;done touch {1..7680}.txt
df -i
df -hT
#删除文件恢复
rm -rf /test/*
df -i
df -hT

xfs 类型文件备份和恢复

CentOS 7 系统默认采用 xfs类型的文件,xfs 类型的文件可使用 xfsdump 与 xfsrestore 工具进行备份恢复。

xfsdump 的备份级别有两种:0 表示完全备份;1-9 表示增量备份。xfsdump 的备份级别默认为 0。

xfsdump 的命令格式为:

xfsdump -f 备份存放位置 要备份的路径或设备文件

xfsdump 命令常用的选项:

-f:指定备份文件目录

-L:指定标签 session label

-M:指定设备标签 media label

-s:备份单个文件,-s 后面不能直接跟路径

xfsdump使用限制:

1.只能备份已挂载的文件系统

2.必须使用root的权限才能操作

3.只能备份XFS文件系统

4.备份后的数据只能让xfsrestore解析

5.不能备份两个具有相同UUID的文件系统(可用 blkid命令查看)

[root@localhost ~]# scan
[root@localhost ~]# lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda      8:0    0   50G  0 disk 
├─sda1   8:1    0  300M  0 part /boot
├─sda2   8:2    0    3G  0 part [SWAP]
└─sda3   8:3    0 46.7G  0 part /
sdb      8:16   0   20G  0 disk 
sr0     11:0    1  4.2G  0 rom  
[root@localhost ~]# fdisk /dev/sdb
Welcome to fdisk (util-linux 2.23.2).

Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Device does not contain a recognized partition table
Building a new DOS disklabel with disk identifier 0xed5b826a.

Command (m for help): n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): 
Using default response p
Partition number (1-4, default 1): 1
First sector (2048-41943039, default 2048): 
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-41943039, default 41943039): +5G
Partition 1 of type Linux and of size 5 GiB is set

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.
[root@localhost ~]# mkfs.xfs -f /dev/sdb1
meta-data=/dev/sdb1              isize=512    agcount=4, agsize=327680 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=0, sparse=0
data     =                       bsize=4096   blocks=1310720, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal log           bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
[root@localhost ~]# mkdir /data
[root@localhost ~]# mount /d
data/ dev/  
[root@localhost ~]# mount /d
data/ dev/  
[root@localhost ~]# mount /dev/sdb1 /d
data/ dev/  
[root@localhost ~]# mount /dev/sdb1 /data/

创建data进行备份:

[root@localhost ~]# cd data
-bash: cd: data: No such file or directory
[root@localhost ~]# ls
anaconda-ks.cfg  initial-setup-ks.cfg  original-ks.cfg
[root@localhost ~]# cd /
[root@localhost /]# ls
bin   data  etc   lib    media  opt   root  sbin  sys  usr
boot  dev   home  lib64  mnt    proc  run   srv   tmp  var
[root@localhost /]# cd data
[root@localhost data]# ls
[root@localhost data]# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda3        47G  5.2G   42G  11% /
devtmpfs        1.4G     0  1.4G   0% /dev
tmpfs           1.4G     0  1.4G   0% /dev/shm
tmpfs           1.4G  9.1M  1.4G   1% /run
tmpfs           1.4G     0  1.4G   0% /sys/fs/cgroup
/dev/sda1       297M  157M  140M  53% /boot
tmpfs           280M  8.0K  280M   1% /run/user/42
tmpfs           280M     0  280M   0% /run/user/0
/dev/sdb1       5.0G   33M  5.0G   1% /data
[root@localhost data]# cp /etc/passwd ./

模拟故障:

[root@localhost data]# mkdir test
[root@localhost data]# touch test/a
[root@localhost data]# rpm -qa | grep xfsdump
xfsdump-3.1.4-1.el7.x86_64
[root@localhost data]# xfsdump -f /opt/dump_sdb1 /d
data/ dev/  
[root@localhost data]# xfsdump -f /opt/dump_sdb1 /dev/sdb1 [-L dump_sdb1 -M sdb1]
xfsdump: using file dump (drive_simple) strategy
xfsdump: version 3.1.4 (dump format 3.0) - type ^C for status and control

 ============================= dump label dialog ==============================

please enter label for this dump session (timeout in 300 sec)
 -> 
session label entered: ""

 --------------------------------- end dialog ---------------------------------

xfsdump: WARNING: no session label specified
xfsdump: level 0 dump of localhost.localdomain:/data
xfsdump: dump date: Thu Mar  2 01:40:27 2023
xfsdump: session id: df49cb60-22ad-47b3-910c-008f487fe005
xfsdump: session label: ""
xfsdump: ino map phase 1: constructing initial dump list
xfsdump: ino map phase 2: skipping (no pruning necessary)
xfsdump: ino map phase 3: skipping (only one dump stream)
xfsdump: ino map construction complete
xfsdump: estimated dump size: 25856 bytes
xfsdump: /var/lib/xfsdump/inventory created
xfsdump: creating dump session media file 0 (media 0, file 0)
xfsdump: dumping ino map
xfsdump: dumping directories
xfsdump: dumping non-directory files
xfsdump: ending media file
xfsdump: media file size 25552 bytes
xfsdump: dump size (non-dir files) : 2592 bytes
xfsdump: dump complete: 3 seconds elapsed
xfsdump: Dump Summary:
xfsdump:   stream 0 /opt/dump_sdb1 OK (success)
xfsdump: Dump Status: SUCCESS
[root@localhost data]# ls
passwd  test
[root@localhost data]# rm -rf ./*
[root@localhost data]# ls

进行恢复:

[root@localhost data]# xfsrestore -f /opt/dump_sdb1 /data/
xfsrestore: using file dump (drive_simple) strategy
xfsrestore: version 3.1.4 (dump format 3.0) - type ^C for status and control
xfsrestore: searching media for dump
xfsrestore: examining media file 0
xfsrestore: dump description: 
xfsrestore: hostname: localhost.localdomain
xfsrestore: mount point: /data
xfsrestore: volume: /dev/sdb1
xfsrestore: session time: Thu Mar  2 01:40:27 2023
xfsrestore: level: 0
xfsrestore: session label: ""
xfsrestore: media label: "sdb1]"
xfsrestore: file system id: b7c9491a-8a0f-46d0-9bc3-08de00a79a51
xfsrestore: session id: df49cb60-22ad-47b3-910c-008f487fe005
xfsrestore: media id: 4bdf219c-9fe3-4151-8ca4-324bcaaf6a9c
xfsrestore: using online session inventory
xfsrestore: searching media for directory dump
xfsrestore: reading directories
xfsrestore: 2 directories and 3 entries processed
xfsrestore: directory post-processing
xfsrestore: restoring non-directory files
xfsrestore: restore complete: 0 seconds elapsed
xfsrestore: Restore Summary:
xfsrestore:   stream 0 /opt/dump_sdb1 OK (success)
xfsrestore: Restore Status: SUCCESS
[root@localhost data]# ls
passwd  test
[root@localhost data]# 

内核及系统日志由系统服务 rsyslog 统一管理,主配置文件为/etc/rsyslog.conf

Linux 操作系统本身和大部分服务器程序的日志文件都默认放在目录/var/log/下。

日志文件

日志的功能

  • 用于记录系统、程序运行中发生的各种事件

  • 通过阅读日志,有助于诊断和解决系统故障

日志文件的分类

  • 内核及系统日志

  • 有系统服务rsyslog统一进行管理,日志格式基本相似

  • 主配置文件/etc/rsyslog.conf

  • 用户日志

  • 记录系统用户登录及推出系统的相关信息

  • 程序日志

  • 有各种应用程序独立管理的日志文件,记录格式不统一

常见的一些日志文件:

#内核及公共消息日志:

/var/log/messages:记录Linux内核消息及各种应用程序的公共日志信息,

包括启动、IO错误、网络错误、程序故障等。

对于未使用独立日志文件的应用程序或服务,一般都可以从该日志文件中获得相关的事件记录信息。

#计划任务日志:

/var/log/cron:记录crond计划任务产生的事件信息。

#系统引导日志:

/var/log/dmesg:记录Linux系统在引导过程中的各种事件信息。

#邮件系统日志:

/var/log/maillog:记录进入或发出系统的电子邮件活动。

#用户登录日志:

/var/log/secure:记录用户认证相关的安全事件信息。

/var/log/lastlog:记录每个用户最近的登录事件。二进制格式

/var/log/wtmp:记录每个用户登录、注销及系统启动和停机事件。二进制格式

/var/run/btmp:记录失败的、错误的登录尝试及验证事件。二进制格式

vim /etc/rsyslog.conf#查看rsyslog.conf配置文件,规则配置格式:【设备.级别动作】

#MODULES     //相关模块配置
 
# Provides UDP syslog reception
#$ModLoad imudp      //使用UDP协议传输日志数据
#$UDPServerRun 514   //端口为514端口
 
# Provides TCP syslog reception
#$ModLoad imtcp      //使用TDP协议传输日志数据
#$InputTCPServerRun 514    //端口为514端口
 
#### GLOBAL DIRECTIVES ####    //全局配置不常用省略
 
#### RULES ####   //日志记录相关的规则配置

*.info;mail.none;authpriv.none;cron.none /var/log/messages

//*表示所有 *.info表示所有级别,分号隔开none表示没有级别,即不记录

//本行中表示不记录mail、authpriv、cron其他所有记录到/var/log/messages文件中

authpriv.* /var/log/secure

//authpriv:所有等级日志记录到/var/log/secure文件中,文件可以自定义路径和文件名

//可以使用1个@或者2@加ip的形式将日志传到其他相通的服务器上

mail.* -/var/log/maillog

//mail所有等级日志记录到-/var/log/maillog文件中,文件可以自定义路径和文件名

//可以使用1个@或者2@加ip的形式将日志传到其他相通的服务器上

cron.* /var/log/cron

//cron所有等级日志记录到/var/log/cron文件中,文件可以自定义路径和文件名

//可以使用1个@或者2@加ip的形式将日志传到其他相通的服务器上

local7.* /var/log/boot.log

//local7表示自定义服务,范围为0-7都可以使用,在支持的服务配置文件中也要写对应的local等级

// /var/log/boot.log表示存到此目录下的文件中,文件可以自定义路径和文件名

//可以使用1个@或者2@加ip的形式将日志传到其他相通的服务器上

设备字段说明:

auth用户认证时产生的日志

authprivssh、ftp等登录信息的验证信息

daemon一些守护进程产生的日志

ftpFTP产生的日志

lpr打印相关活动

markrsyslog服务内部的信息,时间标识

news网络新闻传输协议(nntp)产生的消息。

syslog系统日志

uucpUnix-to-Unix Copy 两个unix之间的相关通信

console针对系统控制台的消息。

cron系统执行定时任务产生的日志。

kern系统内核日志

local0~local7自定义程序使用

mail邮件日志

user用户进程

Linux系统内核日志消息的优先级别(数字等级越小,优先级越高,消息越重要):

0EMERG(紧急):会导致主机系统不可用的情况。如系统崩溃

1ALERT(警告):必须马上采取措施解决的问题。如数据库被破坏

2CRIT(严重):比较严重的情况。如硬盘错误,可能会阻碍程序的部分功能

3ERR(错误):运行出现错误。不是非常紧急,尽快修复的

4WARNING(提醒):可能影响系统功能,需要提醒用户的重要事件。不是错误,如磁盘用了85%等

5NOTICE(注意):不会影响正常功能,但是需要注意的事件。无需处理

6INFO(信息):一般信息。正常的系统信息

7DEBUG(调试):程序或系统调试信息等。包含详细开发的信息,调试程序时使用

none:没有优先级,不记录任何日志消息。

举例:

mail.info /var/log/maillog :比指定级别更高的日志级别,包括指定级别自身,保存到/var/log/maillog中

mail.=info /var/log/maillog :明确指定日志级别为info,保存至/var/log/maillog

mail.!info /var/log/maillog :除了指定的日志级别(info)所有日志级别信息,保存至/var/log/maillog

*.info /var/log/maillog :所有facility的info级别,保存至/var/log/maillog

mail.* /var/log/maillog :mail的所有日志级别信息,都保存至/var/log/maillog

mail.notice;news.info /var/log/maillog :mail的notice以上记得日志级别和news的info以上的级别保存至/var/log/maillog

mail,news.crit -/var/log/maillog :mail和news的crit以上的日志级别保存/var/log/maillog中;“-”代表异步模式

分析工具

users、 who、w 、last、lastb

w 显示目前登入系统的用户信息

last 命令用于查询成功登录到系统的用户记录

lastb 命令用于查询登录失败的用户记录

[root@localhost ~]# w
 13:17:21 up  1:45,  4 users,  load average: 0.13, 0.22, 0.13
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    192.168.233.1    六20   16:26m  0.60s  0.60s -bash
root     pts/1    192.168.233.1    13:12    1.00s  0.05s  0.02s w
root     pts/2    192.168.233.1    13:13    3:49   0.03s  0.01s -bash
dn       :0       :0               13:14   ?xdm?  44.88s  0.11s /usr/libexec/gnome-session-binary

last  #列出截止目前登录过系统的用户信息
[root@localhost ~]# last  
dn       :0           :0               Sun Feb 26 13:14   still logged in   
root     pts/2        192.168.233.1    Sun Feb 26 13:13   still logged in   
root     pts/1        192.168.233.1    Sun Feb 26 13:12   still logged in   
root     pts/2        192.168.233.1    Sun Feb 26 13:10 - 13:10  (00:00)    
root     pts/1        192.168.233.1    Sun Feb 26 11:44 - 13:12  (01:28)   

lastb #查询登录失败的用户记录
[root@localhost ~]# lastb
dn       :0           :0               Sun Feb 26 13:13 - 13:13  (00:00)    

btmp begins Sun Feb 26 13:13:58 2023

公共日志/var/log/messages 文件的记录格式
时间标签:消息发出的日期和时间。
    主机名:生成消息的计算机的名称。
    子系统名称:发出消息的应用程序的名称。
    消息:消息的具体内容。
Feb 26 12:50:01 localhost systemd: Started Session 11 of user root.
Feb 26 12:50:01 localhost systemd: Starting Session 11 of user root.
Feb 26 13:00:01 localhost systemd: Started Session 12 of user root.
    时间标签     主机名  子系统名称      消息的具体内容
    
程序自己维护日志记录,httpd 网站服务程序使用两个日志文件:
access_log         #记录客户访问事件
error_log        #记录错误事件。

-------------实验一:将ssh服务日志单独存放------------

第一步:关闭服务端和客户端防火墙、selinux

[root@localhost logs]# setenforce 0

[root@localhost logs]# systemctl stop firewalld

[root@localhost logs]# vim /etc/rsyslog.conf

# Save boot messages also to boot.log

local7.* /var/log/boot.log

local6.* /var/log/ssh.log

[root@localhost logs]# vim /etc/ssh/sshd_config

# Logging

#SyslogFacility AUTH

#SyslogFacility AUTHPRIV #注释掉

SyslogFacility LOCAL6 #添加这一行,可以复制粘贴,必须要大写

重启服务

[root@localhost logs]# systemctl restart sshd

[root@localhost logs]# systemctl restart rsyslog

验证:

另一台:ssh root@192.168.179.20

在192.168179.23上查看日志 /var/log/ssh.log

[root@localhost ~]# ssh root@192.168.179.20
The authenticity of host '192.168.179.20 (192.168.179.20)' can't be established.
ECDSA key fingerprint is SHA256:1Tg9pURfS0HpXHY9QBe35s6MHOe7P7Nf0G7PJrVRom8.
ECDSA key fingerprint is MD5:b2:9a:14:da:c6:db:de:f2:d2:ca:bb:4e:90:df:a1:f8.
Are you sure you want to continue connecting (yes/no)? y
Please type 'yes' or 'no': yes
Warning: Permanently added '192.168.179.20' (ECDSA) to the list of known hosts.
root@192.168.179.20's password: 
Last login: Thu Mar  2 02:42:00 2023 from 192.168.179.1
[root@localhost ~]# cat /var/log/ssh.log
Mar  2 02:45:21 localhost sshd[12471]: Server listening on 0.0.0.0 port 22.
Mar  2 02:45:21 localhost sshd[12471]: Server listening on :: port 22.
Mar  2 02:47:04 localhost sshd[12505]: Accepted password for root from 192.168.179.23 port 50608 ssh2
[root@localhost ~]# exit
logout
[root@localhost ~]# cat /var/lo
local/ lock/  log/   
[root@localhost ~]# cat /var/lo
local/ lock/  log/   
[root@localhost ~]# cat /var/log/ss
ssh.log  sssd/    
[root@localhost ~]# cat /var/log/ss
ssh.log  sssd/    
[root@localhost ~]# cat /var/log/ssh.log 
Mar  2 02:45:21 localhost sshd[12471]: Server listening on 0.0.0.0 port 22.
Mar  2 02:45:21 localhost sshd[12471]: Server listening on :: port 22.
Mar  2 02:47:04 localhost sshd[12505]: Accepted password for root from 192.168.179.23 port 50608 ssh2
Mar  2 02:47:16 localhost sshd[12505]: Received disconnect from 192.168.179.23 port 50608:11: disconnected by user
Mar  2 02:47:16 localhost sshd[12505]: Disconnected from 192.168.179.23 port 50608
[root@localhost ~]# 

---------- 配置日志服务器来收集日志 ----------

rsyslog是一个C/S架构,可以通过套接字来进行监听记录工作,可以基于TCP和UDP工作,默认的监听端口是514,只需要在MODULES打开即可。

发送服务器:客户端192.168.179.20

收集服务器:服务端192.168.179.23

//关闭服务端和客户端防火墙、selinux

setenforce 0

systemctl stop firewalld7

systemctl disable firewalld

配置发送方:

//修改客户端配置文件,并启动服务

vim /etc/rsyslog.conf

#### MODULES ####

#将下面注释取消

$ModLoad imtcp

$InputTCPServerRun 514

#### RULES ####

#*.info;mail.none;authpriv.none;cron.none /var/log/messages --这一行必须注释

*.info;mail.none;authpriv.none;cron.none @@192.168.233.21 #两个@@表示TCP

ip地址表示接受方

systemctl restart rsyslog

netstat -antp | grep 514 #查看端口情况

配置接收方:

//修改服务端配置文件,并启动服务

vim /etc/rsyslog.conf

#将下面四行前的注释取消掉

$ModLoad imtcp

$InputTCPServerRun 514

systemctl restart rsyslog

netstat -antp | grep 514 #查看端口情况

logger "this is ky27"

---------- journalctl 日志管理工具 ----------

日志管理工具journalctl是centos7上专有的日志管理工具,该工具是从messages这个文件里读取信息。

Systemd统一管理所有Unit的启动日志。带来的好处就是,可以只用journalctl一个命令,查看所有日志(内核日志和应用日志)。

日志的配置文件是/etc/systemd/journald.conf

#查看所有日志(默认情况下,只保存本次启动的日志)

journalctl

journalctl -r#-r表示倒序,从尾部看(推荐)

#查看内核日志(不显示应用日志)

journalctl -k

#查看系统本次启动的日志

journalctl -b [-0]

#查看上一次启动的日志(需更改设置,如上次系统崩溃,需要查看日志时,就要看上一次的启动日志)

journalctl -b -1

#显示尾部指定行数的日志

查看的是/var/log/messages的日志,但是格式上有所调整,如主机名格式不一样而已

journalctl -n 20

#查看某个服务的日志

journalctl -u nginx.service

#查看指定进程的日志

journalctl _PID=1

#查看指定用户的日志

journalctl _UID=0 --since today

journalctl _UID=0 --since yesterday 昨天的日志,能不能看明天的日志?

journalctl -xe

# -x 是目录(catalog)的意思,在报错的信息下会,附加解决问题的网址

#-e pager-end 从末尾开始看

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

R1chArd_TvT

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

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

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

打赏作者

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

抵扣说明:

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

余额充值