MooseFS部署以及Rocky9 基于 Pacemaker+SBD 实现 MooseFS Master 双节点高可用

参考网址:Requirements for Chunkservers | MooseFS Documentation

iphostsrole
192.168.73.171server1master
192.168.73.172server2chunkserver
192.168.73.173server3chunkserver
192.168.73.174server4client

  • mfsmaster(管理主节点) 保存全集群元数据:目录树、文件权限、文件分块位置;统一调度读写;社区版默认单点,元数据常驻内存,文件越多内存占用越高。
  • mfschunkserver(数据存储节点) 真正存放业务数据;文件默认切分为 64MB 的 chunk 块;支持副本复制 / 纠删码 EC 冗余;节点可横向在线扩容、下线维护;读写并行分担压力。
  • mfsmetalogger(元数据日志备份节点) 持续同步 master 元数据操作日志,周期性拉取完整元数据快照;master 宕机后,可手动升级 metalogger 为新 master,用于故障恢复(社区版无自动切换)MooseFS。
  • mfsmount(客户端) FUSE 实现挂载程序,mfsmount /mnt/mfs -H mfsmaster 挂载使用;Linux、FreeBSD、macOS 支持,PRO 版提供 Windows 原生客户端MooseFS。

MooseFs

四台机子全部操作

导入 MooseFS 官方 GPG 密钥 + 配置 yum 软件源

[root@server1 ~]# curl "https://repository.moosefs.com/RPM-GPG-KEY-MooseFS" > /etc/pki/rpm-gpg/RPM-GPG-KEY-MooseFS

[root@server1 ~]# curl "http://repository.moosefs.com/MooseFS-4-el9.repo" > /etc/yum.repos.d/MooseFS.repo

分别安装对应的软件

[root@server1 ~]# yum install moosefs-master moosefs-cgi moosefs-cgiserv moosefs-cli
[root@server2 ~]# yum install moosefs-chunkserver
[root@server3 ~]# yum install moosefs-chunkserver
[root@server4 ~]# yum install moosefs-client

[root@server5 ~]# yum install moosefs-chunkserver

添加master解析,五台机子都添加

所有节点必须能解析 mfsmaster 指向 server1,后续客户端、chunkserver 均使用该域名通信。

Master Server

设置开机自启

[root@server1 ~]# systemctl enable --now moosefs-gui
[root@server1 ~]# systemctl enable --now moosefs-master

查看端口是否正常开启

[root@server1 ~]# netstat -antlp

浏览器访问:192.168.73.171:9425

chunkservers

操作步骤:添加新磁盘----分区---格式化--挂载

server2 server3添加新磁盘

MooseFS 的 ChunkServer 严禁直接使用系统盘存放 chunk 数据,生产环境必须使用独立数据磁盘,这里演示 VMware 虚拟机新增 NVMe 磁盘,并格式化挂载给 mfschunkserver 使用。

注意关闭虚拟机添加,避免出现引导磁盘顺序混乱问题

查看磁盘添加是否成功

[root@server2 ~]# fdisk -l

创建分区

[root@server2 ~]# fdisk /dev/nvme0n2

格式化

[root@server2 ~]# mkfs.xfs /dev/nvme0n2p1

注意这里填写的是刚刚划分出来的分区

查看UUID

[root@server2 ~]# blkid

/dev/nvme0n2p1: UUID="c7e76afd-60a5-46a9-8619-4f5f09349ffb" TYPE="xfs" PARTUUID="47b36de4-01"
 

写入fstab配置文件

[root@server2 ~]# vim /etc/fstab

创建挂载点

[root@server2 ~]# mkdir /mnt/ssd01

添加挂载路径

[root@server2 ~]# vim /etc/mfs/mfshdd.cfg

刷新服务

[root@server2 ~]# systemctl daemon-reload

挂载

[root@server2 ~]# mount -a

df  查看挂载效果

修改权限,否则启动失败

MooseFS 运行用户 mfs 需要目录读写权限

[root@server2 ~]# chown mfs.mfs /mnt/ssd01

[root@server2 ~]# systemctl enable --now moosefs-chunkserver

server3同理

Client

server4

通过 FUSE 工具 mfsmount 将远端 MooseFS 分布式存储挂载到本地目录,像普通磁盘一样读写文件,无需修改业务代码。

[root@server4 ~]# mkdir -p /mnt/mfs
[root@server4 ~]# mfsmount /mnt/mfs -H mfsmaster

这里的主机名称一定要和一开始填写的解析名相同

网页查看

server5  新建部署chunkserver

把分布式数据块(chunk)存到这个挂载目录下面

MooseFS 支持分层存储: 一部分 ChunkServer 用 SSD(热数据高速存储),一部分 ChunkServer 用 HDD(冷数据大容量存储),通过标签区分,指定文件存在固态或者机械盘上docs.moose...。

mkdir /mnt/hdd01
chown mfs.mfs /mnt/hdd01
cd /etc/mfs/
vim mfshdd.cfg

[root@server5 ~]# systemctl enable --now moosefs-chunkserver

标签

命名建议:S 代表 SSD 高性能节点,H 代表 HDD 大容量归档节点,A/B/C 为机房 / 机架分组标签

默认不指定标签:数据可以存入任意可用 ChunkServer;设置标签约束后,副本只会调度到拥有对应标签的节点

[root@server2 ~]# vim /etc/mfs/mfschunkserver.cfg

这里注意格式逗号,我开始没有报错,但后面关机重启的时候爆大雷

[root@server2 ~]# systemctl reload moosefs-chunkserver.service

MooseFS Master 主备高可用完整部署流程(iSCSI 共享存储 + Pacemaker)

MooseFS 的 mfsmaster 是整个集群唯一调度元数据节点(单点核心),一旦宕机整个 MFS 不可读写。 方案思路:

  1. iSCSI:提供共享块存储,存放 Master 全部元数据(元数据两份主机共用同一份磁盘,保证数据一致)
  2. Pacemaker+Corosync:双机高可用集群管理器,实现故障自动切换
  3. VIP(虚拟 IP):对外统一访问入口,切换时 VIP 自动漂移
  4. 资源组顺序:iSCSI 登录 → 挂载共享磁盘 → 启动 mfsmaster → 绑定 VIP

PCS高可用

实验环境下,关闭防火墙,SELinux,设置时间同步

server1:192.168.73.171 mfsmaster

server5:192.168.73.175  mfsmaster备用节点

VIP:192.168.73.100 后续直接使用此VIP完整识别连接

集群名称:ha-cluster

1 5 同样操作

开启高可用仓库

Rocky Linux 9 默认没有启用 HighAvailability(高可用)仓库pacemaker、pcs、corosync 等高可用组件都存放在这个仓库内;这一步就是启用 HA 仓库,之后才能正常安装 Pacemaker 集群工具,用于 MooseFS Master 主备高可用。

[root@server1 ~]# cd /etc/yum.repos.d/
[root@server1 yum.repos.d]# vim rocky-addons.repo

将enabled改成  1

[root@server1 yum.repos.d]# yum list pacemaker

安装

安装高可用工具

[root@server1 yum.repos.d]# dnf install -y pacemaker corosync pcs fence-agents-all resource-agents

hacluster 设置相同密码(两台节点密码一致)

[root@server1 yum.repos.d]# echo westos |passwd --stdin hacluster

开启服务

[root@server1 yum.repos.d]# systemctl enable --now pcsd

vim /etc/hosts

mfsmaster指向VIP

节点认证   仅server1

这里Rocky9  和CentOs7 操作有些与不同

-u hacluster:指定认证用户为 hacluster(高可用内置账号,两台机器必须提前设置相同密码!) 执行后交互输入两台机器 hacluster 用户的密码,输出 Authorized 代表认证成功。

[root@server1 yum.repos.d]# pcs host auth server1 server5 -u hacluster

CentOs7是:pcs cluster auth server1 server5

创建集群 ha-cluster

这里也 不太一样:

CentOs:pcs cluster setup --name mycluster server1 server5

[root@server1 yum.repos.d]# pcs cluster setup ha-cluster server1 server5

所有节点启用开机自启、启动集群

[root@server1 yum.repos.d]# pcs cluster enable  --all

[root@server1 yum.repos.d]# pcs cluster start  --all

设置环境参数

实现环境禁用心跳检测,后面讲解 SDB +Fence时打开

[root@server1 yum.repos.d]# pcs property set stonith-enabled=false
[root@server1 yum.repos.d]# pcs property set no-quorum-policy=ignore

查看集群状态

[root@server1 yum.repos.d]# pcs status

配置iscsi存储 

存储 Target:192.168.73.174

集群节点: server1:192.168.73.171

                   server5:192.168.73.175

VIP:192.168.73.100

iSCSI IQN:iqn.2026-08.com.example:mfsdata

配置存储

server4添加硬盘作为iscsi共享盘

[root@server4 ~]# dnf install -y targetcli

targetcli 是 linux 下配置 iSCSI 共享存储的交互式工具

[root@server4 ~]# systemctl enable --now target

target = iSCSI Target 服务进程,负责对外提供共享磁盘

进入交互式配置界面

/dev/nvme0n2:本机独立磁盘(整块盘,不要提前分区格式化!只在客户端其中一台格式化一次

[root@server4 ~]# targetcli

[root@server2 ~]# targetcli
Warning: Could not load preferences file /root/.targetcli/prefs.bin.
targetcli shell version 2.1.53
Copyright 2011-2013 by Datera, Inc and others.
For help on commands, type 'help'.

/> ls
o- / .................................................................... [...]
o- backstores ......................................................... [...]
| o- block ............................................. [Storage Objects: 0]
| o- fileio ............................................ [Storage Objects: 0]
| o- pscsi ............................................. [Storage Objects: 0]
| o- ramdisk ........................................... [Storage Objects: 0]
o- iscsi ....................................................... [Targets: 0]
o- loopback .................................................... [Targets: 0]
/> cd /backstores/

/backstores> cd block

/backstores/block> create my_disk /dev/nvme0n2
Created block storage object my_disk using /dev/nvmen0n2.


/backstores/block> cd /

/> cd /iscsi

/iscsi> create iqn.2026-08.com.example:mfsdata
Created target iqn.2026-08.com.example:mfsdata.
Created TPG 1.
Global pref auto_add_default_portal=true
Created default portal listening on all IPs (0.0.0.0), port 3260.

/iscsi> cd iqn.2026-08.com.example:mfsdata/

/iscsi/iqn.20...ample:mfsdata> cd tpg1/luns
/iscsi/iqn.20...ata/tpg1/luns> create /backstores/block/my_disk
Created LUN 0.
/iscsi/iqn.20...ata/tpg1/luns> cd ..
/iscsi/iqn.20...:mfsdata/tpg1> ls
o- tpg1 ..................................................................................................... [no-gen-acls, no-auth]
  o- acls ................................................................................................................ [ACLs: 0]
  o- luns ................................................................................................................ [LUNs: 1]
  | o- lun0 ...................................................................... [block/my_disk (/dev/nvme0n2) (default_tg_pt_gp)]
  o- portals .......................................................................................................... [Portals: 1]
    o- 0.0.0.0:3260 ........................................................................................................... [OK]
/iscsi/iqn.20...:mfsdata/tpg1> cd acls
/iscsi/iqn.20...ata/tpg1/acls> create iqn.2026-08.com.example:client
Created Node ACL for iqn.2026-08.com.example:client
Created mapped LUN 0.

/iscsi/iqn.20...ge1/tpg1/acls> exit
Global pref auto_save_on_exit=true
Configuration saved to /etc/target/saveconfig.json

配置客户端

从这里开始为所有的实验经过,存在实验错误和步骤回退,后面有解决方案,行文叙述整体以实验步骤进行,但是会进行阐述说明正确的思路

server1  主 mfsmaster

安装 iSCSI 客户端工具包

[root@server1 ~]# yum install -y iscsi-initiator-utils.x86_64

配置客户端唯一 InitiatorName

[root@server1 ~]# vim /etc/iscsi/initiatorname.iscsi

使用 iscsiadm 执行发现,指定 Target 服务端 IP(示例:192.168.73.174)

[root@server1 ~]# iscsiadm -m discovery -t st -p 192.168.73.174

登录连接远端 iSCSI 块设备

[root@server1 ~]# iscsiadm -m node -l

查看,iscsi磁盘已就位

分区

[root@server1 ~]# fdisk  /dev/sda

输入m查看帮助,n是新建分区,p是划分磁盘,w是保存退出

[root@server1 ~]# lsblk

格式化

[root@server1 ~]# mkfs.xfs /dev/sda1

挂载

[root@server1 ~]# mount /dev/sda1 /mnt/

我们老师有这样一步操作 /dev/sda1 挂载到 /mnt/ 修改/mnt/权限为 mfs mfs 进入 /var/lib/mfs 复制全部到 /mnt/ 取消挂载 又挂载到 /var/lib/mfs 又取消 

[root@server1 ~]# umount /mnt

mount /dev/sda1 /mnt/

chown mfs:mfs /mnt

cp /var/lib/mfs/* /mnt

这一步操作是提前拷贝模版进iscsi共享盘

umount /mnt

挂载再卸载一次,提前发现 iSCSI 磁盘能不能正常挂载,避免集群拉起资源的时候才炸。

mount /dev/sda1 /var/lib/mfs

umount /var/lib/mfs

/var/lib/mfs 默认服务器本地就有空目录。 如果你不先把模板文件拷贝到 iSCSI 共享盘,后续集群挂载失败的时候,master 会直接读取本地空目录

/mnt 只是临时挂载入口,真正操作的底层设备永远是 /dev/sda1 这块 iSCSI 磁盘。 你在 /mnt 上改权限,改的是 磁盘里文件本身的属性;之后把同一块盘挂载到 /var/lib/mfs,看到的还是这批文件,权限自然继承下来。

server5安装master工具

[root@server5 ~]# yum install -y moosefs-master moosefs-cli moosefs-gui

[root@server5 ~]# yum install -y iscsi-initiator-utils.x86_64

[root@server5 ~]# iscsiadm -m discovery -t st -p 192.168.73.174

[root@server5 ~]# vim /etc/iscsi/initiatorname.iscsi

从这里开始就是错误的开始,建议两台mfsmaster设置不一样的   IQN ,为了防止后续虚拟机不停地抖动甚至闪退TCP会话连接,虚拟机界面频繁打印告警信息

同样的,server4进入 进入交互式配置界面,也要将相应的   IQN  添加进去

/iscsi/iqn.20...:mfsdata/tpg1> cd acls
/iscsi/iqn.20...ata/tpg1/acls> create server5的IQN

我这里的配图是当时实验的流程

重启 iscsid,让 iqn 名称配置生效

  • -m node:操作已经发现存储节点
  • -l = login,登录 iSCSI 共享存储

[root@server5 ~]# systemctl restart iscsid
[root@server5 ~]# iscsiadm -m node -l

整合iscsi存储和MooseFs

  • vip:自定义资源名
  • ocf:heartbeat:IPaddr2:VIP 资源代理(管理浮动虚拟 IP)
  • ip=192.168.73.100:对外提供服务的漂移 VIP
  • op monitor interval=30s:每 30 秒检测 VIP 是否正常运行

[root@server1 ~]# pcs resource create vip ocf:heartbeat:IPaddr2 ip=192.168.73.100 op monitor interval=30s

创建共享文件系统资源(mfsdata)

  • mfsdata:资源名
  • ocf:heartbeat:Filesystem:文件系统代理,自动挂载 / 卸载共享盘
  • device=/dev/sda1:iSCSI 共享磁盘分区(替换成你的真实共享设备
  • directory=/var/lib/mfs:挂载点
  • fstype=xfs:文件系统类型

[root@server1 ~]# pcs resource create mfsdata ocf:heartbeat:Filesystem device=/dev/sda1 directory=/var/lib/mfs fstype=xfs op monitor interval=30s

创建 MooseFS-Master 系统服务资源(mfsmaster)

  • systemd:moosefs-master:调用 systemd 管理 moosefs-master 服务(启动、停止、监控)
  • 监控间隔:60 秒检查一次服务状态

[root@server1 ~]# pcs resource create mfsmaster systemd:moosefs-master op monitor interval=1min

创建资源组,把 3 个资源打包在一起

  • mfsgroup:资源组名称
  • 组内顺序:vip → mfsdata → mfsmaster

启动顺序:先绑 VIP → 挂载共享盘 → 启动服务 故障切换停止顺序:停服务 → 卸载磁盘 → 释放 VIP 同一时刻整个组只会在一台节点运行,实现主备自动漂移

[root@server1 ~]# pcs resource group add mfsgroup vip mfsdata mfsmaster

报错:两台mfsmaster都不能正常启动

然后我从这里开始排错

先进入 /var/lib/mfs 查看  发现没有元数据

于是我开始回退

这里其实就是重复老师之前的步骤 ,因为我没有操作所以会没有数据模版和权限

清除集群内记录的故障状态、失败计数 Pacemaker 内部会记录 “这个资源启动失败多少次”,达到阈值后不再重试;cleanup 清空故障标记

[root@server1 ~]# pcs resource cleanup mfsgroup

临时解除集群托管 Pacemaker 不再自动管控这一组资源,不会反复尝试拉起 / 卸载,允许我们手动操作磁盘,避免集群和手动操作互相抢占冲突(非常关键,不然你 mount 会被 pacemaker 立刻 umount)


[root@server1 ~]# pcs resource unmanage mfsgroup

手动挂载 iSCSI 共享分区,这时你进入的才是共享存储,所以能看到真正的元数据文件:metadata.mfs

[root@server1 ~]# mount /dev/sda1 /var/lib/mfs
[root@server1 ~]# cd /var/lib/mfs
[root@server1 mfs]# ls
changelog.1.mfs  metadata.crc  metadata.mfs  metadata.mfs.back.1  stats.mfs

[root@server1 mfs]# chown -R mfs:mfs /var/lib/mfs

手动卸载,交还控制权,留给后面 Pacemaker 的 Filesystem 资源来负责挂载,不能集群托管期间自己永久挂载,会产生挂载冲突。

[root@server1 /]# umount /var/lib/mfs

  • manage:重新交给 Pacemaker 全权托管资源组
  • cleanup:再次清理残留故障计数
  • enable:启用资源,允许集群自动按顺序启动整套资源

[root@server1 /]# pcs resource manage mfsgroup
[root@server1 /]# pcs resource cleanup mfsgroup
[root@server1 /]# pcs resource enable mfsgroup

[root@server1 /]# pcs status

故障检测

Pacemaker 在 server1 上执行 VIP 资源监控检测,发现 IPaddr2 资源代理在 server1 上识别异常 / 配置不一致,判定监控失败,触发资源组整体迁移到另外一台节点 server5。

重启有报错启动不了

这里在前面提到过,我这也是修复的过程,按照前面的建议走,大概率不会遇到这个问题

直接把两个master的IQN设置成不一样的 防止抢占资源

[root@server1 ~]# iscsi-iname
iqn.1994-05.com.redhat:550531ea54
[root@server1 ~]# vi /etc/iscsi/initiatorname.iscsi

/iscsi> cd iqn.2026-08.com.example:mfsdata/tpg1/acls/
/iscsi/iqn.20...ata/tpg1/acls> ls
o- acls .................................................................................................................. [ACLs: 1]
  o- iqn.2026-08.com.example:client ............................................................................... [Mapped LUNs: 1]
    o- mapped_lun0 ....................................................................................... [lun0 block/my_disk (rw)]
/iscsi/iqn.20...ata/tpg1/acls> create iqn.1994-05.com.redhat:550531ea54
Created Node ACL for iqn.1994-05.com.redhat:550531ea54
Created mapped LUN 0.

停止所有iSCSI相关服务

systemctl stop iscsid.socket iscsid.service iscsi.service

退出已登录的远端存储会话(注销LUN连接)

iscsiadm -m node --logout

删除本机保存的target节点记录
iscsiadm -m node -o delete

删除iscsi本地缓存文件,彻底清理旧配置
 rm -rf /var/lib/iscsi/nodes/* /var/lib/iscsi/send_targets/*

重新启动服务
 systemctl start iscsid.socket iscsid.service iscsi.service
systemctl enable iscsid.socket iscsid.service iscsi.service

iscsiadm -m discovery -t sendtargets -p server4:3260

iscsiadm -m node --login

验证:

[root@server5 ~]# pcs node standby

故障正常切换

配置 fence

集群强行把故障节点断电 / 重启,保证同一时间只有一台机器操作共享存储,保护元数据文件安全

为了防止添加新的磁盘后磁盘名称的迁移导致磁盘报错,我们先将PCS集群的iscsi存储盘改为UUID的识别方式   上面我们操作  共享盘是名称为sda1   但是当你添加新盘后这个名称自己就变成了sdb1,为了避免连锁错误,直接改成 UUID    识别

[root@server1 ~]# blkid /dev/sda1
/dev/sda1: UUID="bf679923-a094-4e32-a19f-39a6bd82b62a" TYPE="xfs" PARTUUID="572b2587-01"

[root@server1 ~]# pcs resource update mfsdata device="/dev/disk/by-uuid/bf679923-a094-4e32-a19f-39a6bd82b62a"

[root@server1 ~]# pcs resource config

windows新建SDB盘

以管理员身份运行cmd

查看添加的新磁盘

虚拟机关机,添加刚才创建 的这块磁盘

保持现有格式

点击高级,选择  SCSI 1:0   独立---永久

在windows找到这个虚拟机对应的文件夹,里面有一个 vmx结尾的文件,选择在记事本中打开;在末尾添加下述内容

disk.locking = "FALSE"

disk.EnableUUID = "TRUE"

scsi1.sharedBus = "virtual"

scsi1:0.mode = "independent‑persistent"

注意有的文件有这个最后一行的,就不要重复写,否则会启动不了

此时就去修改server5的操作,添加磁盘并修改vmx  文件,避免后续一台机子启动产生磁盘锁,另一台在修改vmx文件会无法生效,表现为开机后lsblk能查看到这块磁盘,但是blkid始终无法看到这块磁盘的UUID

两台都操作完毕后

进入VM,点击电源----打开虚拟机时进入固件

左箭头  选中  Boot    shift和+   将NUMe  (B:0:0:1)  顺序上调,作为系统的引导盘,否则启动会直接进入单用户紧急模式

保存退出

[root@server1 ~]# lsblk

这里是我当时错误的操作顺序造成的报错

错误:两台虚拟机不能一台开着、另一台修改 vmx,会产生磁盘锁,导致第二台看不到共享盘

[root@server1 ~]# ll /dev/disk/by-id

确保两台虚拟机的这块盘的UUID一样

安装SDB工具

两台节点全部都要执行这套操作

dnf install -y sbd fence-agents-all


加载 softdog 软件看门狗内核模块

  • modprobe softdog:临时加载软件看门狗驱动
  • /etc/modules-load.d/softdog.conf:开机自动加载 softdog
  • ls /dev/watchdog:验证看门狗设备文件是否生成

modprobe softdog
echo "softdog" > /etc/modules-load.d/softdog.conf
 ls /dev/watchdog

 lsmod | grep softdog

这里能看到  /dev/watchdog  才代表操作成功

初始化 SBD(仅在其中一个节点执行 create)

SBD 在共享磁盘初始化

在这块共享盘写入 SBD 头部信息,划分槽位,作为集群仲裁隔离盘

[root@server1 ~]# sbd -d /dev/disk/by-id/scsi-36000c29fa13d4bb4e581e8a75783a2ad create

查看 SBD 磁盘头部信息(验证初始化成功)
[root@server1 ~]# sbd -d /dev/disk/by-id/scsi-36000c29fa13d4bb4e581e8a75783a2ad dump

创建 STONITH 隔离资源 sbd-fence

  • fence_sbd:SBD 专用隔离代理
  • devices:填写磁盘 WWID 软链接(推荐,设备名不会漂移),不要写 /dev/sdb 这种别名
  • op:定义监控、启停超时时间

[root@server1 ~]# pcs stonith create sbd-fence fence_sbd devices="/dev/disk/by-id/scsi-36000c29fa13d4bb4e581e8a75783a2ad" op monitor interval=30s timeout=20s op start timeout=20s op stop timeout=20s

查看 STONITH 隔离设备配置

[root@server1 ~]# pcs stonith config

[root@server1 ~]# pcs property set stonith-enabled=true

pcs cluster stop --all && pcs cluster start --all 作用:滚动重启整个集群,让 stonith-enabled=true 配置生效

[root@server1 ~]# pcs cluster stop --all
[root@server1 ~]# pcs cluster start --all
[root@server1 ~]# pcs status

✅ softdog 软件看门狗(双节点部署完成)
✅ SBD 共享磁盘初始化
✅ fence_sbd STONITH 隔离设备创建
✅ stonith-enabled=true 开启
✅ 业务资源组(VIP+Filesystem+mfsmaster)全部正常运行
✅ 双节点集群高可用部署完毕

今天的博客到这里就结束了,886~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值