SpringBoot 之整合gRPC

springboot整合gprc 传输对象 一,grpc简介: GRPC是google开源的一个高性能、跨语言的RPC框架,基于HTTP2协议,基于protobuf 3.x,基于Netty 4.x +。GRPC与thrift、avro-rpc等其实在总体原理上并没有太大的区别,简而言之GRPC并没有太多突破性的创新。    对于开发者而言:    1)需要使用protobuf定义接口,即.proto文件    2)然后使用compile工具... 阅读详情

父工程中引入基本的依赖:

<modules>
        <module>api</module>
        <module>client</module>
        <module>service</module>
    </modules>
 
<parent>
    <artifactId>spring-boot-starter-parent</artifactId>
    <groupId>org.springframework.boot</groupId>
    <version>2.7.3</version>
</parent>

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

API模块(定义proto文件):

<artifactId>grpc-api</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>

<properties>
    <grpc.version>1.6.1</grpc.version>
    <protobuf.version>3.3.0</protobuf.version>
</properties>

<dependencies>
    <dependency>
        <groupId>io.grpc</groupId>
        <artifactId>grpc-netty</artifactId>
        <version>${grpc.version}</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>io.grpc</groupId>
        <artifactId>grpc-protobuf</artifactId>
        <version>${grpc.version}</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>io.grpc</groupId>
        <artifactId>grpc-stub</artifactId>
        <version>${grpc.version}</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>com.google.protobuf</groupId>
        <artifactId>protobuf-java</artifactId>
        <version>${protobuf.version}</version>
    </dependency>
</dependencies>

<build>
    <extensions>
        <extension>
            <groupId>kr.motd.maven</groupId>
            <artifactId>os-maven-plugin</artifactId>
            <version>1.5.0.Final</version>
        </extension>
    </extensions>


    <plugins>
        <!-- 引入一些插件来帮助我们将.proto文件编译为java的类 -->
        <plugin>
            <groupId>org.xolstice.maven.plugins</groupId>
            <artifactId>protobuf-maven-plugin</artifactId>
            <version>0.5.0</version>
            <configuration>
                <!--使用的protoc版本,os.detected.classifier表示检测到的操作系统,这里检测到的是windows-x86_64-->
                <protocArtifact>com.google.protobuf:protoc:${protobuf.version}:exe:${os.detected.classifier}
                </protocArtifact>
                <pluginId>grpc-java</pluginId>
                <pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}
                </pluginArtifact>
                <!--proto文件所在文件夹的位置-->
                <protoSourceRoot>src/main/proto</protoSourceRoot>
                <!--生成的文件的存放位置 -->
                <outputDirectory>src/main/java</outputDirectory>
                <!--在调用插件去生成java类时,是否清空输出文件夹,这个要设置为false,否则运行compile-custom时会把compile的结果给删了-->
                <clearOutputDirectory>false</clearOutputDirectory>
            </configuration>
            <!-- 做的一个扩展,在执行maven的compile的时候,顺便也执行protobuf-maven-plugin插件的compile和compile-custom-->
            <executions>
                <execution>
                    <goals>
                        <goal>compile</goal>
                        <goal>compile-custom</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

在src/main目录下创建proto文件夹。
创建一个HelloWorldService.proto文件。
在这里插入图片描述

//使用proto3语法
syntax = "proto3";

//生成多个java文件
option java_multiple_files = true;
//把生成的文件放到哪个包下
option java_package = "com.gotion.grpc.api";
//输出的类名
option java_outer_classname = "HelloWorldServiceProto";

//定义一个类
service HelloWorldService {
  //定义一个gRPC方法,参数为HelloRequest,返回结果为HelloResponse
  rpc helloWorld(HelloRequest) returns(HelloResponse) {};
}
//定义的一个请求参数对象
message HelloRequest {
  //msg参数,编号为1,这是编号不是赋值
  string msg = 1;
  //code参数,编号为2
  int32 code = 2;
}
//定义的一个返回结果对象
message HelloResponse {
  //resut参数,编号为1
  string result = 1;
}

将proto文件编译成需要的JAVA文件(使用maven去compile)了。

server模块:

<dependencies>
    <!-- 引入api模块-->
    <dependency>
        <groupId>com.gotion</groupId>
        <artifactId>grpc-api</artifactId>
        <version>1.0.0</version>
    </dependency>
    <!--  引入gRPC服务提供端依赖-->
    <dependency>
        <groupId>net.devh</groupId>
        <artifactId>grpc-server-spring-boot-starter</artifactId>
        <version>2.14.0.RELEASE</version>
    </dependency>
</dependencies>

application.yml文件:

server:
  port: 8081 #正常的SpringBoot应用监听的端口号
 
grpc:
  server:
    port: 9081 #gRPC服务监听的端口号

编写启动类。
实现在API模块中定义的gRPC服务。

import io.grpc.stub.StreamObserver;
import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.server.service.GrpcService;
 
/**
 * gRPC服务提供类,继承api模块中的proto文件编译生成的java文件,重写所定义的gRPC方法
 */
@GrpcService
@Slf4j
public class HelloWorldService extends HelloWorldServiceGrpc.HelloWorldServiceImplBase {
    /**
     * 定义的gRPC方法
     *
     * @param request          请求对象
     * @param responseObserver
     */
    @Override
    public void helloWorld(HelloRequest request, StreamObserver<HelloResponse> responseObserver) {
        //解析请求,获取其中的参数,这些都是我们之前在proto文件中定义的
        String msg = request.getMsg();
        int code = request.getCode();
        log.info("请求中的参数为msg:{},code:{}", msg, code);
        //创建一个响应对象
        HelloResponse helloResponse = HelloResponse.newBuilder().setResult("我是server服务端,我收到了你的请求~").build();
        //将该响应对象返回给调用者
        responseObserver.onNext(helloResponse);
        //这次调用结束了
        responseObserver.onCompleted();
    }
}

client端:

<dependencies>
    <!-- spring boot web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- 引入api模块-->
    <dependency>
        <groupId>com.gotion</groupId>
        <artifactId>grpc-api</artifactId>
        <version>1.0.0</version>
    </dependency>
    <!-- 引入gRPC客户端依赖-->
    <dependency>
        <groupId>net.devh</groupId>
        <artifactId>grpc-client-spring-boot-starter</artifactId>
        <version>2.14.0.RELEASE</version>
    </dependency>
</dependencies>

application.yml文件:

server:
  port: 8080 #springboot应用监听的端口号
grpc:
  client:
    # 自定义服务名(不同服务名可对应不同配置)GrpcClient注解会用到
    grpc-server:
      # 服务端地址,9081是服务提供方的gRPC监听的端口号
      address: localhost:9081
      # 是否开启保持连接(长连接)
      enable-keep-alive: true
      # 使用明文传输
      negotiation-type: plaintext

编写启动类。
测试服务调用(阻塞方式和异步方式)。

import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.client.inject.GrpcClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
 
/**
 * 测试gRPC服务调用
 */
@RestController
@Slf4j
@RequestMapping("/client")
public class TestController {
    //注入阻塞型的gRPC调用对象,服务调用的地址在application.yml中设置了
    @GrpcClient("grpc-server")
    private HelloWorldServiceGrpc.HelloWorldServiceBlockingStub blockingStub;
    //注入异步调用的gRPC调用对象
    @GrpcClient("grpc-server")
    private HelloWorldServiceGrpc.HelloWorldServiceFutureStub futureStub;
    //创建一个线程池来进行异步调用
    private ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 20,
            0, TimeUnit.SECONDS, new ArrayBlockingQueue<>(50), new ThreadPoolExecutor.CallerRunsPolicy());
    //用来接收异步调用结果
    private String result;
 
    /**
     * 测试阻塞调用
     *
     * @return 调用结果
     */
    @GetMapping("/block")
    public String block() {
        //构造请求对象
        HelloRequest helloRequest = HelloRequest.newBuilder().setMsg("block").setCode(100).build();
        //进行阻塞式地调用
        HelloResponse helloResponse = blockingStub.helloWorld(helloRequest);
        return helloResponse.getResult();
    }
 
    /**
     * 测试异步调用
     *
     * @return 调用结果
     */
    @GetMapping("/future")
    public String future() throws InterruptedException {
        //构造请求对象
        HelloRequest helloRequest = HelloRequest.newBuilder().setMsg("block").setCode(100).build();
        //进行异步调用,看到这里返回的是一个ListenableFuture,大家应该都知道要怎么做了哈哈哈
        ListenableFuture<HelloResponse> helloResponseListenableFuture = futureStub.helloWorld(helloRequest);
        //创建一个CountDownLatch,来等待所有的异步任务完成(如果要执行多个异步任务的话,这里只是用一下)
        //参数为要等待执行的异步任务数,这里是1,其实就是一个计算器
        CountDownLatch countDownLatch = new CountDownLatch(1);
        //设置回调
        Futures.addCallback(helloResponseListenableFuture,
                new FutureCallback<HelloResponse>() {
                    @Override
                    public void onSuccess(HelloResponse helloResponse) {
                        log.info("异步调用成功了,结果为{}", helloResponse.getResult());
                        result = helloResponse.getResult();
                        //计数器减1,表示该异步任务执行完成
                        countDownLatch.countDown();
                    }
 
                    @Override
                    public void onFailure(Throwable throwable) {
                        log.error("异步调用失败,原因是{}", throwable.getMessage());
                    }
                },
                executor);
        //为了更直观地表现出异步任务,这里打印一个日志
        log.info("这里是主线程");
        //等待所有异步任务执行完成
        countDownLatch.await();
        return result;
    }
}
springboot 使用 GRPC 说明GRPC是什么?首先我们知道RPC是远程过程调用。而GRPC是RPC的一种实现。那么为什么要用GRPC呢?因为它支持跨语言的开发,换句话说,大家都用过FeignRPC,尤其在springcloud中。然而它只支持java语言,而作为微服务,可能有很多其他的服务不是java开发的。因此需要满足这个需求,就需要一个跨语言的RPC,所以就会考虑使用GRPC好了,下面进入正题直接上代码。我们做一个Service和一个Client进行交互。... 阅读详情

相关推荐

如何在Spring Boot中使用gRPC

通过本文,我们详细介绍了如何在Spring Boot应用中集成和使用gRPC框架,利用其高效的RPC通信机制和自动生成的代码,帮助开发者构建高性能、可扩展的分布式系统。它可以更高效地连接跨语言和跨平台的服务,提供了简单的IDL(接口定义语言)和强大的代码生成工具,帮助开发者快速构建分布式系统。通过集成gRPC,可以利用其高效的底层通信协议和自动生成的客户端和服务端代码,简化分布式系统的开发和维护。首先,定义gRPC的服务和消息类型。编写Spring Boot中的gRPC客户端代码,调用远程的gRPC服务。

微赚开发者技术分享博客 2316

SpringBoot整合grpc

之所以会说grpc是高性能框架,默认情况下,gRPC基于Netty进行服务端和客户端互通,使用Protocol Buffers进行传输,这是Google用于序列化结构化数据的成熟开源机制,基于proto3情况下它还是一个跨语言的RPC框架(目前支持Java、c++、Dart、Python、Objective-C、c#、lite-runtime (Android Java)、Ruby和JavaScript(来自协议缓冲区GitHub repo),以及来自golang/protobuf官方包的Go语言生成器)

qq_38038507的博客 5765

SpringBoot整合Grpc实现跨语言RPC通讯

什么是gRPC gRPC是谷歌开源的基于go语言的一个现代的开源高性能RPC框架,可以在任何环境中运行。它可以有效地连接数据中心内和跨数据中心的服务,并提供可插拔的支持,以实现负载平衡,跟踪,健康检查和身份验证。它还适用于分布式计算的最后一英里,用于将设备,移动应用程序和浏览器连接到后端服务。 简单的服务定义:使用Protocol Buffers定义您的服务,这是一个功能强大的二进制序列化工具集和语言. 跨语言和平台工作:自动为各种语言和平台的服务生成惯用的客户端和服务器存根,当然单纯的java语言之

代码界的扛把子 1186

springboot 集成GRPC

springboot 集成GRPC

sunrj_niu的博客 2290

SpringBoot整合Grpc实现跨语言RPC通讯,你学废了吗?

什么是gRPC gRPC是谷歌开源的基于go语言的一个现代的开源高性能RPC框架,可以在任何环境中运行。它可以有效地连接数据中心内和跨数据中心的服务,并提供可插拔的支持,以实现负载平衡,跟踪,健康检查和身份验证。它还适用于分布式计算的最后一英里,用于将设备,移动应用程序和浏览器连接到后端服务。 简单的服务定义:使用Protocol Buffers定义您的服务,这是一个功能强大的二进制序列化工具集和语言. 跨语言和平台工作:自动为各种语言和平台的服务生成惯用的客户端和服务器存根,当然单纯的java语言之

Java圈全能架构师的博客 1596

springboot 整合谷歌 gRPC

springboot整合grpc

congge 5855

Springboot整合gRPC

Springboot整合gRPC 概述: gRPC 一开始由 google 开发,是一款语言中立、平台中立、开源的远程过程调用(RPC)系统。 在 gRPC 里客户端应用可以像调用本地对象一样直接调用另一台不同的机器上服务端应用的方法,使得您能够更容易地创建分布式应用和服务。与许多 RPC 系统类似,gRPC 也是基于以下理念:定义一个服务,指定其能够被远程调用的方法(包含参数和返回类型)。在服务...

额滴神的博客 2万+

CoppeiaSim(VREP)入门

vrep/CoppeliaSim关节抖动问题原因总结【Coppeliasim|轨迹规划(一)】设置机械臂的关节角时保证机械臂不散架设置机械臂的关节角时保证机械臂不散架。

weixin_50624597的博客 3227

springboot整合grpc

springboot整合grpc 一、简介二、proto3三、Spring Boot 整合 Grpc ) 一、简介 GRPC是google开源的一个高性能、跨语言的RPC框架,基于HTTP2协议,基于protobuf 3.x,基于Netty 4.x +。GRPC与thrift、avro-rpc等其实在总体原理上并没有太大的区别,简而言之GRPC并没有太多突破性的创新。 对于开发者而言: 1)需要使用protobuf定义接口,即.proto文件 2)然后使用compile工具生成特定语言的执行代码,比如J

weixin_46687787的博客 6655

告别电机啸叫!手把手教你配置TMC5160的StealthChop2静音模式(附参数自整定避坑指南)

本文详细介绍了如何通过配置TMC5160的StealthChop2模式彻底消除3D打印机电机噪音。从硬件准备到参数自整定,再到高级调优与异常处理,手把手教你实现实验室级别的静音效果,提升打印质量和使用体验。

weixin_33724659的博客 487

VASP计算层错能(SFE)全攻略2

本文介绍了使用VASP计算纯镍(Ni)层错能(SFE)的具体步骤。首先构建Ni的FCC单胞并扩展为超胞,通过修改原子位置引入堆垛层错;随后分别计算完美晶体和含层错结构的能量;最后通过能量差与层错面积之比求得SFE值。计算需注意k点网格、截断能和超胞尺寸的收敛性测试,并推荐使用PAW赝势和ASE等工具辅助结构构建。

weixin_50519490的博客 1988

gRpc入门和springboot整合

grpc 入门 和 springboot整合

qq_33472553的博客 1448

用deepseek对GPU服务器进行压力测试

利用 DeepSeek 模型对 GPU 服务器进行压力测试,核心思路是通过,验证 GPU 服务器在计算、显存、网络等维度的承载能力,同时观察稳定性与性能瓶颈。

weixin_42795092的博客 1610

Springboot整合gRPC实践

Springboot整合gRPC 最近公司其他服务为go语言开发,这边Java服务需要进行交互,考虑到效率和系统发展的问题,因此使用了gRPC来作为rpc框架。由于基本是第一次使用Springboot集成gRPc,经过一系列的踩坑,终于完成了项目的开发,这边记录下整合方式。 gRPC简介 gRPC是谷歌开源的基于go语言的一个现代的开源高性能RPC框架,可以在任何环境中运行。它可以有效地连接数据中心内和跨数据中心的服务,并提供可插拔的支持,以实现负载平衡,跟踪,健康检查和身份验证。它还适用于分布式计算的最后

JayCoding 5994

IBIS模型中的Pullup和Pulldown曲线详解:如何避免信号完整性设计中的常见错误

本文深入解析IBIS模型中Pullup和Pulldown曲线的关键作用,揭示其在信号完整性设计中的黄金法则。通过详细分析曲线特性、常见误区及验证方法,帮助工程师避免设计错误,优化高速PCB设计。文章还展示了曲线数据在动态终端匹配、串扰预测和电源完整性分析中的高级应用,提升设计效率和可靠性。

weixin_30275415的博客 451

HCIA-Storage 存储工程师学习笔记——1. 存储技术趋势

文章目录1. 存储技术趋势1.1 数据、信息与数据存储1.2 存储技术的发展①存储架构的发展②存储介质的发展③ 接口协议的发展1.3 存储产品的发展趋势 华为HCIA-Storage认证地址:https://e.huawei.com/cn/talent/#/cert/roadmap 1. 存储技术趋势 1.1 数据、信息与数据存储 什么是数据? ​ 数据是对所有事物的数字表示。 数据的种类? 结构化数据 半结构化数据 非结构化数据 数据的处理周期 ​ 数据处理是人或机器对数据进行的重组或重新排序,

超级大洋葱的博客 2847

grpc 介绍与整合springboot

grpc是谷歌的一种高性能、开源的通用型RPC框架;支持多达十几种常用语言,它的原理是通过 IDL(Interface Definition Language)文件定义服务接口的参数和返回值类型,然后通过代码生成程序生成服务端和客户端的具体实现代码,这样在 gRPC 里,客户端应用可以像调用本地对象一样调用另一台服务器上对应的方法。

Jelly 650

Field Characteristics 深入解析,理解 SAP ABAP Analytics 中 Dimension 与 Measure 的真正边界

在SAP ABAP Analytics数据模型中,字段应建模为Dimension还是Measure,关键在于业务语义而非数据类型。Dimension提供分析上下文,构成数据坐标系,支持钻取与切片;Measure则需具备明确聚合语义(如#SUM、#MIN、#MAX),且必须满足Distinct(无重复)与Complete(无缺失)原则,确保聚合结果准确。错误的建模会导致聚合偏差,根源常在事实粒度不清或关联关系不当。因此,正确划分字段角色,本质是让Analytical Engine准确理解业务数据的分析逻辑。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 58

Spring boot 整合grpc 运用

Unary RPC 一元RPC调用,也叫简单RPC调用 【服务端 Server Stream RPC】流式RPC. 客户端向服务端发送单个请求,服务端以流的方式返回一系列消息。客户端从流中读取消息,直到没有更多的消息。当然,返回的消息当然不是乱序的,gRPC保证单个请求中的消息顺序 【客户端 Client Stream RPC】流式RPC调用。客户端向服务端请求一系列的消息,一旦客户端完成消息写入,就会等待服务端读取所有消息并处理它们。gRPC同样会保证单个请求中消息的顺序性 【双向流式调用 B

何xiao树 1007

【DRAM存储器六十四】DDR5介绍--preamble、postamble、interamble、刷新、power down、MPSM

简述DDR5 reamble、postamble、interamble、刷新、power down、MPSM的功能定义

highman110的博客 339

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

gRPC与Spring Boot实战:整合教程

gRPC与Spring Boot实战:整合教程 一、项目目录结构及介绍 本教程基于GitHub上的开源项目 grpc-spring-boot-demo,它演示了如何在一个Spring Boot项目中集成gRPC服务。下面简要介绍项目的结构和各部分的功能: ├── grpc-lib # 包含公共的.proto文件,定义服务接口和消息类型。 │ └── src/main/p...

gitblog_00826的博客 568

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

【橘子分布式】gRPC(番外篇-如何整合springboot)

我们完成了关于grpc的一些基础编程,但是实际开发中往往要和一些主流的框架体系做整合,融入到里面去。我们常见的就是springboot体系,那么grpc如何在springboot中使用这个问题我们今天就来探讨一下。

liuwenqiang1314的博客 867

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

GRPC简介,SpringBoot整合GRPC小案例

什么是RPC? RPC(Remote Procedure Call)远程过程调用,是一种进程间通信方式。 简单地说就是能使应用像调用本地方法一样的调用远程的过程或服务,可以应用在分布式服务、分布式计算、远程服务调用等许多场景。说起 RPC 大家并不陌生,业界有很多开源的优秀 RPC 框架,例如 Dubbo、Thrift、gRPC、Hprose 等等。 下面先简单介绍一下 RPC 与常用远程调用方式的特点 架构图如下: 角色解释: 客户端(Client):服务调用发起方,也称为服务消费者。

weixin_41861506的博客 1313

GRPC快速整合springboot实战

GRPC整合springboot gRPC是一个高性能,开放源代码的通用RPC框架。默认情况下,它使用协议缓冲区来定义公开的服务。 该框架提供了双向流等功能,并支持许多不同的编程语言。 gRPC最初由Google开发,现已获得Apache 2.0的许可。 为了展示gRPC的工作原理,我们来构建一个客户端和相应的服务器,以公开一个简单的Hello World gRPC服务。 一、引入maven依赖包 2.x.x.RELEASE 支持 Spring Boot 2.1.x/2.2.x 和 Spring Cloud

itboy 2536

SpringBoot 整合gRPC

gRPC是一种与语言无关的高性能远程过程调用 (RPC) 框架。 gRPC 的主要优点是: 现代高性能轻量级 RPC 框架。 协定优先 API 开发,默认使用协议缓冲区,允许与语言无关的实现。 可用于多种语言的工具,以生成强类型服务器和客户端。 支持客户端、服务器和双向流式处理调用。 使用 Protobuf 二进制序列化减少对网络的使用。 这些优点使 gRPC 适用于: 效率至关重要的轻量级微服务。 需要多种语言用于开发的 Polyglot 系统。 需要处理流式处理请求或响应的点对点实时.

u014365523的博客 1540
上一篇: Maven 之 配置文件pom
下一篇: Java 之集成 DataX 数据同步工具
yyangqqian
博客等级 码龄15年 406粉丝 406原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值