Linux系统管理

进程管理

进程管理简介

进程是正在执行的一个程序或命令,每一个进程都是一个运行的实体,都有自己的 地址空间,并占用一定的系统资源。

进程管理的作用

  • 判断服务器健康状态
  • 查看系统中所有进程
  • 杀死进程

进程的查看

查看所有进程

ps命令

  • ps aux 查看系统中所有进程,使用BSD操作系统格式
  • ps -le 查看系统中所有进程,使用Linux标准命令格式
    • 选项
      -a 显示一个终端的所有进程,除了会话
      -u 显示进程的归属用户及内存的使用情况
      -x 显示没有控制终端的进程
      -l 长格式显示。显示更加详细的信息
      -e 显示所有进程和-A作用一致
/*  USER 进程由哪个用户生成
    PID 进程ID号
    %CPU 进程占用CPU资源的百分比,占用越高,进程越耗资源
    %MEM 进程占用物理内存的百分比,占用越高,进程越耗资源
    VSZ 进程占用虚拟内存的大小,单位KB
    RSS 进程占用实际物理内存的大小,单位KB

    TTY 进程是在哪个终端中运行。
        其中tty1-tty7代表本地控制台终端,tty1-tty6是本地字符界面终端,tty7是图形终端,pts/0-255代表虚拟终端、远程终端
        tty1-tty7可以通过CTL+ALT+F1~CTL+ALT+F7来切换。
        TTY显示?说明进程是由内核启动的不是由终端启动。

    STAT 进程状态。
        常见的状态:
        R 运行、S 睡眠、T 停止状态、s 包含子进程、+ 位于后台

    START 进程启动时间
    TIME 进程占用CPU的运算时间,注意不是系统时间
    COMMAND 产生此进程的命令名
*/
$ ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.4 185316  4116 ?        Ss   624   0:23 /sbin/init spl
root         2  0.0  0.0      0     0 ?        S    624   0:00 [kthreadd]
root         3  0.0  0.0      0     0 ?        S    624   4:07 [ksoftirqd/0]
root         5  0.0  0.0      0     0 ?        S<   624   0:00 [kworker/0:0H]
root         7  0.1  0.0      0     0 ?        S    624  16:09 [rcu_sched]
...

pstree命令

  • pstree
    • 选项
      -p 显示进程的PID
      -u 显示进程的所属用户
$ pstree
systemd─┬─ModemManager─┬─{gdbus}
        │              └─{gmain}
        ├─NetworkManager─┬─dhclient
        │                ├─dnsmasq
        │                ├─{gdbus}
        │                └─{gmain}
        ├─accounts-daemon─┬─{gdbus}
        │                 └─{gmain}
        ├─acpid
        ├─5*[agetty]
        ├─avahi-daemon───avahi-daemon
        ├─colord─┬─{gdbus}
...

top命令

查看系统健康状态

  • top
    • 选项
      -d 秒数 指定投票命令每隔几秒更新。默认3秒
      -b 使用批处理模式输出。一般和 -n 选项合用
      -n 次数 指定top命令指定的次数。一般和-b选项合用
  • 在top命令的交互模式当中可以执行的命令
    ?或h 显示交互模式的帮助
    P 以CPU使用率排序,默认就是此项
    M 以内存的使用率排序
    N 以PID排序
    q 退出top

第一行信息为任务队列信息

内容说明
12:26:46系统当前时间
up 1 day, 13:32系统的运行时间,本机已经运行1天13小时32分钟
2 users当前登录了两个用户
load average: 0.00, 0.00, 0.00系统在之前1分钟,5分钟,15分钟的平均负载。一般任务小于1时,负载较小。如果大于1,系统已经超出负载。

第二行为进程信息

内容说明
Tasks: 95 tatal系统中进程总数
1 running正在运行的进程数
94 sleeping睡眠的进程
0 stopped正在停止的进程
0 zombie僵尸进程。如果不是0,需要手工检查僵尸进程

注:

孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。

僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵死进程。

第三行行为CPU信息

内容说明
Cpu(s): 0.1%us用户模式占用的CPU百分比
0.1%sy系统模式占用的CPU百分比
0.0%ni改变过优先级的用户进程占用的CPU百分比
99.7%id空闲CPU的CPU百分比
0.1%wa等待输入/输出的进程占用CPU百分比
0.0%hi硬终端请求服务占用的CPU百分比
0.1%si软中断请求服务占用的CPU百分比
0.0%stst(Steal time)虚拟时间百分比。就是当有虚拟机时,虚拟CPU等待实际CPU的时间百分比

第四行行为物理内存信息

内容说明
Mem: 625344k total物理内存的总量,单位KB
571504k used已经使用的物理内存数量
53840 free空闲的物理内存数量,我们使用虚拟机,总共只分配了628MB内存,所以只有53MB的空闲内存了
65800k buffers作为缓冲的内存数量

注:

buffers:加速写入;例如保存文件内容,真是情况是先写入文件进程的缓冲区,然后在文件关闭和系统空闲时再写入硬盘。

第五行为交换分区(swap)信息

内容说明
Swap: 524280k total交换分区(虚拟内存)的总大小
Ok used已经使用的交互分区的大小
524280k free空闲交换分区的大小
409289k cached作为缓存的交换分区的大小

注:

cached:加速读取;例如,读取硬盘文件时可以把部分文件放在内存中缓存起来,不用每次访问硬盘,加速读取文件速度。

top内容主要查看
load average、cpu的空闲率、内存的空闲、Swap分区的空闲。

// 更改top刷新时间为1s,但不建议,top本身耗费资源
$ top -n 1

// 使用top只能在终端中看到很少一部分程序,因此使用-b来保存进程到文件中
$ top -b -n 1 >top.log
$ cat top.log

进程的结束

kill命令

  • kill -l
    • 查看可用的进程信号
信号代号信号名称说明
1SIGHUB该信号让进程立即关闭,然后重新读取配置文件之后重启
2SIGINT程序终止信号,用于终止前台进程。相当于输出ctl+c快捷键
8SIGFPE在发生致命的算术运算错误时发出。不仅包括浮点运算错误,还包括溢出及除数为0等其他所有的算术的错误
9SIGKILL用来立即结束程序的运行。本信号不能被阻塞、处理和忽略。一般用于强制终止进程。
14SIGALRM时钟定时信号,计算的是实际的时间或时钟时间。alarm函数使用该信号
15SIGTERM正常结束进程的信号,kill命令默认信号。有时如果进程已经发生问题,这个信号是无法正常终止进程的,我们才会尝试SIGKILL信号,也就是信号9。
18SIGCONT该信号可以让暂停的进程恢复执行,本信号不能被阻塞。
19SIGSTOP该信号可以暂停前台进程,相当于输入ctl+z快捷键。本信号不能被阻断。

SIGHUB信号
若apache服务器重新设置配置文件,需要重启apache服务,如果使用服务命令stop、start时关闭服务造成用户体验非常差。那么可以使用Kill -HUB pid的命令使apache服务重新加载配置实现平滑重启。但apache服务有多个服务进程,那么可以使用killall 命令实现。
平滑重启不会使服务器登录用户掉线。

SIGKILL
强制终止进程,kill -9 2236

// 查看可用的进程信号
$ kill -l
// 强制终止进程,注kill后跟的是pid不能是进程名
$ kill -9 2237

killall命令

  • killall [选项][信号]进程名
    • 选项
      -i 交互式,询问是否要杀死某个进程
      -I 忽略进程名的大小写
// 杀死所有apache服务
$ killall -9 httpd

pkill命令

  • pkill [选项][信号]进程号
    • 选项
      -t 终端号 按照终端号踢出用户

注:pkill和killall命令基本相同。

// 查看当前登录用户
$ w
 19:53:45 up  3:02,  1 user,  load average: 0.00, 0.01, 0.05
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root   tty1     -               16:51    3:02m 23.87s  0.23s -bash
root   pts/0    192.168.44.1    04:47    0.00s 0.22s   0.00s w
root   pts/0    192.168.44.1    04:47    0.00s 0.22s   0.00s -bash

// 只有root用户可以踢掉本地用户
# pkill -9 -t tty1

进程优先级的修改

进程优先级简介

Linux操作系统是一个多用户、多任务的操作系统,Linux系统中通知运行着非常多的进程。但是CPU在统一时钟周期内只能运算一个指令。进程优先级决定了每个进程处理的先后顺序。

$ ps -le
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S     0     1     0  0  80   0 - 29895 -      ?        00:00:02 systemd
1 S     0     2     0  0  80   0 -     0 -      ?        00:00:00 kthreadd
1 S     0     3     2  0  80   0 -     0 -      ?        00:00:00 ksoftirqd/0
1 S     0     5     2  0  60 -20 -     0 -      ?        00:00:00 kworker/0:0H
1 S     0     7     2  0  80   0 -     0 -      ?        00:00:03 rcu_sched
1 S     0     8     2  0  80   0 -     0 -      ?        00:00:00 rcu_bh
1 S     0     9     2  0 -40   - -     0 -      ?        00:00:00 migration/0
5 S     0    10     2  0 -40   - -     0 -      ?        00:00:00 watchdog/0
5 S     0    11     2  0  80   0 -     0 -      ?        00:00:00 kdevtmpfs
1 S     0    12     2  0  60 -20 -     0 -      ?        00:00:00 netns

// PRI代表Priority,NI代表Nice。这两个值都是优先级,数字越小代表该进程优先级越高。

修改NI值时有几个注意事项

  • NI的值的范围是-20到19
  • 普通用户调整NI值的范围是0到19,而且只能调整自己的进程
  • 普通用户只能调高NI值,而不是降低,如原本NI值为0,则只能调整为大于0
  • root用户才能设定进程NI值为负值,而且可以调整任何用户的进程
  • PRI(最终值)=PRI(原始值)+NI
  • 用户只能修改NI的值,不能直接修改PRI

nice命令

  • nice [选项] 命令
    nice命令可以给新执行的命令直接赋予NI值,但是不能修改已经存在进程的NI值
    • 选项
      -n NI值 给命令赋予NI值
// 进程启动时才可以修改其NI值,进程运行时无法修改
# nice -n -5 service httpd start

renice命令

  • renice [优先级] PID
    renice命令是修改已经存在进程的NI值命令
// 使用renice来修改已经存在进程的NI值
# renice -10 2125

工作管理

工作管理简介

工作管理是指在单个登录终端中(也就是登录的shell界面中)同时管理多个工作的行为。

注意事项

  • 当前的登录终端,只能管理当前终端的工作,而不能管理其他登录终端的工作

  • 放入后台的命令必须可以持续运行一段时间,这样我们才能捕捉和操作这个工作

  • 放入后台执行的命令不能和前台有交互或需要前台输入,否则放入后台只能暂停,而不能运行

工作管理方法

进程放入后台

  1. 使用 & 把命令放入后台
  2. 使用 ctrl + z快捷键把命令放入后台
// 把命令放入后台,并在后台执行
$ tar -zcf etc.tar.gz /etc &

// 按下ctl + z 快捷键,放在后台暂停
$ top
ctl + z

查看后台的工作

  • jobs
    • 选项
      -l 显示工作的PID
      注:”+”号代表最近一个放入后台的工作,也是工作回复时,默认回复的工作。”-“号代表倒数第二个放入后台的工作
$ top&
$ top // ctrl+ z放入后台
// 查看后台进程,两个top进程都是停止的,因为top给前台用户查看的,和前台有交互,无法在后台执行
$ jobs
[1]-  Stopped                 top
[2]+  Stopped                 top

$ vi abc &
$ jobs
[1]   Stopped                 top
[2]-  Stopped                 top
[3]+  Stopped                 vi abc

将后台暂停的工作恢复到前台执行

  • fg %工作号
    • 参数
      %工作号 %号可以省略,但是注意工作和PID的区别

将后台暂停的工作恢复到后台执行

  • bg %工作号
    • 参数
      %工作号 %号可以省略,但是注意工作和PID的区别

注:后台恢复执行的命令,是不能和前台有交互的,否则不能恢复到后台执行

后台命令脱离登录终端执行

简介

把命令放入后台,只能在当前登录终端执行。一旦退出或关闭终端,后台程序就会停止。

后台命令脱离登录终端执行的方法

  • 把需要后台执行的命令加入 /etc/rc.local文件
  • 使用系统定时任务,让系统在指定的时间执行某个后台命令
  • 使用nohub命令,推荐使用
  • 做成daemon守护进程 如mysqld服务
// 系统启动时执行rc.local文件
$ cat /etc/rc.local
touch /var/lock/subsys/local // 注:这里不是创建文件,改变文件的timestamp
// 在终端1中执行for.sh
# vi for.sh
#!/bin/bash
for ((i=0; i<=1000; i=i+1))
    do
        echo 11 >> /root/for.log
        sleep 10
    done

# nohup /root/for.sh &
// 关闭终端1
// 打开终端2,ps aux 可以看到for.sh仍在运行

系统资源查看

vmstat命令监控系统资源

vmstat [刷新延时 刷新次数]

$ vmstat 1 3
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0  70280 133280  13140 303244    0    4    60    16   53  121  1  1 98  0  0
 0  0  70280 133264  13140 303248    0    0     0     0   40  201  1  0 99  0  0
 0  0  70280 133264  13140 303248    0    0     0     0   43  183  1  0 99  0  0
  • process 进程信息字段
    -r 等待运行的进程数,数量越大,系统越繁忙
    -b 不可被唤醒的进程数量,数量越大,系统越繁忙
  • memory 内存信息字段
    -swpd 虚拟内存的使用情况,单位KB
    -free 空闲的内存容量,单位KB
    -buff 缓冲的内存容量,单位KB
    -cache 缓冲的内存容量,单位KB
  • swap 交换分区的信息字段
    -si 从磁盘中交换到内存中数据的数量,单位KB
    -so 从内从中交换到磁盘中数据的数量,单位KB。此两个数越大,证明数据需要经常在磁盘和内存之间交换,系统性能越差。
  • io 磁盘读写信息字段
    -bi 从块设备读入数据的总量,单位是块
    -bo 写到块设备的数据的总量,单位是块。次两个数越大,代表系统的I/O越繁忙。
  • system 系统信息字段
    -in 每秒被中断的进程次数
    -cs 每秒中进行的时间切换次数。此两个数越大,代表系统与接口设备的通信非常繁忙。
  • CPU CPU信息字段
    -us 非内核进程消耗CPU运算时间的百分比
    -sy 内核进程消耗CPU运算时间的百分比
    -id 空闲CPU的百分比
    -wa 等待I/O所消耗的CPU百分比
    -st 被虚拟机所盗用的CPU占比

dmesg开机时内核检测信息

$ dmesg |grep CPU

free命令查看内存使用状态

  • free [-b|-k|-m|-g]
    • 选项
      -b 以字节为单位显示
      -k 以KB为单位显示,默认就是以KB为单位显示
      -m 以MB为单位显示
      -g 以GB为单位显示
/*
    total 总内存数
    used 已经使用内存数
    free 空闲的内存数
    shared 多个进程共享的内存数
    buffers 缓冲内存数
    cached 缓存内存数
    默认单位是KB
*/
$ free -m
              total        used        free      shared  buff/cache   available
Mem:            983         545         124           6         313         273       
Swap:          1906          68        1838

查看CPU信息

$ cat /proc/cpuinfo

uptime命令

显示系统的启动时间和平均负载,也就是top命令的第一行。w命令也可以看到这个数据。

$ uptime
 10:10:47 up  6:11,  1 user,  load average: 0.18, 0.10, 0.09

$ w
 10:11:35 up  6:12,  1 user,  load average: 0.09, 0.09, 0.09
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root   tty7     :016   17:20m 49.38s  0.28s /sbin/upstart --user

查看系统与内核相关信息

  • uname [选项]
    • 选项
      -a 查看系统所有相关信息
      -r 查看内核版本
      -s 查看内核名称

判断当前系统的位数

  • file /bin/ls

查看当前Linux系统的发行版本

  • lsb_release -a

列出进程打开或使用的文件信息

  • lsof [选项]
    列出进程调用或打开文件的信息
    • 选项
      -c 字符串 只列出以字符串开头的进程打开的文件
      -u 用户名 只列出某个用户的进程打开的文件
      -p pid 列出某个PID进程打开的文件
// 查询系统中所有进程调用的文件
$ lsof |more
// 查询某个文件被哪个进程调用
$ lsof /sbin/init
// 查看httpd进程调用了哪些文件
$ lsof -c httpd
// 按照用户名,查询某个用户进程调用的文件
$ lsof -u root

缓存和缓冲的区别
简单来说缓存(cache)用来加速数据从硬盘中“读取”的,而缓冲(buffer)用来加速数据“写入”硬盘的。

系统定时任务

  • at一次性定时任务
  • crontab循环定时任务
  • 系统的crontab设置
  • anacron配置

at命令

确定at安装

// at 服务是否安装
# chkconfig --list |grep atd
# service atd status

at的访问控制

  • 如果系统中有/etc/at.allow文件,那么只有写入/etc/at.allow文件(白名单)中的用户可以使用at命令(/etc/at.deny文件会被忽略)

  • 如果系统中没有/etc/at.allow文件,只有/etc/at.deny文件,那么写入/etc/at.deny文件(黑名单)中的用户不能使用at命令。对root不起作用

  • 如果系统中这两个文件都不存在,那么只有root用户可以使用at命令

at命令

at [选项] 时间
选项
-m 当at工作完成后,无论是否命令有输出,都用email通知执行at命令的用户
-c 工作号 显示该at 工作的实际内容
时间:
-HH:MM 例如:02:30
-HH:MM YYYY-MM-DD 例如:02:30 2013-07-25
-HH:MM [am|pm] [month] [date] 例如:02:30 July 25
-HH:MM [am|pm] + [minutes|hours|days|weeks] 例如:now + 5 minutes

例子

$ at now +2 minutes
at> /root/hello.sh >> /root/hello.log
at> <EOT>

// 指定时间重启
$ at 02:00 2013-07-26
at>/bin/sync
at>/sbin/shutdown -r now

其他at管理命令

  • atq

    • 查询当前服务器上的at工作
  • atrm [工作号]

    • 删除指定的at任务

crontab

crond服务管理与访问控制

// 检查crond服务是否安装启动
# service crond restart
# chkconfig crond on

访问控制

  • 当系统中有/etc/cron.allow文件时,只有写入此文件的用户可以使用crontab命令,没有写入的用户不能使用crontab命令。同样如果有此文件,/etc/cron.deny文件会被忽略,/etc/cron.allow文件的优先级更高

  • 当系统中只有/etc/cron.deny文件时,则写入此文件的用户不能使用crontab命令,没有写入文件的用户可以使用crontab命令

用户的crontab设置

  • crontab [选项]
    • 选项:
      -e 编辑crontab定时任务
      -l 查询crontab任务
      -r 删除当前用户所有的crontab任务
// 编辑crontab命令
$ crontab -e
***** command
项目含义范围
第一个*一小时当中的第几分钟0-59
第二个*一天当中的第几小时0-23
第三个*一个月当中的第几天1-31
第四个*一年当中的第几个月1-12
第五个*一周当中的星期几0-7(0和7都代表星期日)
特殊符号含义
*代表任何时间。比如第一个“*”就代表一小时中的每分钟都执行一次的意思
,代表不连续的时间。比如“0 8,12,16 * * * 命令”,就代表每天的8点0分,12点0分,16点0分都执行一次命令
-代表连续的时间范围,比如“0 5 * * 1-6 命令”,代表在周一到周六凌晨5点0分执行命令
*/n代表每隔多久执行一次。比如“ */10 * * * * 命令”,代表每隔10分钟就执行一遍命令
// cron命令,每月1号和15号,每周1的0点0分都会执行
// 注意:星期几和几号最好不要同时出现,他们定义的都是天。非常迷惑。
0 0 1,15 * 1 命令

// 例子
// 每隔5分钟在/root/test中写入111
*/5 * * * * echo 111 >> /root/test

crontab注意事项

  • 六个选项不能为空,必须填写。如果不确定使用“*”代表任意时间。

  • crontab定时任务,最小有效时间是分钟,最大时间范围是月。想2018年某时执行,3点30分30秒这样的时间都不能识别。

  • 在定义时间时,日期和星期最好不要在一条定时任务中出现,因为他们都是以天作为单位,飞铲更容易让管理员混乱。

  • 在定时任务中,不管是直接写命令,还是在脚本中写命令,最好都是用绝对路径

注:定时任务自带的环境变量与$PATH中的保存的环境变量不一定相同,所以在crontab中使用绝对路径。

系统定的crontab设置

“crontab -e”是每个用户执行的命令,也就是说不同的用户身份可以执行自己的定时任务。可是有些定时任务需要系统执行,这是我们就需要编辑/etc/crontab这个配置文件。

// 这里crontab是普通用户的定时任务
$ crontab -e 

// 系统定时任务
// CentOS 5 中的配置文件
$ vim /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/

#run-parts
01 * * * * root run-parts /etc/cron.hourly
02 4 * * * root run-parts /etc/cron.daily
22 4 * * 0 root run-parts /etc/cron.weekly
42 4 1 * * root run-parts /etc/cron.monthly
// 查看/etc下crontab相关的目录和文件
# ls /etc/cron
cron.d/       cron.hourly/  crontab       
cron.daily/   cron.monthly/ cron.weekly/  

执行系统的定时任务的方法

  • 手工执行定时任务

  • 系统定时任务

    • 第一种是把需要定时执行的脚本复制到/etc/cron.{daily, weekly, monthly}目录中任意一个

    • 第二种是修改/etc/crontab配置文件

anacron配置

anacron是用来保证在系统关机的时候错过的定时任务,可以在系统开机之后再执行

anacron检测周期

  • anacron会使用一天,七天,一个月作为检测周期

  • 在系统的/var/spool/anacron/目录中存在cron.{daily, weekly, monthly}文件,用于记录上次执行cron的时间

  • 和当前时间作比较,如果两个时间的差值超过了anacron的指定时间差值,证明有cron任务没有被执行

CentOS 6.x 的区别

  • 在老的CentOS版本中,/etc/cron.{daily, weekly, monthly}这些目录即会被cron调用,也会被anacron调用,容易重复执行

  • 在CentOS 6.x中则只会被anacron调用,避免了重复执行

  • 在CentOS 6.x中,anacron不再是服务,而是系统命令

anacron配置文件

$ vi /etc/anacrontab

# /etc/anacrontab: configuration file for anacron

# See anacron(8) and anacrontab(5) for details.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
HOME=/root
LOGNAME=root

RANDOM_DELAY=45

START_HOURS_RANGE=3-22

# These replace cron's entries
1       5       cron.daily      run-parts --report /etc/cron.daily
7       10      cron.weekly     run-parts --report /etc/cron.weekly
@monthly        15      cron.monthly    run-parts --report /etc/cron.monthly
#天数    强制延迟(分钟)    工作名称    实际执行的命令

cron.daily工作来说明执行过程

  • 首先读取/var/spool/anacron/cron.daily中上一次anacron执行的时间

  • 和当前时间比较,如果两个时间差值超过1天,就执行cron.daily工作

  • 执行这个工作只能在03:00-22:00之间

  • 执行工作时强制延迟时间为5分钟,再随机延迟0-45分钟时间

  • 使用nice命令指定默认优先级,使用run-parts脚本执行/etc/cron.daily目录中所有可执行文件

参考

Linux中的计划任务-Crontab
慕课网Linux系统管理课程

打赏

支付宝

alipay

微信

wechat

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值