java服务调用+java注册中心(Eureka)

15 篇文章 0 订阅
2 篇文章 0 订阅

java服务调用+java注册中心(Eureka)

管理方式

在这里插入图片描述

添加包
方便管理

替换 properties
然后添加下面代码

<!-- 统一管理jar包版本 -->
    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <junit.version>4.12</junit.version>
        <log4j.version>1.2.17</log4j.version>
        <lombok.version>1.16.18</lombok.version>
        <mysql.version>5.1.47</mysql.version>
        <druid.version>1.1.16</druid.version>
        <mybatis.spring.boot.version>3.4.0</mybatis.spring.boot.version>
    </properties>

    <!-- 1、只是声明依赖,并不实际引入,子项目按需声明使用的依赖 -->
    <!-- 2、子项目可以继承父项目的 version 和 scope -->
    <!-- 3、子项目若指定了 version 和 scope,以子项目为准 -->
    <dependencyManagement>
        <dependencies>
            <!--spring boot 2.2.2-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.2.2.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--spring cloud Hoxton.SR1-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--spring cloud alibaba 2.1.0.RELEASE-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.1.0.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>${druid.version}</version>
            </dependency>
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>${mybatis.spring.boot.version}</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
            </dependency>
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>${log4j.version}</version>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
                <version>2.2.2.RELEASE</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork>
                    <addResources>true</addResources>
                </configuration>
            </plugin>
        </plugins>
    </build>

新建子类

在这里插入图片描述

添加jar包

这里 不写版本号使用父类版本号

在这里插入图片描述

添加启动程序

在这里插入图片描述

添加端口号

在这里插入代码片

新建控制层
注意层级关系

在这里插入图片描述

创建完后在新建一个module

名为 provider8001
端口8001
添加启动程序
添加控制层

在这里插入图片描述

启动后,可以在Service 里面看见这两个的情况

在这里插入图片描述

这里我们访问
http://localhost:81/test?name=%22%E5%BC%A0%E4%B8%89%22

这里就会报错

这里我们就要添加一个config

在这里插入图片描述

ContextConfig

在这里插入图片描述

这里可以看到我们就不报错了

在这里插入图片描述

再次通过
http://localhost:81/test?name=%22%E5%BC%A0%E4%B8%89%22
这个网址访问
就可以访问了

在这里插入图片描述

java 注册中心

新建项目
eureka7001

在这里插入图片描述

配置项目
项目创建成功后,需要在启动类上加上一个注解(@EnableEurekaServer),标记它是一EurekaServer:

@EnableEurekaServer // 表达当前的项目 是注册中心 服务器
package com;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
// 使用 cloud 依赖
@EnableEurekaServer // 表达当前的项目 是注册中心 服务器
public class Eureka7001 {
    public static void main(String[] args) {
        SpringApplication.run(Eureka7001.class, args);
    }
}

在application.propeties加入配置:

server:
  port: 7001

# eureka 默认配置 是向注册中心服务器 注册
# 7001 作为 服务端 自己不用向 自己注册
eureka:
  client:
    fetch-registry: false
    register-with-eureka: false
    # 把服务器端口 暴露出去 给其他的子项目使用
    service-url:
      defaultZone: http://localhost:7001/

配置完成后就可以启动项目了。
浏览器输入localhost:7001,当看见这个页面,就证明已经配置成功了

在这里插入图片描述

负载均衡(怎么实现)

在这里插入图片描述

8001 配置文件添加代码
添加完 application name 后会在注册中心显示

在这里插入图片描述


spring:
  datasource:
    password: root123
    username: root
    url: jdbc:mysql://localhost:3306/ebookSys?useSSL=false
    driver-class-name: com.mysql.jdbc.Driver
  application:
    name: provider-service


server:
  port: 8001
#  同时启用多个项目 如果端口号 一样 就会出现异常

eureka:
  client:
    fetch-registry: true
    register-with-eureka: true
    # 把服务器端口 暴露出去 给其他的子项目使用
    service-url:
      defaultZone: http://localhost:7001/eureka #单机版

7001 服务端 配置文件需要修改

server:
  port: 7001

# eureka 默认配置 是向注册中心服务器 注册
# 7001 作为 服务端 自己不用向 自己注册
eureka:
  client:
    fetch-registry: false
    register-with-eureka: false
    # 把服务器端口 暴露出去 给其他的子项目使用
    service-url:
      defaultZone: http://localhost:7001/eureka

7001 服务端 jar 包

<?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>cloud1009</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>eureka7001</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
<!--       引入依赖 cloud注册中心 服务端依赖 server服务端-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>

</project>

8001 在Controller 里面添加 代码

package com.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

// 用户服务 用来操作 用户数据表
@RestController
public class UserController {

    @RequestMapping("/login")
    public String login(String username, String password) {
        System.out.println(username + password);
        return "8001 login接口" + username + password;
    }

		// 获取配置信息里的端口号
    @Value("${server.port}")
    String port;

    @RequestMapping("/myLBtest")
    public String myLBtest(){
        return port + " myLBtest";
    }
}

8001 所用的 jar包

      <dependencies>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-web</artifactId>
       </dependency>

       <!--       引入依赖 cloud注册中心 服务端依赖 server服务端 client客户端-->
       <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
       </dependency>
       <dependency>
           <groupId>mysql</groupId>
           <artifactId>mysql-connector-java</artifactId>
           <version>5.1.32</version>
       </dependency>
       <dependency>
           <groupId>com.baomidou</groupId>
           <artifactId>mybatis-plus-boot-starter</artifactId>
       </dependency>
   </dependencies>

新建 provider8002 provider8003

上面弄完后 复制com 和 配置文件 application.yml 到 provider8002 provider8003 里面去 并修改端口号 为 8002 8003
修改启动类的文件名
在这里插入图片描述

然后启动

在这里插入图片描述

输入不同的端口下面就会跟着变

在这里插入图片描述

在这里插入图片描述

扩展 随机版

在这里插入图片描述

consumer80 配置文件

游览器默认端口 80

server:
  port: 81
#  同时启用多个项目 如果端口号 一样 就会出现异常

eureka:
  client:
    fetch-registry: true
    register-with-eureka: true
    # 把服务器端口 暴露出去 给其他的子项目使用
    service-url:
      defaultZone: http://localhost:7001/eureka # 单机版
spring:
  application:
    name: consumer-service

使用 jar 包

<?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>cloud1009</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>consumer80</artifactId>

   <dependencies>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-web</artifactId>
       </dependency>
       <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-commons</artifactId>
       </dependency>
       <!--       引入依赖 cloud注册中心 服务端依赖 server服务端-->
       <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
       </dependency>
   </dependencies>

</project>

在这里插入图片描述

在这里插入图片描述

controller 层代码

package com.controller;


import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.List;
import java.util.Random;

@RestController
// RestController = com.controller + responsebody
public class TestController {

    // 把spring 容器里面的 对象 自动 装配到当前类中
    // restTemplate 首先 要存在spring 容器里面
    @Resource
    RestTemplate restTemplate;
    // 负载均衡 由cloud提供的组件 来 按照特定规则 调用 服务 8001 8002 8003 (随机 轮换)

    @RequestMapping("/test")
    public String test(String name) {
        System.out.println(name);
        String url = "http://localhost:8001/login?username=张三&password=123";
        // restTemplate.getForObject(url,String.class); 这个是调用8001 服务器 login 接口
        String forObject = restTemplate.getForObject(url, String.class);
        return "80服务器 test接口" + name + "  " + forObject;
    }

    @Resource
    DiscoveryClient discoveryClient;

    @RequestMapping("/mylb")
    public String mylb() {

        // 1 先获取 provider 服务集合
        List<ServiceInstance> instances = discoveryClient.getInstances("PROVIDER-SERVICE");
        for (ServiceInstance s : instances) {
            System.out.println(s.getUri());
            System.out.println(s.getHost() + "" + s.getPort());
        }

        String url = serverUrl(instances);
        // restTemplate.getForObject(url,String.class); 这个是调用8001 服务器 login 接口
        String forObject = restTemplate.getForObject(url + "/myLBtest", String.class);
        return forObject;
    }


    int count = 1;

    // 参数 服务器 集合
    // 返回值 其中的一个服务器地址
    public String serverUrl(List<ServiceInstance> instances) {
        // 所有服务器个数
        int size = instances.size();
//        System.out.println(size);
        System.out.println("第" + count + "次访问服务");
        // 顺序版
//        int num = 0;
//        if (count % size == 1) {
//            num = 0;
//        } else if (count % size == 2) {
//            num = 1;
//        } else {
//            num = 2;
//        }

        count++;
        // 随机版
        Random random = new Random();
        int num = random.nextInt(size);
        System.out.println(num);

        return instances.get(num).getUri().toString();
    }
}

然后输入网址,点刷新 每次的结果不一样

在这里插入图片描述

负载均衡

创建 module consumer-feign80
导入jar包

在这里插入图片描述

所需jar包

<dependencies>
       <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-starter-openfeign</artifactId>
       </dependency>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-web</artifactId>
       </dependency>
       <!--       引入依赖 cloud注册中心 服务端依赖 server服务端-->
       <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
       </dependency>
   </dependencies>

创建启动类

@EnableFeignClients  // 开启feign 功能

在这里插入图片描述

创建控制层

package com.controller;

import com.service.FeiService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
public class UserController80 {
    @Resource
    FeiService feiService;

    @RequestMapping("/test")
    public String test(){
        // 服务调用 feign 不在使用 resttempl 模板
        System.out.println("test.....feign");
        // 创建 service 层通过配置 feign 来实现调用服务
        String login = feiService.login();
        return login;
    }
}


创建 service 层

package com.service;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;

@FeignClient(value = "PROVIDER-SERVICE")
@Component
public interface FeiService {

    // 8001 服务  方法头部保持一致
    @RequestMapping("/login")
    public String login();
}


注意启动是不要开启
consumer80

三种参数的传递

第一种 基本类型参数

首先在80添加测试代码

在这里插入图片描述

service添加
注意service 层代码要和8001-8003 的方法保持一致

 @RequestMapping("/test1")
    public String test1();

在8001 8002 8003 添加测试代码

8002 8003 修改 下面的输出

 @RequestMapping("/test1")
    public String test1(String name){
        System.out.println("8001.." + name);
        return "test1 8001" + name;
    }

在这里插入图片描述

可以看到这里参数并没有传过来

在service 层 和 8001-8003 服务的Controller层 添加 RequestParam 注解

在这里插入图片描述

在这里插入图片描述

consumer-feign 80 的Controller 层 不需要添加 注解

在这里插入图片描述

第二种 地址栏传参

Controller 层添加

这里注意要在上面添加 注解

  // 地址栏传参 restful 风格 访问
    @RequestMapping("/test2/{id}")
    public String test2(@PathVariable("id") Integer id){
        System.out.println("test1..."+id);
        String test = feiService.test2(id);
        return test;
    }

在这里插入图片描述

FeiService 层

@RequestMapping("/test2/{id}")
    public String test2(@PathVariable("id") Integer id);

8001 - 8003 添加

其他的修改 下面输出就行

 @RequestMapping("/test2/{id}")
    public String test2(@PathVariable("id") Integer id){
        System.out.println("8001.." + id);
        return "test1 8001 " + id;
    }
第三种 对象传参

Controller 层添加

注意这里不需要添加注解

 // 3 对象传参
    @RequestMapping("/test3")
    public String test3(UserInfo userInfo){
        System.out.println("test3..."+userInfo);
        String test = feiService.test3(userInfo);
        return test;
    }

在这里插入图片描述

FeiService 层

@RequestMapping("/test3")
    public String test3(@RequestBody UserInfo userInfo);

8001 - 8003 添加

其他的修改 下面输出就行

 @RequestMapping("/test3")
    public String test2(@RequestBody UserInfo userInfo){
        System.out.println("8001.." + userInfo);
        return "test3 8001 " + userInfo;
    }

网关

在这里插入图片描述

新建module
在这里插入图片描述

需要用到的包

<dependencies>
<!--      eureka 客户端  -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
<!--        gateway 网关的包-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
    </dependencies>

新建启动类
Gateway9527

package com;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@EnableEurekaClient
public class Gateway9527 {
    public static void main(String[] args) {
        SpringApplication.run(Gateway9527.class, args);
    }
}

添加配置文件

spring:
  application:
    name: gateway-service
    # 服务名称


server:
  port: 9527
#  同时启用多个项目 如果端口号 一样 就会出现异常

eureka:
  client:
    fetch-registry: true
    register-with-eureka: true
    # 把服务器端口 暴露出去 给其他的子项目使用
    service-url:
      defaultZone: http://localhost:7001/eureka #单机版

设置配置信息
GateConfig

package com.config;

import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class GateConfig {
    @Bean
    // spring 容器 注入 一个 路由检查对象
    // 网关 路由
    public RouteLocator routeLocator(RouteLocatorBuilder builder) {
//      1  RouteLocatorBuilder 通过这个build 生成一个 build对象 用api来控制页面访问
//        mybatis factory build session mapper 对象
        RouteLocatorBuilder.Builder routes = builder.routes();
//        routes.route() 方法里面来实际 操作地址的 转换请求访问
//        当页面输入path guonei 地址的时候 网关 就会自动配置这个路径的映射 uri
//        要想实现还需要配置访问规则
        routes.route("gate_route1",
                r -> r.path("/guonei")
                        .uri("https://news.baidu.com/"))
                .build();
//        mvc config 配置     pattern mapping
        return routes.build();
//        https://news.baidu.com/guonei
//        http://localhost:9527/guonei  类似隐藏真实的 服务器地址
    }

}

网址拦截

spring:
  application:
    name: gateway-service
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true   #  打开路由开关
      routes: # 路由规则
        - id: provider_routh #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名
          #          uri: http://localhost:8002          #匹配后提供服务的路由地址
          uri: lb://PROVIDER-SERVICE
          #  匹配的  具体的服务
          predicates: # 匹配规则   断言机制   path  只允许 path设置的 访问请求
            # 这里 1 改成 * 号 就是不管是test1 test2 依次类推 ,都不能访问
            - Path=/test1/**
# uri path 也就说只允许访间8001服务的test1方法
#  1 直接访问 8001  http://localhost:8001/test1?name=123  成功
#  2 http://localhost:9527/test1?name=123 通过网关 成功
# 3 http://localhost:8001/test2/123  test2 成功
# 4 http://localhost:9527/test2/123  失败
#  5,6  80服务器访问 test1 test2  http://localhost:8001/test2/222  都成功

server:
  port: 9527
#  同时启用多个项目 如果端口号 一样 就会出现异常

eureka:
  client:
    fetch-registry: true
    register-with-eureka: true
    # 把服务器端口 暴露出去 给其他的子项目使用
    service-url:
      defaultZone: http://localhost:7001/eureka #单机版


在这里插入图片描述

这里我们通过9527访问 test1 是可以访问的
访问test2 test3访问不了

时间拦截

这个意思是10:07分前不可以访问,10:07分后可以访问

在这里插入图片描述

服务降级

避免前端访问错误

在这里插入图片描述

当服务不可用的时候避免前端返回错误最好是服务器返回友好提示服务不可用请稍后再试

需要jar 包

  <!--新增hystrix-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>

我们在 consumer-feign80 里开启 服务降级功能

在这里插入图片描述

package com;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableFeignClients // 开启 feign 功能
@EnableHystrix  //  开启 服务降级功能
public class ConsumerFeign80 {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerFeign80.class,args);
    }
}

配置文件中添加

feign:
  hystrix:
    enabled: true

在这里插入图片描述

新建类
HysFeiServiceImpl

package com.service;

import com.model.UserInfo;
import org.springframework.stereotype.Component;

@Component
public class HysFeiServiceImpl implements FeiService{

    @Override
    public String login() {
        return "login 接口 服务不可用,请稍后重试";
    }

    @Override
    public String test1(String name) {
        return "test1 接口 服务不可用,请稍后重试 " + name;
    }

    @Override
    public String test2(Integer id) {
        return "test2 接口 服务不可用,请稍后重试 " + id;
    }

    @Override
    public String test3(UserInfo userInfo) {
        return "test3 接口 服务不可用,请稍后重试 " + userInfo;
    }
}

在这里插入图片描述

修改FeiService 接口

package com.service;

import com.model.UserInfo;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

//@FeignClient(value = "PROVIDER-SERVICE")
//@FeignClient(value = "GATEWAY-SERVICE")
// feign 和 hystrix 配置
// 降解类 要实现 当前接口 重写 当前类的方法
@FeignClient(value = "GATEWAY-SERVICE",fallback = HysFeiServiceImpl.class)
@Component
public interface FeiService {

    // 8001 服务  方法头部保持一致
    @RequestMapping("/login")
    public String login();

    @RequestMapping("/test1")
    public String test1(@RequestParam("name") String name);

    @RequestMapping("/test2/{id}")
    public String test2(@PathVariable("id") Integer id);

    @RequestMapping("/test3")
    public String test3(@RequestBody UserInfo userInfo);
}

我们访问test1
这里是可以访问的

在这里插入图片描述

可以看到test2 test3就不可以访问了

在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

SSOA6

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

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

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

打赏作者

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

抵扣说明:

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

余额充值