# 从浅入深 学习 SpringCloud 微服务架构(七)Hystrix(2)

8 篇文章 0 订阅
4 篇文章 0 订阅

从浅入深 学习 SpringCloud 微服务架构(七)Hystrix(2)

一、Hystrix:基于 RestTemplate 的统一降级配置

1、Hystrix:基于 RestTemplate 的统一降级配置 步骤:

1)在项目的 pom.xml 配置文件中,引入 hystrix 依赖。


<!-- Hystrix 组件 对 RestTemplate 的支持4步:1)引入 Hystrix 依赖坐标 -->
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

2)在项目启动类中激活 hystrix


@SpringBootApplication
@EntityScan("djh.it.order.domain")
@EnableEurekaClient  //激活 EurekaClient,同 @EnableDiscoveryClient 注解相同。
//@EnableFeignClients  //激活 Feign
@EnableCircuitBreaker  // Hystrix 组件 对 RestTemplate 的支持4步:2)激活 hystrix
public class OrderApplication { ... }

3)在项目的 Controller 类中,配置熔断触发的降级逻辑。


/**
 *  Hystrix:基于 RestTemplate 的统一降级配置:指定统一降级的方法,无参数。
 *  注意:使用统一降级配置,需要返回类型保持一致。
 * @return
 */
public Product defaultFallBack(){
	Product product = new Product();
	product.setProductName("触发 统一 降级方法 defaultFallBack");
	return product;
}

4)在项目的 Controller 类中,在需要受到保护的接口上使用 @HystrixCommand 注解配置。


//@HystrixCommand(fallbackMethod = "orderFallBack")
@HystrixCommand  //配置了公共的熔断设置后,就不需要传参数。
@RequestMapping(value = "/buy/{id}", method = RequestMethod.GET)
public Product findById(@PathVariable Long id){
	Product product = null;
	//product = restTemplate.getForObject("http://127.0.0.1:9001/product/1", Product.class);
	product = restTemplate.getForObject("http://service-product/product/1", Product.class);
	return product;
}

2、在服务消费者 order_service 子工程(子模块)中,修改 controller 类 OrderController.java,添加 Hystrix:基于 RestTemplate 的统一降级配置。

浏览器中安装一个插件,【Json 格式化工具】,将看上去杂乱无章的 Json 串转换为容易阅读的格式。

# Http 请求的 json 数据,显示的内容比较乱,难看懂,如何让它格式化显示?

/**
 *   spring_cloud_consul_demo\order_service\src\main\java\djh\it\order\controller\OrderController.java
 *
 *  2024-4-27 订单的 controller 类 OrderController.java
 *  2024-4-28 修改,添加 Hystrix:基于 RestTemplate 的统一降级配置。
 */
package djh.it.order.controller;

import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import djh.it.order.domain.Product;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
@RequestMapping("/order")
@DefaultProperties(defaultFallback = "defaultFallBack")  //Hystrix:基于 RestTemplate 的统一降级配置,指定此接口中公共的熔断设置。
public class OrderController {

    @Autowired  // 注入 restTemplate 对象
    private RestTemplate restTemplate;

    /**
     *  Hystrix 组件 对 RestTemplate 的支持4步:4)使用注解配置熔断保护
     *      fallbackmethod : 配置熔断之后的降级方法
     * @param id
     * @return
     */
//    @HystrixCommand(fallbackMethod = "orderFallBack")
    @HystrixCommand  //配置了公共的熔断设置后,就不需要传参数。
    @RequestMapping(value = "/buy/{id}", method = RequestMethod.GET)
    public Product findById(@PathVariable Long id){
        Product product = null;
        //product = restTemplate.getForObject("http://127.0.0.1:9001/product/1", Product.class);
        product = restTemplate.getForObject("http://service-product/product/1", Product.class);
        return product;
    }

    /**
     *  Hystrix 组件 对 RestTemplate 的支持4步:3)降级方法
     * @param id
     * @return
     */
    public Product orderFallBack(Long id){
        Product product = new Product();
        product.setProductName("触发降级方法");
        return product;
    }

    /**
     *  Hystrix:基于 RestTemplate 的统一降级配置:指定统一降级的方法,无参数。
     *  注意:使用统一降级配置,需要返回类型保持一致。
     * @return
     */
    public Product defaultFallBack(){
        Product product = new Product();
        product.setProductName("触发 统一 降级方法 defaultFallBack");
        return product;
    }

}

3、重新运行 order_service, product_service, eureka_service 模块中,三个启动类,进行测试

在这里插入图片描述

1)浏览器地址栏输入:http://127.0.0.1:9000

发现 两个 服务,端口号分别是 9001.9002。

在这里插入图片描述

2)浏览器地址栏输入:http://127.0.0.1:9001/product/1

输出 mysql 数据库的第一条记录:

在这里插入图片描述

3)浏览器地址栏输入:http://localhost:9002/order/buy/1
输出如下:

在这里插入图片描述
4)模拟服务器宕机:如果访问的 service-product 服务器宕机,service-order 模块中,就会触发此降级方法。
把 服务提供者 product_service 模块中,启动类停止,再次访问测试,发现触发了降级方法。

浏览器地址栏输入:http://127.0.0.1:9002/order/buy/1

在这里插入图片描述

在这里插入图片描述

二、hystrix:基于 feign 调用的熔断配置。

1、在服务消费者 order_service 子工程(子模块)中,修改 启动类 添加 注解 @EnableFeignClients //激活 Feign 组件。


/**
 *    spring_cloud_demo\order_service\src\main\java\djh\it\order\OrderApplication.java
 *
 *   2024-4-27  启动类 OrderApplication.java
 */
package djh.it.order;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EntityScan("djh.it.order.domain")
@EnableEurekaClient  //激活 EurekaClient,同 @EnableDiscoveryClient 注解相同。
@EnableFeignClients  //激活 Feign
//@EnableCircuitBreaker  // 2)激活 hystrix,  Hystrix 组件 对 RestTemplate 的支持4步:
public class OrderApplication {

    //@EnableFeignClients  //激活 Feign 组件后,不需要以下配置。
//    @LoadBalanced
//    @Bean
//    public RestTemplate restTemplate(){
//        return new RestTemplate();
//    }

    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }
}


2、在服务消费者 order_service 子工程(子模块)中,创建 调用 feign 组件的接口类 ProductFeignClient.java。


/**
 *   spring_cloud_demo\order_service\src\main\java\djh\it\order\feign\ProductFeignClient.java
 *
 *   2024-4-27  创建 调用 feign 组件的接口类 ProductFeignClient.java
 *   声明需要调用的微服务名称 @FeignClient, name: 服务提供者的名称
 */

package djh.it.order.feign;

import djh.it.order.domain.Product;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@FeignClient(name="service-product")
public interface ProductFeignClient {
    //配置需要调用的微服务接口
    @RequestMapping(value = "/product/{id}", method = RequestMethod.GET)
    public Product findById(@PathVariable("id") Long id);
}



3、在服务消费者 order_service 子工程(子模块)中,修改 Controller 类 OrderController.java , 添加 注入 feign 组件的接口类 ProductFeignClient 并调用其方法。


/**
 *   spring_cloud_consul_demo\order_service\src\main\java\djh\it\order\controller\OrderController.java
 *
 *  2024-4-27 订单的 controller 类 OrderController.java
 *  2024-4-27 第一次修改,添加 Hystrix:基于 RestTemplate 的统一降级配置。
 *  2024-4-27 第二次修改,添加 hystrix:基于 feign 调用的熔断配置
 */
package djh.it.order.controller;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import djh.it.order.domain.Product;
import djh.it.order.feign.ProductFeignClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/order")
//@DefaultProperties(defaultFallback = "defaultFallBack")  //Hystrix:基于 RestTemplate 的统一降级配置,指定此接口中公共的熔断设置。
public class OrderController {

    @Resource    //按类型名称注入 调用 feign 组件的接口类 ProductFeignClient
    //@Autowired   //自动注入 调用 feign 组件的接口类 ProductFeignClient //有时变量名报红,可替换为 @Resource 注解
    private ProductFeignClient productFeignClient;

//    @Autowired  // 注入 restTemplate 对象
//    private RestTemplate restTemplate;

    /**
     *  Hystrix 组件 对 RestTemplate 的支持4步:4)使用注解配置熔断保护
     *      fallbackmethod : 配置熔断之后的降级方法
     * @param id
     * @return
     */
//    @HystrixCommand(fallbackMethod = "orderFallBack")
    @HystrixCommand  //配置了公共的熔断设置后,就不需要传参数。
    @RequestMapping(value = "/buy/{id}", method = RequestMethod.GET)
    public Product findById(@PathVariable Long id){
        Product product = null;
        //product = restTemplate.getForObject("http://127.0.0.1:9001/product/1", Product.class);
        //product = restTemplate.getForObject("http://service-product/product/1", Product.class);

       //调用 feign 组件的接口类 的方法
        product = productFeignClient.findById(id);

        return product;
    }

    /**
     *  Hystrix 组件 对 RestTemplate 的支持4步:3)降级方法
     * @param id
     * @return
     */
//    public Product orderFallBack(Long id){
//        Product product = new Product();
//        product.setProductName("触发降级方法");
//        return product;
//    }

    /**
     *  Hystrix:基于 RestTemplate 的统一降级配置:指定统一降级的方法,无参数。
     *  注意:使用统一降级配置,需要返回类型保持一致。
     * @return
     */
//    public Product defaultFallBack(){
//        Product product = new Product();
//        product.setProductName("触发 统一 降级方法 defaultFallBack");
//        return product;
//    }

}

4、Hystrix:基于 feign 调用的熔断配置 步骤:

1)在项目的 pom.xml 配置文件中,引入 hystrix 依赖。


<!-- Hystrix 组件 对 feign 调用 的支持4步:1)引入 Hystrix 依赖坐标 -->
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

2)在项目 的 application.yml 配置文件中,feign 配置中配置开启 Hystrix 。


feign:
  client:
    config:
      service-product:
        loggerLevel: FULL
  hystrix:  # 开启对 hystrix 的支持。
    enabled: true

3)在项目中自定义一个 feign 接口的实现类,配置熔断触发的降级逻辑。


/**
 *   spring_cloud_sonsul_demo\order_service\src\main\java\djh\it\order\feign\ProductFeignClientCallBack.java
 *
 *   2024-4-27  创建 feign 组件的接口类 ProductFeignClient 的实现类 ProductFeignClientCallBack.java
 *   配置熔断触发的降级逻辑。
 */

package djh.it.order.feign;

import djh.it.order.domain.Product;
import org.springframework.stereotype.Component;

@Component
public class ProductFeignClientCallBack implements ProductFeignClient{

    @Override  // 熔断降级的方法
    public Product findById(Long id) {
        Product product = new Product();
        product.setProductName("hystrix:基于 feign 调用的熔断配置 -- feign 调用触发熔断降级的方法。");
        return product;
    }
}



4)在项目中修改 feignClient 接口,添加降级方法的支持。


@FeignClient(name="service-product", fallback = ProductFeignClientCallBack.class)
public interface ProductFeignClient {
    //配置需要调用的微服务接口
    @RequestMapping(value = "/product/{id}", method = RequestMethod.GET)
    public Product findById(@PathVariable("id") Long id);
}

5、在服务消费者 order_service 子工程(子模块)pom.xml 配置文件中,引入 hystrix 依赖。此步骤可省略,因为 feign 中 集成了 hystrix 组件。


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring_cloud_consul_demo</artifactId>
        <groupId>djh.it</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>order_service</artifactId>

    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <!--            <version>5.1.32</version>-->
            <version>8.0.26</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!-- 导入 eureka 注册中心 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!-- springcloud 提供的对基于 consul 的服务发现 -->
<!--        <dependency>-->
<!--            <groupId>org.springframework.cloud</groupId>-->
<!--            <artifactId>spring-cloud-starter-consul-discovery</artifactId>-->
<!--        </dependency>-->
<!--        &lt;!&ndash; actuator 健康检查 &ndash;&gt;-->
<!--        <dependency>-->
<!--            <groupId>org.springframework.boot</groupId>-->
<!--            <artifactId>spring-boot-starter-actuator</artifactId>-->
<!--        </dependency>-->
        <!-- springcloud 整合 openFeign -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!-- Hystrix 组件 对 RestTemplate 的支持4步:1)引入 Hystrix 依赖坐标 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
    </dependencies>
</project>
<!--  spring_cloud_consul_demo\order_service\pom.xml -->

6、在服务消费者 order_service 子工程(子模块)application.yml 配置文件中,引入 【feign 中配置开启 Hystrix 】。

##  spring_cloud_consul_demo\order_service\src\main\resources\application.yml

server:
  port: 9002  # 启动端口 命令行注入。
#  port: ${port:9002}  # 启动端口设置为动态传参,如果未传参数,默认端口为 9002
#  tomcat:
#    max-threads: 10  # 设置 tomcat 最大连接数量,用以模拟高并发环境问题。

spring:
  application:
    name: service-order  #spring应用名, # 注意 FeignClient 不支持名字带下划线
#  main:
#    allow-bean-definition-overriding: true # SpringBoot2.1 需要设定。
  datasource:
    driver-class-name: com.mysql.jdbc.Driver  # mysql 驱动
#    url: jdbc:mysql://localhost:3306/shop?useUnicode=true&characterEncoding=utf8
    url: jdbc:mysql://localhost:3306/shop?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
    # MySQL8.0 可以写成  root, 012311 或  'root', '012311'   # MySQL5.7 只能写成 'root', '012311'  # 注意用户名和密码后一定不能有空格。
    username: 'root'
    password: '12311'
  jpa:
    database: MySQL
    show-sql: true
    open-in-view: true

eureka:  # 配置 Eureka
  client:
    service-url:
      defaultZone: http://localhost:9000/eureka/  # 多个 eurekaserver 用 , 隔开。
  instance:
    prefer-ip-address: true  # 使用 ip 地址注册
    instance-id: ${spring.cloud.client.ip-address}:${server.port}

# 配置 feign 日志的输出。
# 日志配置:NONE:GI 不输出日志,BASIC:适用于生产环境追踪问题,HEADERS:在BASIC基础上,记录请求和响应头信息,FULL:记录所有。
feign:
  client:
    config:
      default:
        connectTimeout: 5000   #服务之间建立连接所用的时间  #不设置 connectTimeout 会导致 readTimeout 设置不生效
        readTimeout: 5000   #建立连接后从服务端读取到数据用的时间
      service-product:  # 需要调用的服务名称
        loggerLevel: FULL
  hystrix:  # 开启对 hystrix 的支持。
    enabled: true

logging:
  level:
    djh.it.order.feign.ProductFeignClient: debug

#management:   # 配置 Actuator 获取 hystrix 的监控数据 暴躁端点。
#  endpoints:
#    web:
#      exposure:
#        include: '*'   # 暴露所有端点。

hystrix:  # 配置 hystrix 熔断(Hystrix:基于 RestTemplate 的统一降级配置)
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 5000  # 默认的熔断超时时间为1秒,若1秒没有返回数据,会自动触发降级逻辑。

#  # 配置 consul 的服务注册
#  cloud:
#    consul:
#      host: 127.0.0.1  # consul 服务器的主机地址
#      port: 8500  # consul 端口
#      discovery:
#        register: false  # 是否需要注册,默认是 false
#        instance-id: ${spring.application.name}-1  # 注册的实例 ID(唯一标志)
#        service-name: ${spring.application.name}  # 服务的名称
#        port: ${server.port}  # 服务的请求端口
#        prefer-ip-address: true  # 指定开启 IP 地址注册
#        ip-address: ${spring.cloud.client.ip-address}  # 当前服务的请求 IP


7、在服务消费者 order_service 子工程(子模块),创建 feign 组件的接口类 ProductFeignClient 的实现类 ProductFeignClientCallBack.java 配置熔断触发的降级逻辑。

/**
 *   spring_cloud_sonsul_demo\order_service\src\main\java\djh\it\order\feign\ProductFeignClientCallBack.java
 *
 *   2024-4-27  创建 feign 组件的接口类 ProductFeignClient 的实现类 ProductFeignClientCallBack.java
 *   配置熔断触发的降级逻辑。
 */

package djh.it.order.feign;

import djh.it.order.domain.Product;
import org.springframework.stereotype.Component;

@Component
public class ProductFeignClientCallBack implements ProductFeignClient{

    @Override  // 熔断降级的方法
    public Product findById(Long id) {
        Product product = new Product();
        product.setProductName("hystrix:基于 feign 调用的熔断配置 -- feign 调用触发熔断降级的方法。");
        return product;
    }
}

8、在服务消费者 order_service 子工程(子模块)feign 组件的接口类 ProductFeignClient.java 中,添加降级方法的支持,配置熔断触发的降级逻辑。

/**
 *   spring_cloud_demo\order_service\src\main\java\djh\it\order\feign\ProductFeignClient.java
 *
 *   2024-4-27  创建 调用 feign 组件的接口类 ProductFeignClient.java
 *   声明需要调用的微服务名称 @FeignClient, name: 服务提供者的名称, fallback:配置熔断发生的降级方法。
 */

package djh.it.order.feign;

import djh.it.order.domain.Product;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@FeignClient(name="service-product", fallback = ProductFeignClientCallBack.class)  //添加降级方法的支持
public interface ProductFeignClient {
    //配置需要调用的微服务接口
    @RequestMapping(value = "/product/{id}", method = RequestMethod.GET)
    public Product findById(@PathVariable("id") Long id);
}


9、重新运行 eureka_service, product_service, order_service, 三个启动类,进行测试

在这里插入图片描述

1)浏览器地址栏输入:http://127.0.0.1:9000

发现 两个 服务,端口号分别是 9001.9002。

在这里插入图片描述

2)浏览器地址栏输入:http://127.0.0.1:9001/product/1

正常输出 mysql 数据库的第一条记录:

在这里插入图片描述

3)浏览器地址栏输入:http://localhost:9002/order/buy/1

正常输出 mysql 数据库的第一条记录:

在这里插入图片描述

4)重新运行 eureka_service, order_service, 不启动 product_service 模块(停掉),进行测试

浏览器地址栏输入:http://localhost:9002/order/buy/1

会触发熔断器,输出熔断提示如下:
1.png

在这里插入图片描述

上一节链接请点击:
# 从浅入深 学习 SpringCloud 微服务架构(七)Hystrix(1)

  • 40
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Spring Cloud 微服务架构实战代码是一个基于 Spring Cloud 微服务解决方案的实践项目。它通过将常见的微服务技术组件和应用场景进行集成和示例演示,使读者能够入了解和学习 Spring Cloud 微服务架构的实际应用。 该项目包含多个模块,其中包括注册中心(Eureka)、配置中心(Config)、网关(Zuul)、负载均衡(Ribbon)、链路跟踪(Sleuth)、熔断器(Hystrix)等,涵盖了微服务架构中的关键技术组件。在实现过程中,项目采用了 Spring Boot 来简化微服务架构的搭建和开发,并以 Maven 进行依赖管理和构建。 通过该项目的学习,读者可以了解到微服务架构的基本概念、实际应用场景和解决方案,掌握 Spring Cloud 微服务架构的相关技术和工具的实际应用,了解微服务架构的开发和部署流程,掌握基于 Spring Boot 的微服务开发和集成方法,从而提高微服务架构的设计实现和部署能力。 总之,Spring Cloud 微服务架构实战代码是一份完整的微服务架构实践项目,它可以帮助读者学习和了解微服务架构的实际应用,并具备较高的实际参考价值。 ### 回答2: Spring Cloud是一个开源的微服务架构实战代码,能够让开发人员在构建分布式系统时快速开发和部署微服务。它诞生于Spring项目之上,提供了基于Spring Boot的一套开发工具和服务,可以方便地管理和实现微服务架构的各项需求。 Spring Cloud包含了许多组件,如Eureka、FeignHystrix、Zuul等,这些组件都可以独立使用,也可以混合使用,相互之间的集成非常容易。例如,Eureka提供了服务注册与发现的能力,Feign支持微服务之间的远程调用,Hystrix可以提供服务的自我保护机制,Zuul可以提供API网关的功能,等等。 通过使用Spring Cloud,开发人员可以有效地解决微服务中需要处理的分布式问题,例如服务发现、服务注册、服务负载均衡、熔断、容错、路由、安全等等。此外,Spring Cloud还提供了一些常用的开发工具,如Spring Cloud Config,它可以帮助团队在开发和发布过程中有效地管理和配置系统的环境和配置文件。 总之,Spring Cloud是一套非常完善,且易于集成、扩展的微服务架构实战代码,尤其适用于企业级和大型系统的开发。它能够快速地实现微服务的各项技术需求,提高开发效率,使得开发人员更加专注于业务逻辑的开发,而不用再花费大量时间和精力处理微服务本身的问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

段子手-168

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

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

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

打赏作者

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

抵扣说明:

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

余额充值