springcloud笔记(上),Eureka等

【这篇文章是纯笔记了,有点混乱,先发上去保存一下,后期有空再优化】


SOA->Dubbo

微服务架构->Spring Cloud提供了一个一站式的微服务解决方案

--------------------------

单体应用:
优点:
项目前期开发节奏快,团队成员少的时候能够快速迭代
架构简单,MVC架构,只需要借助IDE开发、调试即可
易于测试,只需要通过单元测试或者浏览器完成
易于部署,打包成单一可执行的jar或者打成war包放到容器内启动

缺点:
随着不断的功能迭代,单个项目过大,代码杂乱,耦合严重,开发团队逐渐壮大后,沟通成本变高。
新增业务困难,新人学习成本高,维护旧功能困难。
核心业务与边缘业务混合在一起,出现问题互相影响。

--------------------------
垂直应用架构:
基于功能特性,对服务进行拆分,将一个大系统拆分成多个小系统,可以针对每个小系统进行优化、部署集群等。

--------------------------
SOA架构:
为了解决垂直划分后接口协议不统一、服务无法监控、服务负载均衡等问题,使用SOA架构。
例如引入Dubbo-一款高性能、轻量级的开源java RPC框架,提供三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。

Service-Orientend Architecture,即面向服务的架构。根据实际业务,把系统拆分成合适的、独立部署的模块,模块之间相互独立(通过Webservice/Dubbo等技术进行通信)。

-------------------------------
微服务应用架构:
可以说是SOA架构的一种扩展,这种架构模式下它拆分粒度更小,服务更独立。把应用拆分成一个个微小的服务,不同服务可以使用不同的开发语言和存储,服务之间往往通过Restful等轻量级通信。微服务架构关键在于微小、独立、轻量级通信。

与SOA相比,可以说在服务拆分上更细,引入了新的技术栈。

-----------------------------------

微服务架构优缺点:
优点:
微服务很小,便于特定业务功能的聚焦;
每个微服务都可以被一个小团队单独实施,便于敏捷开发;
便于重用和模块之间的组装;
不同微服务可以使用不同的语言开发,松耦合;
微服务架构下,更容易引入新技术;
可以更好的实现DevOps开发运维一体化。

缺点:
微服务架构下,分布式复杂难以管理,当服务数量增加,管理将越加复杂;
微服务架构下,分布式链路跟踪难。

--------------------------------

负载均衡、熔断、链路追踪、网关

API网关:让API请求调用统一接口接入API网关层,由网关转发请求。
API网关更专注在安全、路由、流量等问题的处理上。(微服务团队专注于处理业务逻辑即可)
它的功能比如:
1.统一接入(路由)
2.安全防护
3.黑白名单
4.协议适配
5.流量管控
6.长短链接支持
7.容错能力

=======================================
Spring Cloud综述
Spring Cloud是什么:
Spring Cloud是一系列框架的有序集合,它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。

Spring Cloud其实是一套规范,是一套用于构架微服务的规范,而不是一个可以拿来即用的框架。

在这个规范下,第三方的Netfix公司开发了一些组件、Spring官方开发了一些框架/组件,包括第三方的阿里巴巴开发了一套框架/组件集合Spring Cloud Alibaba,这些才是Spring Cloud规范的实现。

--------------------------------

Spring Cloud规范及实现意图要解决的问题其实就是微服务架构实施过程中存在的一些问题,比如微服务架构中的服务注册发现问题、网络问题(比如熔断场景)、统一认证安全授权问题、负载均衡问题、链路追踪等问题。

----------------------------------------

第一代Spring Cloud(Netfix,SCN)
注册中心 Netfix Eureka
客户端负载均衡 Netfix Ribbon
熔断器 Netfix Hystrix
<网关 Netfix Zuul:性能一般,未来将推出Spring Cloud生态圈>
配置中心 官方Spring Cloud Config
服务调用 Netfix Feign
消息驱动 官方 Spring Cloud Stream
链路追踪 官方 Spring Cloud Sleuth/Zipkin

-----------------------------------------------

第二代Spring Cloud(主要就是Spring Cloud Alibaba,SCA)
注册中心 阿里巴巴 Nacos
客户端负载均衡 阿里巴巴 Dubbo LB、Spring Cloud Loadbalancer
熔断器 阿里巴巴 Sentinel
网关 官方Spring Cloud Gateway
配置中心 阿里巴巴 Nacos、携程Apollo
服务调用 阿里巴巴 Dubbo RPC


-------------------------------

Spring Cloud与Dubbo对比
Dubbo传输效率比Spring Cloud Netfix(Http)高。
但是Dubbo体系的组件不全,不能够提供一站式解决方案,比如服务注册与发现需要借助Zookeeper等实现,而Spring Cloud Netfix则是真正的提供了一站式服务化解决方案,且有Spring大家族背景。

------------------------------

Spring Cloud 与 Spring Boot 的关系
Spring Cloud利用了Spring Boot的特点,让我们能够快速的实现微服务组件开发。

----------------------------

第一代spring cloud组件(Netflix,SCN):
用户请求->网关Gateway->服务(RestTemplate+Ribbon+Hystrix)或Feign
服务->注册中心Config
服务->配置中心Eureka

----------------------

服务注册中心server:
1.启动服务提供者后,会注册到服务注册中心server。后续要定期发送心跳。
2.服务注册中心server可以使用push模式,当服务有变化时推送给服务消费者;
也可以使用poll模式,服务消费者主动(定时)从服务注册中心拉取服务信息。

Eureka使用poll模式。(没有完成push模式)

------------------

主流服务注册中心有:
zookeeper、Eureka、Consul、Nacos

Zookeeper本质=存储+监听通知

Eureka:由Netflix开源,并被Pivatal集成到SpringCloud体系中,它是基于RestfulAPI风格开发的服务注册与发现组件。

Consul:是由HashiCorp基于Go语言开发的支持多数据中心分布式高可用的服务发布和注册服务软件,采用Raft算法保证服务的一致性,且支持健康检查。

Nacos:是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。简单来说Nacos就是 注册中心+配置中心 的组合。Nacos是Spring Cloud Alibaba核心组件之一,负责服务注册与发现,还有配置。


组件名 语言 CAP 对外暴露接口
Eureka java AP(自我保护机制,没有收到心跳时,不会立即删除服务信息,可能是网络问题导致没有心跳但是服务可用。保证可用) Http
Consul Go CP Http/DNS
Zookeeper java CP 客户端
Nacos java 支持AP/CP切换 Http

------------------

服务注册中心组件Eureka

server端:Eureka server注册中心,需要自己创建工程,引入服务端jar包,然后启动。
client:分为客户端消费者与服务端消费者。需要引入eureka client相关的jar,然后进行相关的配置,微服务才能和eureka server建立联系。

Eureka服务注册中心可以搭建集群,防止只有一台挂掉时影响使用。
Eureka服务提供者也可以搭建集群
Eureka服务消费者也可以搭建集群

-------------------------

Eureka元数据详解:
Eureka元数据有2种:标准元数据和自定义元数据。

标准元数据:主机名、IP地址、端口号等信息,这些信息都会被发布在服务注册表中,用于服务之间的调用。
自定义元数据:可以使用eureka.instance.metadata-map配置,符合KEY/VALUE的存储格式。这些元数据可以在远程客户端中访问。

客户端可以从Eureka Server中获取服务的实例信息以及接口信息(标准元数据)
服务端可以配置自定义元数据,之后客户端可以从Eureka Server中获取,进行后续操作。

-----------------------------

Eureka服务提供者要向Eureka Server注册服务,并完成服务续约等工作。
服务注册:
1.导入eureka-client依赖坐标,配置Eureka服务注册中心地址
2.服务在启动时会向注册中心发起注册请求,携带服务元数据信息
3.Eureka注册中心会把服务的信息保存在Map中

服务续约:
服务每隔30秒会向注册中心续约(心跳)一次(也称为报活),如果没有续约,租约在90秒后到期,然后服务会被失效。每隔30秒的续约操作我们称之为心跳检测。

往往我们不需要调整这两个设置。

----------------------------

Eureka服务消费者每隔30秒会从注册中心拉取一份服务列表,这个时间可以通过配置修改。

1.服务消费者启动时,从EurekaServer服务列表获取只读备份,缓存到本地
2.每隔30秒,会重新获取并更新数据
3.每隔30秒的时间可以通过配置eureka.client.registry-fetch-interval-seconds修改

----------------------------------

Eureka服务端:
服务下线:
1.当服务正常关闭操作时,会发送服务下线的REST请求给EurekaServer。
2.服务中心接受到请求后,将该服务置为下线状态。

失效剔除
Eureka Server会定时(间隔值是eureka.server.eviction-interval-timer-in-ms,默认60s)进行检查,如果发现实例在一定时间(此值有客户端设置的eureka.instance.lease-expiration-duration-in-seconds定义,默认值为90s)内没有收到心跳,则会注销此实例。

自我保护:
如果在15分钟内超过85%的客户端节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,Eureka Server自动进入自我保护机制。

为什么会有自我保护机制:
默认情况下,90s没有收到心跳,应该移除该服务实例;但是当网络分区故障发生时,微服务与Eureka Server之间无法正常通信,而微服务本身是正常运行的,此时不应该移除这个微服务,所以引入了自我保护机制。

当处于自我保护机制时:
1.不会剔除任何服务实例,保证了大多数服务依然可用
2.Eureka Server仍然能够接受新服务的注册和查询请求,但是不会被同步到其它节点上,保证当前节点依然可用;当网络稳定时,当前Eureka Server新的注册信息会被同步到其它节点中。
3.在Eureka Server工程中通过eureka.server.enable-self-preservation配置可关停自我保护,默认值是打开。

【建议生产环境打开自我保护机制。】

==============================================


Ribbon负载均衡

关于负载均衡:
负载均衡一般分为服务器端负载均衡与客户端负载均衡。

服务端负载均衡:负载均衡的执行是在服务器端。
例如,客户端请求->nginx/F5->服务器1/2/3/4

客户端负载均衡:负载均衡算法的执行是在客户端。
例如,客户端请求->注册中心
客户端从注册中心获取key提供服务的实例信息,然后客户端根据一定算法选择一个去直接请求
客户端请求->server1/2/3/4

Ribbon是Netflix发布的负载均衡器,Eureka一般配合Ribbon进行使用,Ribbon利用从Eureka中读取到的服务信息,在调用服务提供者提供的服务时,会根据一定的算法进行负载。

Ribbon是客户端负载均衡,不需要引入额外的jar坐标,因为在服务消费者中引入过eureka-client,它会引入Ribbon相关的jar。
使用时,在RestTemplate上添加对应注解即可。

@Bean
//Ribbon负载均衡
@LoadBalanced
public RestTemplate getRestTemplate() {
  return new RestTemplate();
}


-----------------------------

Ribbon负载均衡策略:
RoundRobinRule:轮询策略;默认超过10次获取到的server都不可用,会返回一个空的server。
RandomRUle:随机策略;如果随机到的server为null或不可用的话,会while不停的循环选取。
RetryRule:重试策略;一定时间内循环重试。默认继承RoundRobinRule,也支持自定义注入。会在每次选取之后,对选取的server进行判断,是否为null,是否alive,并在500ms内会不停的选取判断。
BestAvailableRule:最小连接数策略。遍历serverList,选取出可用的且连接数最小的一个server。如果选取的server为null,会调用RoundRobinRule重新选取。
AvailabilityFilteringRule:可用过滤策略。扩展了轮询策略,会先通过默认的轮询选取一个server,再去判断是否可用,连接数是否超限,都成功后再返回。
ZoneAvoidanceRule:区域权衡策略(默认策略)。扩展了轮询策略,继承了2个过滤器,除了过滤超时和连接数过多的server,还会过滤掉不符合要求的zone区域里面的所有节点。在一个区域/机房内的服务实例中轮询。(先进行过滤,本质是轮询)

==========================

Hystrix熔断器
属于一种容错机制,用来防止服务器雪崩效应。

微服务中的雪崩效应:
微服务中,一个请求可能需要多个微服务接口才能实现,会形成复杂的调用链路。
如果有一个微服务挂掉,那么调用它的微服务会由于调用响应时间过长、请求累积后、占用越来越多的系统资源,进而引起系统崩溃。

雪崩效应解决方案:
1.服务熔断
当某个微服务不可用或响应时间太长时,要熔断对该节点的调用,进行服务的降级,快速返回错误的响应信息。
当检测到该节点微服务调用响应正常后,恢复调用链路。
注意:
服务熔断重点在"断",切断对下游服务的调用。
服务熔断和服务降级往往是一起使用的,Hystrix就是这样。

2.服务降级
将一些不重要的服务停掉,待请求高峰过去,再把服务打开。
此时客户端可以自己准备一个本地的fallback回调,当要调用的服务不可用时,返回一个缺省值。(比抛出异常好一些)

3.服务限流
当某些重要的服务不能用服务降级解决时(服务不能停),可以考虑服务限流。
限流措施有:
限制总并发数(比如数据库连接池、线程池)
限制瞬时并发数(比如nginx限制瞬时并发连接数)
限制时间窗口内的平均速率(如Guava的Ratelimiter、nginx的limit_req模块,限制每秒的平均速率)
限制远程接口调用速率、限制MQ的消费速率等。

-------------------------------

Hystrix简介:
Hystrix是由Netflix开源的一个延迟和容错库,用于隔离访问远程系统、服务或者第三方库,防止级联失败,从而提升系统的可用性与容错性。Hystrix主要通过以下几点实现延迟和容错:
●包裹请求:使用HystrixCommand包裹对依赖的调用逻辑。
●跳闸机制:当某服务的错误率超过一定的阈值时,Hystrix可以跳闸,停止请求该服务一段时间。
●资源隔离:Hystrix为每个依赖都维护了一个小型的线程池,如果该线程池已满,发往该依赖的请求就被立即拒绝,而不是排队等待,从而加速失败判定。
●监控:Hystrix可以近乎实时地监控运行指标和配置的变化,例如成功、失败、超时、以及被拒绝的请求等。
●回退机制:当请求失败、超时、被拒绝,或当断路器打开时,执行回退逻辑。回退逻辑由开发人员自行提供,例如返回一个缺省值。
●自我修复:断路器打开一段时间后,会自动进入"半开"状态。(如果微服务可用后,会恢复对该微服务的调用)

-----------------------------------

Hystrix Dashboard监控仪表盘

--------------------------------------

Hystrix Turbine聚合监控

----------------------------------

Feign,对Restful进行了封装,简化了请求方式,不用拼接url了。

==================================

GateWay

可以设置全局过滤器,限制某些IP的访问,防止爬虫

----------------------------

Spring Cloud Config分布式配置中心

========================================
========================================
========================================
========================================
========================================
========================================


Spring Cloud Eureka

Eureka可以分为2部分,Eureka Server与Eureka Client;

Eureka Server是服务注册中心;

Eureka Client又可以分为2部分,服务提供者与服务消费者;

服务提供者(client)会将自己提供的服务注册到服务注册中心(server);

服务消费者(client)会从服务注册中心(server)获取服务地址,然后去调用服务。


========================================

Ribbon负载均衡:
是客户端负载均衡器,使用后,服务消费者就不需要指定具体的某一个服务提供者了,只需要在url中输入服务名称即可(有多个服务提供者使用同一个服务名称),然后ribbon会自动选择一个服务提供者进行访问。

使用时,只需要在RestTemplate上加@LoadBalanced即可。

// 使用RestTemplate模板对象进行远程调用
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }

========================================

Hystrix熔断器:
在服务消费者中配置,在controller中的方法上使用@HystrixCommand,配置后对应方法就有了熔断机制;
使用熔断器时,也可以使用fallbackMethod设置回退方法(保底方法),当调不通服务提供者的方法时,就会使用回退方法的返回值作为结果。

----------------------------------------

Hystrix Dashboard断路监控仪表盘

1.使用时,需要单独写一个hystrix项目并启动;
2.需要在被监测的微服务中注册监控servlet,之后就会自动把自己的状态发给Hystrix项目。
3.登录Hystrix页面,输入某个微服务注册的servlet的url,就可以查看对应微服务的状态。

---------------------------------------

Hystrix Turbine聚合监控
Turbine(涡轮)可以聚合多个微服务的监控数据。
1.新建一个turbine项目,使用turbine.appConfig配置好要聚合监控的微服务名称,如果有多个,可以用英文逗号拼接。
2.启动项目
3.登录Hystrix项目的url,在界面输入turbine的url,即可查看聚合监控数据。(后缀为/turbine.stream,例如:http://localhost:9001/turbine.stream)


========================

Feign远程调用组件

Feign是Netflix开发的一个轻量级RESTful的HTTP服务客户端,封装了Http调用流程,更符合面向接口化的编程习惯,类似于Dubbo的服务调用。

1.在服务消费者中使用,写一个本地接口类,类中的方法上可以用@GetMapping注解指明服务提供者的url
2.在服务消费者的另一个类中,注入本地接口类,调用对应的方法,实际上就是调用了远程服务的方法了。

Feign = RestTemplate+Ribbon+Hystrix

Feign本身已经集成了RestTemplate(发http请求调用服务用的)、Ribbon(负载均衡用的)、Hystrix(熔断器)这些功能,使用时增加相关配置即可。

======================================

GateWay网关组件

GateWay的核心逻辑:路由转发+执行过滤器链

需要新建一个Gateway项目,注意不要引入starter-web,需要引入web-flux

Gateway部分主要配置信息与注释:
application.yml
server:
 port: 9002  # 网关的端口是9002
 
spring:
  application:
  name: lagou-cloud-gateway
  cloud:
    gateway:
      routes: # 路由可以有多个
        - id: service-autodeliver-router # 我们自定义的路由 ID,保持唯一
          #uri: http://127.0.0.1:8096  # 目标服务地址  自动投递微服务(部署多实例)  动态路由:uri配置的应该是一个服务名称,而不应该是一个具体的服务实例的地址
          uri: lb://lagou-service-autodeliver   # gateway网关从服务注册中心获取实例信息然后负载后路由
          predicates:                                         # 断言:路由条件,Predicate 接受一个输入参数,返回一个布尔值结果。该接口包含多种默 认方法来将 Predicate 组合成其他复杂的逻辑(比如:与,或,非)。
            - Path=/autodeliver/**
        - id: service-resume-router      # 我们自定义的路由 ID,保持唯一
          #uri: http://127.0.0.1:8081       # 目标服务地址
          #http://localhost:9002/resume/openstate/1545132

          #http://127.0.0.1:8081/openstate/1545132
          uri: lb://lagou-service-resume
          predicates:                                         # 断言:路由条件,Predicate 接受一个输入参数,返回一个布尔值结果。该接口包含多种默 认方法来将 Predicate 组合成其他复杂的逻辑(比如:与,或,非)。
            - Path=/resume/**
          filters:
            - StripPrefix=1  # 去掉url中第1个占位后转发,也就是去掉resume之后转发


这段配置的意思是,配置了id为service-autodeliver-router与service-resume-router的2个路由规则;
本地启动网关项目后,当向网关发起请求:
http://localhost:9002/autodeliver/openstate/1545132
请求会被分发到:
lb://lagou-service-autodeliver/openstate/1545132
相当于:
http://localhost:8081/openstate/1545132

说明:网关的路径是localhost:9002;
      配置了- Path=/autodeliver/**,所以请求这个路径的会被转发;
      配置了lb://lagou-service-autodeliver ,它对应注册到Eureka的服务的名称,相当于地址http://localhost:8081
      所以最后,访问http://localhost:9002/autodeliver/openstate/1545132,会被转发到http://localhost:8081/openstate/1545132
      就是把http://localhost:9002/autodeliver/,换成了http://localhost:8081/,后面的保持不变。
      
      
动态路由设置时,uri以 lb: //开头(lb代表从注册中心获取服务),后面是需要转发到的服务名称。


predicates:
 - Path=/resume/**
 filters:
 - StripPrefix=1 # 去掉url中第1个占位后转发,也就是去掉resume之后转发

-------------------------------------------

Spring Cloud GateWay 还内置了很多 Predicates 功能,实现了各种路由匹配规则(通过 Header、请求参数等作为条件)匹配到对应的路由。


GateWay还可以自定义全局过滤器实现黑白名单。(java中,实现GlobalFilter, Ordered接口,重写filter方法)

-------------------------------------------

GateWay高可用:可以启动多个GateWay实例来实现高可用,在GateWay的上游使用Nginx等负载均衡设备进行负载转发以达到高可用的目的。

===========================================

Spring Cloud Config 分布式配置中心

用来对配置文件进行集中管理,修改配置文件后,对多个微服务都生效。

Spring Cloud Config是一个分布式配置管理方案,包含了Server端和Client端两个部分。

1.可以把配置文件放置在某个地方,例如git。
2.启动server端,它可以从git上获取配置文件的信息。
3.每个微服务相当于client端,启动后,可以从server端获取配置文件的信息并使用。


------------------------------------------

Spring Cloud Config + +Spring Cloud Bus 实现自动刷新
1.可以在Spring Cloud Config项目中引入mq相关jar包,在配置文件中进行一些配置。
2.在其余微服务客户端也引入mq相关jar包,在配置文件中进行一些配置。
3.然后,当修改了git上的配置文件时,给config项目发请求:

//9006是config项目所在路径,后面的是固定的,这个可以刷新所有微服务客户端的配置信息
http://localhost:9006/actuator/bus-refresh
//如果在后面加上 服务名:端口, 表示只刷新这个微服务客户端的配置信息
http://localhost:9006/actuator/bus-refresh/lagou-service-resume:8081

4.config项目会把刷新请求放入mq队列
5.微服务客户端从mq队列获取到刷新请求后,就会重新请求config项目,更新配置文件,并重启自己,使用新的配置文件信息。
(比完全重启要快,似乎是只重启spring容器,会打印:Started application in 4.516 seconds (JVM running for 3286.61))


============================================

Spring Cloud Stream
Spring Cloud Stream 消息驱动组件可以帮助我们更快速,更方便,更友好的去构建消息驱动微服务。
Spring Cloud Stream进行了很好的上层抽象,可以让我们与具体消息中间件解耦合,屏蔽掉了底层具体MQ消息中间件的细节差异,就像Hibernate屏蔽掉了具体数
据库(Mysql/Oracle)一样。

也就是对MQ操作进行了封装,不管使用什么MQ(ActiveMQ,RabbitMQ,RocketMQ,Kafka),上层操作都是一样的,比较方便。


【启动项目连接RabbitMQ时,发现报错:Rabbit health check failed;还有一句:Attempting to connect to: [localhost:5672]。通过百度发现,RabbitMQ会链接本地进行健康检查,如果MQ的位置是远程的,就会报这个错,不过不影响使用。意思是MQ建议项目与MQ的位置部署在同一台机器上,否则不健康。】

============================================

SpringCloud使用Sleuth + Zipkin进行链路追踪,可以在每一个微服务中引入Sleuth,Sleuth把数据信息发送给 Zipkin 进行聚合,利用 Zipkin 存储并展示数据。(每个请求,每经过一个微服务,日志中就会多一个参数记录。)

============================================

微服务统一认证方案 Spring Cloud OAuth2 + JWT,是分布式系统认证方案,可以让用户在分布式系统中保持登录状态等。
用户的请求参数中保存一个jwt令牌,每访问一个微服务,该微服务都会从缓存中查询并校验用户合法性。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

追逐梦想永不停

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

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

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

打赏作者

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

抵扣说明:

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

余额充值