高可用ftp、sftp服务器的搭建

ftp基础服务的搭建

安装vsftpd服务

  1. 检查vsftpd服务是否已安装?
sudo rpm -qa |grep vsftpd
  1. 如果没安装,则先安装vsftpd服务
sudo yum install vsftpd –y
  1. vsftpd服务控制命令
查看 sudo service vsftpd status
启动 sudo service vsftpd start
停止 sudo service vsftpd stop
重启 sudo service vsftpd restart

用户及目录创建

  1. 创建FTP所需目录
sudo mkdir /service
sudo mkdir /service/vsftpd_files
  1. 创建目录所属用户,注意修改密码及实际目录
sudo useradd -d /service/vsftpd_files -g ftp ftpuser
sudo passwd ftpuser
EP7fXKdniOvRfI3p
sudo chown -R ftpuser:ftp /service/vsftpd_files
  1. 权限配置
    编辑vsftpd文件
sudo vi /etc/vsftpd/vsftpd.conf

放开如下 chroot 的注释:
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chroot_list

添加权限控制用户到如下文件

sudo vi /etc/vsftpd/chroot_list

重启FTP服务

sudo service vsftpd restart

使用创建好的用户登录测试上传、下载、删除操作。
FTP备用节点,步骤完全参照上述,一模一样即可。

ssh端口与sftp端口分离

由于sftp是ssh内含的协议,只要sshd服务器启动了,它就可用,并且都是走22端口,如果有需求需要某用户只能使用sftp方式登录系统存取文件,而不能使用ssh方式登录系统,这是就需要将sftp的端口修改成其他端口。
创建两个‘sshd’进程,一个作为ssh服务的deamon,一个作为sftp服务的deamon,要实现ssh和sftp分离,分别监听不同的端口,可以通过创建两个‘/usr/sbin/sshd’后台程序,一个监听22端口(ssh),一个监听10022端口(sftp),为了区分ssh和sftp服务的后台程序

修改配置文件

  1. 将sshd文件复制一份命名为sftpd文件
sudo cp /usr/lib/systemd/system/sshd.service /etc/systemd/system/sftpd.service
  1. 修改sftpd.service文件,修改成如下图红框中的内容
sudo vim /etc/systemd/system/sftpd.service

在这里插入图片描述
EnvironmentFile=/etc/sysconfig/sftpd
ExecStart=/usr/sbin/sftpd -D $OPTIONS -f /etc/ssh/sftpd_config

  1. 创建/etc/pam.d/sftpd
sudo cp /etc/pam.d/sshd /etc/pam.d/sftpd
  1. 建立软连接
sudo ln -sf /usr/sbin/sshd /usr/sbin/sftpd
  1. 创建修改/etc/sysconfig/sftp文件
    在这里插入图片描述
sudo cp /etc/sysconfig/sshd /etc/sysconfig/sftpd
sudo vim /etc/sysconfig/sftpd 注释掉原有的内容

添加一项: SFTPD_OPTS=""

创建sftp配置文件

  1. 通过copy sshd_config文件得到sftpd_config
sudo cp /etc/ssh/sshd_config /etc/ssh/sftpd_config
  1. 编辑sftpd_config文件,需要修改的地方如下图红框
sudo vi /etc/ssh/sftpd_config

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  1. 如果你关闭了SELinux,可以忽略该步骤
    先查看SELinux开放给ssh使用的端口
semanage port -l | grep ssh

如果SELinux没有给SSH开放10022端口,那么需要添加该端口

sudo  semanage port -a -t ssh_port_t -p tcp 10022

服务测试

  1. 重启服务
sudo service sshd restart
sudo service sftpd restart
sudo service sftpd status

若启动报错可查询相关日志

sudo cat /var/log/messages | grep
  1. sftp命令测试
sftp -o Port=10022 ${用户名}@${ip}
  1. ssh命令测试
ssh -o Port=10022 ${用户名}@${ip}

关闭22号端口下的sftp服务

  1. 方式一
    编辑/usr/sbin/sshd的配置文件/etc/ssh/sshd_config文件,将Subsystem参数注释掉,然后重启sshd
sudo vim /etc/ssh/sshd_config

在这里插入图片描述

  1. 方式一
    方式二(慎重操作,记忆允许的用户组):也可以设置可访问22号端口的用户白名单:编辑/etc/ssh/sshd_config文件,设置AllowGroups参数(假设设置为AllowGroups sshonly),限制仅AllowGroups组内的用户可通过22号端口ssh登录系统(对于需要ssh登录系统的用户可通过usermod -A sshonly 将其加入到AllowGroups组内)
sudo vim /etc/ssh/sshd_config

AllowGroups sshonly
在这里插入图片描述
重启sshd:

sudo service sshd restart

高可用的安装与配置

机器准备

  1. 机器信息
    两台 CentOS7 服务器,IP 地址分别为 172.xx.xx.31(主)、172.xx.xx.32(从)
    vip 地址:172.xx.xx.30
    登录服务器用户密码:mtnsadmin/xxxxxxxxx
  2. 补充,sftp权限访问控制
    设置SFTP访问需要控制访问目录权限:
    编辑/etc/ssh/sshd_config,执行命令:sudo vim /etc/ssh/sshd_config
Subsystem sftp internal-sftp #指定使用 sftp 服务使用系统自带的 internal-sftp
Match User prodamiftp #匹配用户,如果要匹配多个组,多个组之间用逗号分割 ChrootDirectory /u01/prod/ALL_FTP_Files/AMI_Files #用chroot将指定用户的根目录 Match User prodwmsftp
ChrootDirectory /u01/prod/ALL_FTP_Files/WMS_Files
Match User prodhapftp
ChrootDirectory /u01/prod/ALL_FTP_Files/HAP_Files
  1. 备注
    ChrootDirectory 设置的目录权限及其所有的上级文件夹权限,属主和属组必须是 root
    目录权限及其所有的上级文件夹,权限可以是 755 或者 750
    在 ChrootDirectory 下新建的目录,属主属组需要属于对应的 User
    参考链接:Linux下sftp服务配置操作说明

安装LVS

  1. 通过安装
sudo yum install ipvsadm -y

安装及配置keepalived

  1. 通过源码安装
    链接:http://www.keepalived.org/download.html 下载keepalived-2.0.12.tar.gz,
    将该文件包放置在FTP /home/mtnsadmin/package目录下,两个节点都需要安装配置
  2. 解压
cd /home/mtnsadmin/package 
tar -zxvf keepalived-2.0.12.tar.gz
  1. 安装编译
    LVS采用的是yum安装:
sudo yum install ipvsadm
cd keepalived-2.0.12
./configure --prefix=/usr/local/keepalived
sudo make && sudo make install(需要安装openssl: yum install openssl*,如没有安 装线执行安装)

备注:安装过程中如果出现以下提示:
在这里插入图片描述
解决,执行:

yum install -y libnl3.x86_64
yum install -y libnl3-devel.x86_64
  1. 拷贝配置文件
sudo mkdir /etc/keepalived
sudo cp /home/mtnsadmin/package/keepalived- 2.0.12/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf
sudo cp /home/mtnsadmin/package/keepalived- 2.0.12/keepalived/etc/init.d/keepalived /etc/init.d/
sudo cp /home/mtnsadmin/package/keepalived- 2.0.12/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
sudo cp /usr/local/keepalived/sbin/keepalived /usr/sbin/
  1. 配置keepalived.conf
    主节点的配置信息:
sudo vim /etc/keepalived/keepalived.conf
global_defs {
router_id LVS_FTP enable_script_security script_user root
}
vrrp_sync_group VGM {
   group {
     VI_FTP
} }
vrrp_script check_ftp {
script "/etc/keepalived/check_ftp.sh" interval 2
#weight 2
#user root
}
vrrp_instance VI_FTP {
state MASTER interface ens160 virtual_router_id 51 priority 100 advert_int 1 authentication {
auth_type PASS
auth_pass 1111 }
virtual_ipaddress { 172.xx.xx.30
}
track_script {
check_ftp }
}
virtual_server 172.xx.xx.30 21 { delay_loop 6
lb_algo wlc
lb_kind DR
#net_mask 255.255.225.128 persistence_timeout 50 protocol TCP
real_server 172.xx.xx.31 21 { weight 3
MISC_CHECK {
connect_timeout 10 nb_get_retry 3 delay_before_retry 3 connect_port 21
} }
real_server 172.xx.xx.32 21 { weight 1
MISC_CHECK {
connect_timeout 10 nb_get_retry 3 delay_before_retry 3 connect_port 21
} }
}

从节点的配置信息:

global_defs {
router_id LVS_FTP enable_script_security script_user root
}
vrrp_sync_group VGM { group {
VI_FTP }
}
vrrp_script check_ftp {
script "/etc/keepalived/check_ftp.sh" interval 2
#weight -2
#user mtnsadmin
}
vrrp_instance VI_FTP { state BACKUP
interface ens160 virtual_router_id 51 priority 50 advert_int 1 authentication {
auth_type PASS auth_pass 1111
}
virtual_ipaddress { 172.xx.xx.30
}
track_script {
check_ftp }
}
virtual_server 172.xx.xx.30 21 { delay_loop 6
lb_algo wlc
lb_kind DR
#net_mask 255.255.225.128 persistence_timeout 50 protocol TCP
real_server 172.xx.xx.31 21 { weight 3
MISC_CHECK { connect_timeout 10 nb_get_retry 3 delay_before_retry 3 connect_port 21
} }
real_server 172.xx.xx.32 21 { weight 1
MISC_CHECK { connect_timeout 10 nb_get_retry 3 delay_before_retry 3 connect_port 21
} }
}

keepalived.conf的配置可能根据不通供应商的服务器有些不通的配置,例如腾讯云服务器,需要增加配置:

unicast_src_ip 172.xx.xx.79 #本机内网 IP unicast_peer {
172.xx.xx.80 #对端设备的 IP 地址
}

否则主备节点无法通信,会导致主备节点均会出现vip的情况,所以这里的配置最好去参考官方的文档。

  1. 编辑check_ftp.sh
vim /etc/keepalived/check_ftp.sh

主节点如下:

#!/bin/bash
ftppid=`ss -antp |grep vsftp | wc -l` if [ $ftppid -eq 0 ];then
ps -ef | grep inotify | grep -v grep | awk '{print $2}' | xargs kill -9;
   systemctl stop keepalived.service;
fi

从节点如下:

#!/bin/bash
ftppid=`ss -antp |grep vsftp | wc -l` if [ $ftppid -eq 0 ];then
systemctl stop keepalived.service;
fi

并分别修改文件属性:chown a+x /etc/keepalived/check_ftp.sh

  1. 启停keepalived
#启动keepalived服务
sudo systemctl start keepalived.service #停止keepalived服务
sudo systemctl stop keepalived.service #重启keepalived服务
sudo systemctl restart keepalived.service #查看keepalived服务
sudo systemctl status keepalived.service

通过启停keepalived服务查看vip是否有效漂移,执行命令:ip a查看:
在这里插入图片描述
在这里插入图片描述

安装及配置rsync

  1. 通过yum安装
    主从节点均安装并配置
sudo yum -y install rsync
  1. 编辑rsyncd.conf
sudo vim /etc/rsyncd.conf

主节点内容如下:

uid = 0
gid = 0
use chroot = no
max connections = 10
log file = /var/log/rsyncd.log [ftprsyncd]
path = /u01/prod/ALL_FTP_Files ignore errors
read only = no
list = no
hosts allow = 172.xx.xx.32/25 auth users = ftprsyncd
secrets file = /etc/rsyncd.secrets

从节点内容如下:

uid = 0
gid = 0
use chroot = no
max connections = 10
log file = /var/log/rsyncd.log [ftprsyncd]
path = /u01/prod/ALL_FTP_Files ignore errors
read only = no
list = no
hosts allow = 172.xx.xx.31/25 auth users = ftprsyncd
secrets file = /etc/rsyncd.secrets

use chroot:若为 true,则 rsync 在传输文件之前首先 chroot 到 path 参数所指定的目 录下。这样做的原因是实现额外的安全防护,但是缺点是需要 root 权限,并且不能备 份指向 path 外部的符号连接所指向的目录文件。
uid: 指定该模块以指定的 UID 传输文件。 gid: 指定该模块以指定的 GID 传输文件。
max connections:指定该模块的最大并发连接数量以保护服务器,超过限制的连接请 求将被告知随后再试。
log file:指定 rsync 守护进程的日志文件,而不将日志发送给 syslog [ftprsyncd]:模块名称。
path:指定当前模块在 rsync 服务器上的同步路径,该参数是必须指定的。
ignore errors:指定在 rsync 服务器上运行 delete 操作时是否忽略 I/O 错误。一般来 说 rsync 在出现 I/O 错误时将将跳过 –delete 操作,以防止因为暂时的资源不足或其它 I/O 错误导致的严重问题。
read only:指定是否允许客户上传文件。若为 true 则不允许上传;若为 false 并且服 务器目录也具有读写权限则允许上传。
list:指定当客户请求列出可以使用的模块列表时,该模块是否应该被列出。如果设置 该选项为 false,可以创建隐藏的模块
auth users:指定由空格或逗号分隔的用户名列表,只有这些用户才允许连接该模块。 这里的用户和系统用户没有任何关系。用户名和口令以明文方式存放在 secrets file 参 数指定的文件中。
secrets file:指定一个 rsync 认证口令文件。只有在 auth users 被定义时,该文件才起 作用

  1. 编辑rsync 认证口令
sudo vim /etc/rsyncd.secrets
内容如下:
#是配置文件rsyncd.conf里auth users设置账号对应的密码 ${user}:${password}
设置权限为600
sudo chmod 600 /etc/rsyncd.secrets
  1. 启停rsync
sudo rsync --daemon
或者
sudo systemctl start rsyncd.service
检测rsync服务是否启动
sudo ss -anpt|grep 873
设置rsync服务开机自启动
sudo systemctl enable rsyncd.service

安装及配置inotify

只需要在主节点安装配置即可

  1. 先安装epol源
sudo wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel- 7.repo
  1. 通过yum安装
sudo yum install inotify-tools -y
  1. 配置inotify
vim /home/mtnsadmin/inotify.sh

通过inotify命令监控主节点的/u01/prod/A LL_FTP_Files/目录文件有变动就自动同步至 从节点,内容如下:

#!/bin/bash
/usr/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f' -e modify,delete,create,attrib ${文件路径} | while read file
do
rsync -vzurtopg --delete --progress ${文件路径} ftprsyncd@172.xx.xx.32::ftprsyncd --password- file=/etc/rsyncd.secret
done

备注:
认证口令文件(这里是/etc/rsyncd.secrets),有的服务器支持username: password,有 的服务器只支持password,所以需要在客户端单独指定个认证口令文件作自动同步认 证。例如:
rsync -vzurtopg --delete --progress {文件路径} ftprsyncd@172.xx.xx.32::ftprsyncd --password-file= /home/mtnsadmin/rsyncd.secret
使用命令查看:cat /home/mtnsadmin/rsyncd.secret:

rsync的选项说明:

-v:显示 rsync 过程中详细信息。可以使用"-vvvv"获取更详细信息。 
-P:显示文件传输的进度信息。(实际上"-P"="--partial --progress",其中的"--progress"才是显示进度信息的)。 
-n --dry-run :仅测试传输,而不实际传输。常和"-vvvv"配合使用来查看rsync是如何工作的。
-a --archive :归档模式,表示递归传输并保持文件属性。等同于"-rtopgDl"。
-r --recursive:递归到目录中去。
-t --times:保持 mtime 属性。强烈建议任何时候都加上"-t",否则目标文件 mtime 会设置为系统时间,导致下次更新:检查出 mtime 不同从而导致增量传输无效。 
-o --owner:保持 owner 属性(属主)。
-g --group:保持 group 属性(属组)。
-p --perms:保持 perms 属性(权限,不包括特殊权限)。
-D :是"--device --specials"选项的组合,即也拷贝设备文件和特殊文件。
-l --links:如果文件是软链接文件,则拷贝软链接本身而非软链接所指向的对象。
-z :传输时进行压缩提高效率。
-R --relative:使用相对路径。意味着将命令行中指定的全路径而非路径最尾部的文件名发送给服务端,包括它们的属性。用 法见下文示例。
--size-only :默认算法是检查文件大小和 mtime 不同的文件,使用此选项将只检查文件大小。
-u --update :仅在源 mtime 比目标已存在文件的 mtime 新时才拷贝。注意,该选项是接收端判断的,不会影响删除行为。
-d --dirs :以不递归的方式拷贝目录本身。默认递归时,如果源为"dir1/file1",则不会拷贝dir1目录,使用该选项将拷 贝 dir1 但不拷贝 file1。
--max-size :限制rsync传输的最大文件大小。可以使用单位后缀,还可以是一个小数值(例如:"--max-size=1.5m") 
--min-size :限制rsync传输的最小文件大小。这可以用于禁止传输小文件或那些垃圾文件。 
--exclude :指定排除规则来排除不需要传输的文件。
--delete :以 SRC 为主,对 DEST 进行同步。多则删之,少则补之。注意"--delete"是在接收端执行的,所以它是在 :exclude/include 规则生效之后才执行的。 
-b --backup :对目标上已存在的文件做一个备份,备份的文件名后默认使用"~"做后缀。
--backup-dir:指定备份文件的保存路径。不指定时默认和待备份文件保存在同一目录下。
-e :指定所要使用的远程 shell 程序,默认为 ssh。
--port :连接 daemon 时使用的端口号,默认为 873 端口。
--password-file:daemon 模式时的密码文件,可以从中读取密码实现非交互式。注意,这不是远程 shell 认证的密码,而是 rsync 模块认证的密码。
-W --whole-file:rsync将不再使用增量传输,而是全量传输。在网络带宽高于磁盘带宽时,该选项比增量传输更高效。 
--existing :要求只更新目标端已存在的文件,目标端还不存在的文件不传输。注意,使用相对路径时如果上层目录不存在也 不会传输。
--ignore-existing:要求只更新目标端不存在的文件。和"--existing"结合使用有特殊功能,见下文示例。 
--remove-source-files:要求删除源端已经成功传输的文件。

Inotify-tools选项说明:

Inotify-tools 提供的两个工具
inotifywait: 通过inotify API等待被监控文件上的相应事件并返回监控结果。 
inotifywatch: 用于收集关于被监视的文件系统的统计数据。
inotifywait:
-m :实时监控。 
-d :后台运行。 
-r :递归,对子目录监控。 
-e :监控事件。
以下 access:检测文件访问事件。 
close_write:写入关闭事件。 
modify:文件发生变化。
attrib:文件属性变化事件。
delete:文件被删除。
--timefmt :当在--format 选项中使用%T 时,--timefrt 选项则可以用来指定自定义的符合 strftime 规范的时间格式,此时间 格式可用的格式符可以通过 strftime 的手册页获取;--timefrt 后常用的参数是'%d/%m/%y %H:%M';
--format :自定义 inotifywait 的输出格式,如--format '%T %w %f';常用的格式符如下:
%w:显示被监控文件的文件名;
%f:如果发生某事件的对象是目录,则显示被监控目录的名字;默认显示为空串;
%T:使用--timefmt 选项中自定义的时间格式.
eg. inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f' -e close_write /data #输出时间
eg. innotifywait -mrq --format '%w%f' -e create,close_write,delete /data #简化输出
-m :永远监控,实时监控。
-d:后台运行。
-q:仅打印监控事件的信息。
-r:递归,对子目录监控。
-e:监控事件。以下
access:检测文件访问事件。
close_write:写入关闭事件。
modify:文件发生变化。
attrib:文件属性变化事件。
delete:文件被删除。
--timefmt :当在--format 选项中使用%T 时,--timefrt 选项则可以用来指定自定义的符合 strftime 规范的时间格式,此时间 格式可用的格式符可以通过 strftime 的手册页获取;--timefrt 后常用的参数是 '%d/%m/%y %H:%M';
--format :自定义 inotifywait 的输出格式,如--format '%T %w %f';常用的格式符如下:
%w:显示被监控文件的文件名.
%f:如果发生某事件的对象是目录,则显示被监控目录的名字;默认显示为空串;
%T:使用--timefmt 选项中自定义的时间格式.
eg. inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f' -e close_write /data #输出时间.
eg. innotifywait -mrq --format '%w%f' -e create,close_write,delete /data #简化输出.
inotifywait 主要用到的参数:
-m|--monitor 永远监听事件。
-d|--daemon 后台运行,以守护进程方式运行
-r|--recursive 递归监控
-e|--event 监听事件
  1. 启动inotify
    主从服务器需要开通22、873端口。
cd /home/mtnsadmin/
nohup ./inotify.sh > rsync.log 2>&1 &

使用说明书

  1. 起停脚本
    在用户的根目录,vim start.sh
    主节点内容如下:
#!/bin/bash
if [ ! -n "$1" ] ;then
	echo "输入一个命令,例如:start|stop 启动|停止"; 
elif [ $1 = "start" ] ;then
	echo " 启动vsftp服务 ";
	sudo service vsftpd start;
	echo " 启动 keepalived 服务 ";
	sudo systemctl start keepalived.service; 
	echo " 清除内核虚拟服务器列表中的所有记录 " sudo ipvsadm -C ;
	echo " 启动inotify"
	nohup ./inotify.sh > ./logs/rsync.log 2>&1 &
elif [ $1 = "stop" ] || [ $1 = "stp" ] ; then 
	echo " 停止vsftp服务 ;
	sudo service vsftpd stop ; echo"停止keepalived服务 ;
	sudo systemctl stop keepalived.service;
	echo "停止 inotify"
	ps -ef | grep inotify | grep -v grep | awk '{print $2}' | xargs kill -9;
fi

从节点内容如下:

#!/bin/bash
if [ ! -n "$1" ] ;then
	echo "输入一个命令,例如:start|stop 启动|停止"; 
elif [ $1 = "start" ] ;then
	echo " 启动vsftp服务 ";
	sudo service vsftpd start;
	echo " 启动 keepalived 服务 ";
	sudo systemctl start keepalived.service; 
	echo " 清除内核虚拟服务器列表中的所有记录 " sudo ipvsadm -C ;
elif [ $1 = "stop" ] || [ $1 = "stp" ] ; then 
	echo " 停止vsftp服务 ;
	sudo service vsftpd stop ; 
	echo"停止keepalived服务 ;
	sudo systemctl stop keepalived.service; 
fi
  1. 启停顺序
    启动顺序,先启动ftp主节点,再启动ftp从节点;
    停止顺序:先停止ftp从节点,再停止ftp主节点。
  2. 启停命令
    启停服务请使用start.sh,因为服务间是相互依赖的关系,rsync服务、keepalived 服务是依赖ftp服务是正常使用的情况下来进行开启服务的,如果ftp服务down 了,则rsync服务、keepalived服务会通过keepalived里的check_ftp.sh脚本检查进 行关闭。
    执行命令:
启动:./start.sh start 
停止:./start.sh stop
  1. 启动后检查
    ftp等服务正常启动后,检查vip地址停留在哪台服务器,正常情况下应该停留在ftp
    主节点(172.xx.xx.31),执行命令:ip a查看:
    在这里插入图片描述
    查看ftp服务:ps -ef|grep vsftpd
    查看keepalived服务:ps -ef|grep keepalived/ systemctl status
    keepalived.service 查看inotify服务:ps -ef|grep inotify
  2. 故障修复后启停说明
    当ftp主节点服务器down了,等主节点修复后,需要人工检查主从文件是否一致,
    然后把从节点的服务也停了,进行主从节点的文件同步;

高可用 ftp 服务主节点故障后切回主节点步骤:

  1. 前提确保准备切回主节点前,没有任何系统连接ftp 服务,这样是为了避免数据丢失
  2. 停止从节点 ftp 服务,同时确保主节点 ftp 服务均是停止状态
  3. 将从节点 ftp 文件目录同步至主节点,在从节点服务器上执行:
rsync -vzurtopg --progress --delete ${ftp文件路径} ftprsyncd@172.xx.xx.79::ftprsyncd -- password-file=/home/mtnsadmin/rsyncd.secrets
  1. 先启动主节点,再启动从节点
  2. 检查下主从节点是否正常,检查连接 ftp 读写传输是否正常
  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值