Nacos的学习总结


前言

此为Nacos的学习总结,记录了Nacos的环境搭建和基本用法。


一、何为Nacos?

Nacos 作为阿里巴巴的产品,也是SpringCloud中的一个组件。能够实现注册中心以及配置管理等功能。

本文大致分为三部分:

  1. Nacos实现注册中心
  2. Nacos实现配置管理
  3. Nacos的集群搭建

二、Nacos的基础环境搭建

1. Nacos的安装

a) 在Nacos官网下载安装包并解压到本地目录:Nacos官网 。这里使用的是Windows环境下的nacos-server-1.4.1

注意安装目录不能包含中文!
在这里插入图片描述
b) 端口配置。Nacos的默认端口为8848,如果被占用,需进行手动修改。

/nacos/conf/application.properties
在这里插入图片描述

c) 单机启动Nacos(后面会配置Nacos集群,实现整个集群的启动)

/nacos/bin目录下打开命令行窗口:使用startup.cmd -m standalone实现单机启动。

在这里插入图片描述

在浏览器中访问地址:初始登录用户和密码都为:nacos。登录成功后,即可看到该页面。(确实比Eureka的Beautiful 亿点点)

在这里插入图片描述

2. 在父工程的pom文件中引入nacos 的管理依赖:

	<dependencyManagement>
		 <dependencies>
			 <dependency>
			     <groupId>com.alibaba.cloud</groupId>
			     <artifactId>spring-cloud-alibaba-dependencies</artifactId>
			     <version>2.2.5.RELEASE</version>
			     <type>pom</type>
			     <scope>import</scope>
			 </dependency>
		</dependencies>
	</dependencyManagement>
			

3. 在服务的pom文件中添加nacos客户端依赖

		<!--  nacos 客户端依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

4. 添加Nacos的相关配置信息

application.yml

spring:
  application:
    name: orderservice # 配置注册服务的名称
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos服务端的地址

配置后,启动项目,即可在Nacos的服务端查看到已注册的服务信息:

在这里插入图片描述


三、Nacos的相关知识

1. 服务多级存储模型

一个服务有多个实例,在服务与实例之间,中间还有一个集群的概念。

在这里插入图片描述

服务初始化属于默认集群

在这里插入图片描述

2. 配置服务集群属性

spring:
  application:
    name: orderservice # 配置注册服务的名称
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos服务端的地址
      discovery:
        cluster-name: HZ # 配置集群名称(HZ  --- 杭州)

重新启动项目即可看到集群变化
在这里插入图片描述

总的来说,Nacos服务分级存储模型分为三级:服务、集群以及实例。

3. Nacos中的负载均衡 — NacosRule

userservice: # 指定要调用的哪个服务,为指定的服务配置负载均衡规则
  ribbon:
    #  Nacos 的负载均衡策略
    # (优先选择本地集群的服务实例,对于本地的实例,采用随机的负载均衡策略)
    NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule

NacosRule负载均衡策略:

  1. 优先选择同集群服务实例列表。
  2. 确定可用集群列表后,再采用随机负载均衡策略挑选实例。

此外: 还可以为具体实例设置权重,实现根据权重实现负载均衡:
a) 在Nacos控制台设置权重值:
在这里插入图片描述

b) 权重值的范围为:0~1,权重越高,被访问的概率越大,权重为零则实例不会被访问。因此,在服务功能升级时,可先将某一些实例的权重设置为0,然后再进行下线修改,修改完成后,重新上限,设置较小的权重值,接收少量的请求进行测试,若无误则依次升级其他服务实例,实现服务整体平滑的升级。(Nice)

4. Nacos — 环境隔离

Nacos中的服务存储以及数据存储最外层都可设置namespace,实现外层隔离。(Group 通常使用默认的即可)

每个namespace 都有唯一的id,不同的namespace 下的服务不可见。

在这里插入图片描述
a) 在Nacos控制台手动添加命名空间:
在这里插入图片描述

在这里插入图片描述

添加命名空间后,即可在服务列表中查看:

在这里插入图片描述

b) 修改服务的配置文件:
application.yml文件中添加 namespace 属性,值为其自动生成的uuid。

在这里插入图片描述

spring:
  application:
    name: orderservice
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos服务地址
      discovery:
        # 配置集群名称(HZ  --- 杭州)
        cluster-name: HZ
        # dev 环境。配置命名空间(实现环境隔离)
        namespace: f669352d-03c5-40b3-a21b-04a297b74344
        

重新启动项目,即可在不同的namespace 中查看其下注册的实例信息。

5. Nacos 与 Eureka 的对比

相同点:

  1. 服务消费者都会定时向注册中心拉取服务做更新操作
  2. 服务提供者都会向注册中心注册服务信息。都存在心跳机制监测实例的健康状态。

不同点:

  1. Nacos的消费者与注册中心采用 定时拉取主动推送相结合。当注册中心中的实例信息发生变化时,会主动向消费者推送变更信息,解决定时拉取不及时存在的问题。
  2. 在Nacos中,将服务提供者分为临时实例非临时实例。临时实例的监测机制与Eureka相同,采用心跳监测,在实例故障时,Nacos控制台会直接删除其相关信息;非临时实例监测机制为注册中心主动向实例发起询问,询问其的健康状态,且在实例故障时,不会直接删除相关信息,而是等待其恢复正常。
    在这里插入图片描述

注册的实例默认为临时实例。(非临时实例会加大Nacos的负担)
也可通过修改application.yml配置文件中的信息,修改注册实例的方式。

spring:
  application:
    name: orderservice
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos服务地址
      discovery:
        # 配置集群名称(HZ  --- 杭州)
        cluster-name: HZ
        # dev 环境。配置命名空间(实现环境隔离)
        namespace: f669352d-03c5-40b3-a21b-04a297b74344
        # 设置该服务实例为非临时实例(临时实例与非临时实例的监测机制不同)
        ephemeral: false 
        

修改后,重新启动项目,在Nacos控制台即可查看临时实例:true

在这里插入图片描述

四、Nacos实现统一配置管理

Nacos在完成注册中心的基础上,提供了服务配置管理的功能,能够让服务的配置实现热更新,非常丝滑。

在这里插入图片描述

1. 在Nacos客户端填写配置信息

!:注意此处的Data ID的格式为:服务名称 + 开发环境 + 文件名后缀。与在IDEA中的配置相对应。
在这里插入图片描述

2. 添加管理客户端依赖

        <!--        nacos 的配置管理依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>

创建bootstrap.yml配置文件,此文件为引导文件,读取优先级高于application.yml。在文件中配置nacos地址、当前环境、服务名称、文件后缀名,以此决定当程序启动时去nacos读取哪个文件。

在这里插入图片描述

在bootstrap.yml 添加此内容。注意此处的 name + active + file-extension = 前面的Data ID

spring:
  application:
    name: userservice
  profiles:
    active: dev # 开发环境
  cloud:
    nacos:
      server-addr: localhost:80
      config:
        file-extension: yaml #文件后缀名

3. 读取配置(方式一)

完成以上工作后,即可读取该配置文件中的内容。

 	@Value("${pattern.dateformat}")
    private String dateformat;

    @GetMapping("/now")
    public String now(){
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dateformat));
    }

在浏览器中访问,即可查看当前格式化以后的时间:

在这里插入图片描述

4. 读取配置(方式二)【常用】

读取配置,存在另外一种方法:

// 添加专门读取配置的类
@Data
@Component
@ConfigurationProperties(prefix = "pattern")
public class PatternProperties {
    private String dateformat;

    private String envSharedValue;
}

	// Controller
    @Autowired
    private PatternProperties properties;

    @GetMapping("/prop")
    public PatternProperties properties(){
        return properties;
    }

5. 配置自动刷新

Nacos中的配置文件变更后,微服务无需重启就可以感知进行修改,可采取两种方式开启配置自动刷新:

方式一: 在@Value 注入的变量所在的类上添加 @RefreshScope 注解

@RefreshScope
public class UserController {

    @Value("${pattern.dateformat}")
    private String dateformat

方式二: 使用@ConfigurationProperties 注解。这也是读取配置时使用方式二的原因之一。

@ConfigurationProperties(prefix = "pattern")
public class PatternProperties {
    private String dateformat;
}

6. 多环境配置共享

微服务启动时会从nacos读取多个配置文件:
userservice-dev.yaml -->> userservice.yaml

无论profile环境如何变化,[spring.application.name].yaml 文件一定会被加载,因此可以借助该文件实现多环境共享配置。

在这里插入图片描述
此时,我们微服务启动就会读取三个配置文件,那么它们的优先级如何呢?

在这里插入图片描述

注意: 不是所有的配置都适合放到配置中心,维护起来较为麻烦。建议将一些关键参数、需要进行调整的参数放到nacos的配置中心。


五、Nacos集群管理

	## 搭建步骤:
		1. 搭建MySQL集群并初始化数据库表。
		2. 搭建nacos集群
		3. 启动多个nacos节点
		4. nginx实现反向代理

1. 搭建MySQL集群并初始化数据库表

这里仅仅使用单一数据库,创建nacos 数据库,初始化数据库表:

CREATE TABLE `config_info` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `data_id` varchar(255) NOT NULL COMMENT 'data_id',
  `group_id` varchar(255) DEFAULT NULL,
  `content` longtext NOT NULL COMMENT 'content',
  `md5` varchar(32) DEFAULT NULL COMMENT 'md5',
  `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
  `src_user` text COMMENT 'source user',
  `src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip',
  `app_name` varchar(128) DEFAULT NULL,
  `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
  `c_desc` varchar(256) DEFAULT NULL,
  `c_use` varchar(64) DEFAULT NULL,
  `effect` varchar(64) DEFAULT NULL,
  `type` varchar(64) DEFAULT NULL,
  `c_schema` text,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_configinfo_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info';

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = config_info_aggr   */
/******************************************/
CREATE TABLE `config_info_aggr` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `data_id` varchar(255) NOT NULL COMMENT 'data_id',
  `group_id` varchar(255) NOT NULL COMMENT 'group_id',
  `datum_id` varchar(255) NOT NULL COMMENT 'datum_id',
  `content` longtext NOT NULL COMMENT '内容',
  `gmt_modified` datetime NOT NULL COMMENT '修改时间',
  `app_name` varchar(128) DEFAULT NULL,
  `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_configinfoaggr_datagrouptenantdatum` (`data_id`,`group_id`,`tenant_id`,`datum_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='增加租户字段';


/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = config_info_beta   */
/******************************************/
CREATE TABLE `config_info_beta` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `data_id` varchar(255) NOT NULL COMMENT 'data_id',
  `group_id` varchar(128) NOT NULL COMMENT 'group_id',
  `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
  `content` longtext NOT NULL COMMENT 'content',
  `beta_ips` varchar(1024) DEFAULT NULL COMMENT 'betaIps',
  `md5` varchar(32) DEFAULT NULL COMMENT 'md5',
  `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
  `src_user` text COMMENT 'source user',
  `src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip',
  `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_configinfobeta_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_beta';

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = config_info_tag   */
/******************************************/
CREATE TABLE `config_info_tag` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `data_id` varchar(255) NOT NULL COMMENT 'data_id',
  `group_id` varchar(128) NOT NULL COMMENT 'group_id',
  `tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id',
  `tag_id` varchar(128) NOT NULL COMMENT 'tag_id',
  `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
  `content` longtext NOT NULL COMMENT 'content',
  `md5` varchar(32) DEFAULT NULL COMMENT 'md5',
  `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
  `src_user` text COMMENT 'source user',
  `src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_configinfotag_datagrouptenanttag` (`data_id`,`group_id`,`tenant_id`,`tag_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_tag';

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = config_tags_relation   */
/******************************************/
CREATE TABLE `config_tags_relation` (
  `id` bigint(20) NOT NULL COMMENT 'id',
  `tag_name` varchar(128) NOT NULL COMMENT 'tag_name',
  `tag_type` varchar(64) DEFAULT NULL COMMENT 'tag_type',
  `data_id` varchar(255) NOT NULL COMMENT 'data_id',
  `group_id` varchar(128) NOT NULL COMMENT 'group_id',
  `tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id',
  `nid` bigint(20) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`nid`),
  UNIQUE KEY `uk_configtagrelation_configidtag` (`id`,`tag_name`,`tag_type`),
  KEY `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_tag_relation';

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = group_capacity   */
/******************************************/
CREATE TABLE `group_capacity` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `group_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Group ID,空字符表示整个集群',
  `quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值',
  `usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',
  `max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
  `max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数,,0表示使用默认值',
  `max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',
  `max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量',
  `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_group_id` (`group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='集群、各Group容量信息表';

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = his_config_info   */
/******************************************/
CREATE TABLE `his_config_info` (
  `id` bigint(64) unsigned NOT NULL,
  `nid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `data_id` varchar(255) NOT NULL,
  `group_id` varchar(128) NOT NULL,
  `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
  `content` longtext NOT NULL,
  `md5` varchar(32) DEFAULT NULL,
  `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `src_user` text,
  `src_ip` varchar(50) DEFAULT NULL,
  `op_type` char(10) DEFAULT NULL,
  `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
  PRIMARY KEY (`nid`),
  KEY `idx_gmt_create` (`gmt_create`),
  KEY `idx_gmt_modified` (`gmt_modified`),
  KEY `idx_did` (`data_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='多租户改造';


/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = tenant_capacity   */
/******************************************/
CREATE TABLE `tenant_capacity` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `tenant_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Tenant ID',
  `quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值',
  `usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',
  `max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
  `max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数',
  `max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',
  `max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量',
  `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='租户容量信息表';


CREATE TABLE `tenant_info` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `kp` varchar(128) NOT NULL COMMENT 'kp',
  `tenant_id` varchar(128) default '' COMMENT 'tenant_id',
  `tenant_name` varchar(128) default '' COMMENT 'tenant_name',
  `tenant_desc` varchar(256) DEFAULT NULL COMMENT 'tenant_desc',
  `create_source` varchar(32) DEFAULT NULL COMMENT 'create_source',
  `gmt_create` bigint(20) NOT NULL COMMENT '创建时间',
  `gmt_modified` bigint(20) NOT NULL COMMENT '修改时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_tenant_info_kptenantid` (`kp`,`tenant_id`),
  KEY `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='tenant_info';

CREATE TABLE `users` (
	`username` varchar(50) NOT NULL PRIMARY KEY,
	`password` varchar(500) NOT NULL,
	`enabled` boolean NOT NULL
);

CREATE TABLE `roles` (
	`username` varchar(50) NOT NULL,
	`role` varchar(50) NOT NULL,
	UNIQUE INDEX `idx_user_role` (`username` ASC, `role` ASC) USING BTREE
);

CREATE TABLE `permissions` (
    `role` varchar(50) NOT NULL,
    `resource` varchar(255) NOT NULL,
    `action` varchar(8) NOT NULL,
    UNIQUE INDEX `uk_role_permission` (`role`,`resource`,`action`) USING BTREE
);

INSERT INTO users (username, password, enabled) VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE);

INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN');

创建成功!

在这里插入图片描述

2. 搭建nacos集群

a) 将nacos解压到无中文无特殊符号 [如’(’ 和 ‘)’] 、无数字的目录下。亲测,如果不按要求,则会无法正常启动集群。(要求真多)
在这里插入图片描述

b) 进入nacos的conf目录,修改配置文件cluster.conf.example,重命名为cluster.conf

在这里插入图片描述
打开cluster.conf文件,添加内容:
在这里插入图片描述
同时修改该目录下的 application.properties文件:

在这里插入图片描述

c) 直接复制另外两台nacos,修改application.properties文件的端口好,分别为8846、8847

在这里插入图片描述

3、启动nacos集群:

在各自bin目录下,打开命令行窗口,执行 startup.cmd,即可以集群的方式启动nacos。

4、nginx实现反向代理

a) 在nginx 的 conf 目录下,打开 nginx.conf文件,添加相关配置:
在这里插入图片描述

在这里插入图片描述

b) 启动nginx
在nginx目录下,打开命令行窗口,执行start nginx.exe即可启动nginx服务。

在这里插入图片描述
启动成功后,即可通过浏览器访问localhost/nacos访问到nacos的控制台了。

最后,需将项目中访问nacos服务的地址改为:localhost:80

在这里插入图片描述


六、问题记录

1. 在nacos集群启动时, 出现 “ 此时不应有\nacos“\logs\java_heapdump.hprof” 问题
**解决方法:**nacos集群的安装路径改为无中文、无特殊字符、无数字即可。(括号也算作特殊字符)
在这里插入图片描述


七、总结

希望自己通过总结后,记忆能够更深刻一些,在以后记忆模糊时,也能回来稍微浏览一下。


以上就为本篇文章的全部内容啦!

如果本篇内容对您有帮助的话,请多多点赞支持一下呗!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值