微服务讲解

29 篇文章 0 订阅
21 篇文章 0 订阅

微服务技术栈

  1. 注册中心
  2. 配置中心
  3. 服务集群
  4. 服务网关
  5. 数据库
  6. 分布式缓存
  7. 分布式搜索
  8. 消息队列
  9. 分布式日志服务
  10. 系统监控链路追踪
  11. 持续集成(自动化部署)
  12. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6xidqUEV-1662454500890)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662122178534.png)]

学习内容

微服务治理

  1. 注册发现
  2. 远程调用
  3. 负载均衡
  4. 配置管理
  5. 网关路由
  6. 系统保护
  7. 流量控制
  8. 服务授权
  9. 熔断降级
  10. 分布式事务
  11. TCC模型
  12. AT模型
  13. Seata

异步通信技术

  1. MO消息模型
  2. SpringAMQP
  3. 消息堆积问题
  4. 消息可靠性
  5. 仲裁队列
  6. 延迟队列
  7. 镜像集群
  8. 数据持久化

缓存技术

  1. 缓存穿透、雪崩
  2. SpringDataRedis
  3. Redis主从复制
  4. OpenResty
  5. 缓存数据同步
  6. Nginx本地缓存
  7. Redis持久化
  8. 多级缓存分层
  9. Redis分片集群
  10. Lua脚本
  11. Redis数据结构

DevOps

  1. Dockerfile
  2. DockerCompose
  3. DrayLog
  4. Jenkins
  5. GrayLog
  6. SkyWalking
  7. Docker的使用
  8. Kubernetes

搜索技术

  1. DSL语句
  2. ES集群
  3. RestAPI
  4. 集群脑裂
  5. 竞价排名
  6. 聚合统计
  7. 自动补全
  8. 地理坐标
  9. 拼音分词

认识微服务

  1. 单体架构

    将业务的所有功能集中在一个项目中开发,打包成一个部署

  2. 分布式架构

    根据业务功能对系统进行拆分,每个业务模块作为独立项目开发,称为一个服务

  3. 分布式架构需要考虑的问题

    1. 服务拆分粒度如何
    2. 服务集群地址如何维护
    3. 服务之间如何实现远程调用
    4. 服务健康状态如何感知
  4. 微服务

    是一种经过良好架构设计的分布式架构方案

  5. 微服务特征

    1. 单依职责:微服务拆分粒度更小,每一个服务都对应唯一的业务能力,做到单一职责,避免重复业务开发
    2. 面向服务:微服务对外暴露业务接口
    3. 自治:团队独立,独立技术,数据独立,部署独立
    4. 隔离性强:服务调用做好隔离,容错,降级,避免出现级联问题
  6. 微服务结构

    国内知名微服务技术:SpringCloud ,阿里巴巴的Dubbo

  7. springcloud实现各种微服务组件,并实现了自动装配,开箱即用

    1. 服务注册与发现 Eureka、Nacos、Consul
    2. 服务远程调用 OpenFeign、Dubbo
    3. 统一网关路由 SpringCloudGateway、Zuul
    4. 服务链路监控 Zipkin、Sleuth
    5. 流控、降级、保护 Hystix、Sentinel
  8. springcloud与springboot版本一一对应

服务拆分及远程调用

  1. 服务拆分注意事项

    1. 微服务需要根据业务模块开发,做到单一职责,不要重复开发相同的业务
    2. 微服务数据独立,不要访问其它微服务的数据库
    3. 微服务可以将自己的业务暴露为接口。供其它微服务调用
  2. 远程调用方式分析

    1. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MOPxK1wk-1662454500891)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662345002730.png)]

    2. 注册RestTemplate

    3. 调用方法,发送远程调用服务

  3. 微服务调用方式

    1. 基于RestTemplate发起的http请求实现远程调用
    2. http请求做远程调用是与语言无关的调用,只要知道对方的ip、端口、接口路径、请求参数即可
  4. 提供者与消费者

    1. 服务提供者:一次业务中,被其它微服务调用的服务(提供接口给其他微服务)
    2. 服务消费者:一次业务中,调用其他微服务的服务(调用其他微服务提供的接口)
    3. 提供者与消费者的角色是相对的

Eureka注册中心

服务调用出现的问题

  1. 服务消费者如何获取服务提供者的地址信息

    1. 服务提供者启动时向eureka注册自己的信息
    2. eureka保存这些信息
    3. 消费者根据服务名称向eureka拉取提供者信息
  2. 如果有多个服务提供者,消费者该如何选择

    服务消费者利用负载均衡算法(nginx),从服务列表中挑选一个

  3. 消费者如何得知服务提供者的健康状态

    1. 服务提供者会每隔30秒向EurekaServer发送心跳请求,报告健康状态
    2. eureka会更新服务列表信息,心跳不正常会被剔除
    3. 消费者就可以拉取到最新的消息

Eureka

  1. eureka-server 注册中心
  2. eureka-client
    1. consumer 服务消费者
    2. provider 服务提供者
  3. 作用
    1. 注册服务中心
    2. 拉去服务
    3. 心跳续约,每30秒1次

实践

搭建eureka
  1. 创建项目,引入依赖

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WQNtIGFW-1662454500892)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662346473502.png)]

  2. 编写启动类,添加@EnableEurekaServer注解

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SOvxkZZf-1662454500892)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662346700567.png)]

  3. 添加application.yml文件,编写配置

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0JX8eaYz-1662454500893)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662346548174.png)]

注册服务
  1. 在客户端中添加客户端依赖

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lya9iUhm-1662454500893)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662346985149.png)]

  2. 在application.yml文件中,编写配置

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h1F5kwvy-1662454500893)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662347041077.png)]

服务发现

服务拉取是基于服务名称获取服务列表,然后再对服务列表做负载均衡

  1. 访问的url路径中,服务名代替ip和端口

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vQgMbBDT-1662454500894)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662348195331.png)]

  2. 在服务消费者的项目启动类中的RestTemplate中添加负载均衡注解

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8887ebOX-1662454500894)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662348320004.png)]

Ribbon负载均衡

负载均衡原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wVjPQggA-1662454500894)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662348674216.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kttCdMYB-1662454500895)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662349270405.png)]

负载均衡策略

  1. Ribbon的负载均衡规则是IRule接口定义的,每一个子接口都是一种规则

  2. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P1oDX3La-1662454500895)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662349425604.png)]

  3. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xTgipAkb-1662454500895)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662349454253.png)]

  4. 调整负载均衡策略的两种方式

    1. 代码方式,全局配置:在客户端的启动类中,定义一个新的IRule

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7ySeFaOG-1662454500896)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662349582698.png)]

    2. 配置文件方式,局部配置:可指定服务名,针对某个服务

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-74bMXuL8-1662454500896)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662349843555.png)]

饥饿加载

  1. Ribbon默认采用懒加载,即第一次访问时才会创建LoadBalanceClient,请求时间会很长
  2. 饥饿加载则会在项目启动时创建,降低第一次访问的耗时,通过配置开启饥饿加载
  3. 指定饥饿加载的服务器名称
  4. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fBzq9Bwb-1662454500896)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662350595353.png)]

Nacos注册中心

安装

配置

  1. 引入springcloudAlibaba的管理依赖

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yD2ON4NH-1662454500896)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662351325616.png)]

  2. 添加nacos客户端依赖

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AtnYkKKy-1662454500897)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662351379840.png)]

  3. 配置nacos地址信息

nacos服务分级存储模型

  1. 一级服务、二级集群、三级实例

  2. 服务跨集群调用问题

    1. 服务调用尽可能选择本地集群,跨集群调用延迟较高
    2. 本地集群不可访问时,再去访问其它集群
  3. 服务集群属性

    1. 修改application.yml,添加相应配置

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jpebLWdg-1662454500897)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662356689016.png)]

    2. 在nacos控制台可以看到集群变化

负载均衡

根据器群负载均衡

  1. 修改客户端的application.yml,设置集群名

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C6odIFuT-1662454500897)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662357206547.png)]

  2. 修改客户端的负载均衡Irule为NacosRule,这个规则会优先寻找与自己同集群的服务

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-772I3fr6-1662454500898)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662357311562.png)]

  3. 注意将该客户端的权重都设置为1

根据权重负载均衡

  1. 实际情况

    服务器设备性能有差异,部分实例所在机器性能较好,另一些较差,我们希望性能好的机器承担更多的用户请求

  2. nacos提供了权重配置来控制访问频率,权重越大则访问频率越高

  3. 在nacos控制台可以设置实例的权重值,一般为0-1之间

环境隔离

  1. nacos中服务存储和数据存储的最外层都是一个名为namespace的东西,用来做最外层隔离

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HRKhwGrd-1662454500898)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662358315331.png)]

  2. 修改服务的命名空间

    在配置文件中添加命名空间的id

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RqElA0yH-1662454500898)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662358489132.png)]

  3. 不同namespace中的服务互相不可见

nacos注册中心细节分析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fbjsTChM-1662454500898)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662358844171.png)]

  1. 注册服务信息

  2. 定时拉取服务pull

  3. 主动推送变更消息push

  4. 服务列表缓存

  5. 远程调用

  6. 临时实例采用心跳检测

  7. 非临时实例nacos主动询问

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lNIjjyn4-1662454500899)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662358954224.png)]

nacos与eureka的异同

  1. 相同点
    1. 都支持服务注册和服务拉取
    2. 都支持服务提供者心跳方式做健康检测
  2. 不同点
    1. nacos支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时采用主动检测模式
    2. 临时实例心跳不正常会被剔除,非临时实例则不会被剔除
    3. nacos支持服务列表变更的消息推送模式,服务列表更新更及时
    4. nacos集群默认采用ap方式,当集群中存在非临时实例是,采用cp模式,eureka采用ap方式

nacos配置管理

统一配置管理

  1. 配置更改热更新

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wmRhcCle-1662454500899)(F:\我的文档\笔记本\1662359591730.png)]

  2. 配置获取的步骤

    1. 引入nacos的配置管理客户端依赖

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1ecIWv43-1662454500899)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662360125025.png)]

    2. 在resource目录添加一个bootstrap.yml文件,这个文件是引导文件,优先级高于application.yml

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tT2z4Wyc-1662454500899)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662360240127.png)]

配置自动刷新

nacos 中的配置文件变更后,微服务无法重启就可以感知,不过需要通过配置来实现,有两种方式

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

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E4ktIPno-1662454500899)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662360782935.png)]

  2. 方式二:使用@ConfigurationProperties注解

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jmWIl4Gu-1662454500900)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662361021174.png)]

  3. 注意

    1. 不是所有的配置都适合放到配置中心,维护起来比较麻烦
    2. 建议将一些关键参数,需要运行时调整的参数放到nacos配置中心,一般都是自定义配置

多配置管理

  1. 微服务启动时会从nacos中读取多个配置文件

  2. 多种配置文件优先级

    服务名-profile.yaml>服务名称.yaml>本地配置

nacos集群搭建

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sahmWFxC-1662454500900)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662362145605.png)]

  1. 搭建数据库,初始化数据库表结构

  2. 下载nacos安装包

  3. 配置nacos

    1. 进入nacos的conf目录,修改配置文件cluster.conf.example,重命名为cluster.conf,并添加集群的ip:端口号

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kGeXcafh-1662454500900)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662362607441.png)]

    2. 修改application.properties文件,添加数据库配置

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KSdWy34O-1662454500900)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662362645452.png)]

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gicxKH3n-1662454500901)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662362693637.png)]

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ze9n88Mw-1662454500901)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662362724239.png)]

  4. 启动nacos集群

    打开bin目录,双击startup.cmd

  5. nginx反向代理

    1. 修改conf/nginx.conf文件

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eEhr46Ri-1662454500901)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662362952892.png)]

    2. 双击.exe文件启动

http客户端Feign

RestTemplate方式调用存在的问题

  1. 代码可读性差,编程体验不统一
  2. 参数复杂url难以维护
  3. Feign是一个声明式的http客户端,其作用就是帮助我们优雅地实现http请求的发送,解决以上问题

使用Feign的步骤如下

  1. 引入依赖

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WGJVJ6eR-1662454500901)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662363442056.png)]

  2. 在客户端的启动类中添加注解开启Feign的功能

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aMFDlIeN-1662454500902)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662363488100.png)]

  3. 编写Feign客户端

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QxXw4Isg-1662454500902)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662363553851.png)]

    主要是基于SpringMVC的注解来声明远程调用的信息,如

    1. 服务名称
    2. 请求方式
    3. 请求路径
    4. 请求参数
    5. 返回值类型

自定义Feign的配置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iP8rs5Oi-1662454500902)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662364131986.png)]

一般我们需要配置的是日志级别

自定义Feign的配置有两种方式

  1. 方式一:配置文件方式

    1. 全局生效

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NuRmFjHp-1662454500902)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662364244195.png)]

    2. 局部生效

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9rUmod6N-1662454500903)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662364267076.png)]

  2. 方式二:java代码方式,需要先声明一个Bean

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4Q4F4bMj-1662454500903)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662364313973.png)]

    1. 全局配置。把它放到@EnableFeginClient注解中

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D59MsmtP-1662454500903)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662364377777.png)]

    2. 局部配置,把它放到@FeignClient注解中

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D1uw86Bs-1662454500903)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662364414890.png)]

Feign性能优化

  1. Feingn底层的客户端实现

    1. URLConnection:默认实现,不支持连接池
    2. Apache HTTPClient:支持连接池
    3. OKHttp:支持连接池
  2. 因此优化Feign的性能主要包括

    1. 使用连接池代替默认的URLConnection
    2. 日志级别,最好使用basic或none
  3. 连接池配置

    1. 引入HttpClient依赖

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ysd88Y4L-1662454500903)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662365642799.png)]

    2. 配置连接池

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iGyitQcZ-1662454500904)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662365671105.png)]

Feign的最佳实践

  1. 方式一(继承):给消费者的FeignClient和提供者的controller定义统一的父接口作为标准 (不推荐,造成紧耦合)

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7GilzSaa-1662454500904)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662366234665.png)]

  2. 方式二(抽取):将FeignClient抽取为独立模块,并且把接口有关的POJO、默认的Feign配置都放到这个模块中,提供给消费者使用

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G0XGm93I-1662454500904)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662366526218.png)]

实现方式二,抽取FeignClient

  1. 首先创建一个module。命名为feign-qpi,然后引入feign的starter依赖

  2. 将消费者中编写的生产者客户端,bean、默认Feign配置都赋值到feign-api项目中

  3. 在消费者中引入feign-api依赖

  4. 修改消费者中的与上述三个组件有关 的import部分,改成导入feign-api中的包

  5. 重启测试

  6. 当定义的FeignClient不再SpringbootApplication的扫描包范围内,这些FeignClient无法使用,有两种解决方案

    1. 方式一:指定FeignClient所在包

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZHiNWW8c-1662454500904)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662367336806.png)]

    2. 指定|FeignClient字节码(推荐)

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-56h7Rk6e-1662454500905)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662367367357.png)]

Gateway网关

网关功能

  1. 身份认证和权限校验

  2. 服务路由,负载均衡

  3. 请求限流

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UnWOqQqy-1662454500905)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662367865004.png)]

网关技术实现

  1. 两种实现方式
    1. gateway:基于spring5中提供能webflux,属于响应式实现,具备更好的性能
    2. zuul:基于servlet实现,属于阻塞式编程

搭建网关Gateway

  1. 创建新的module,引入依赖,之后创建启动类

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1f859mcU-1662454500905)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662368171100.png)]

  2. 编写路由配置及nacos地址

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jNzFAUIL-1662454500905)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662368541795.png)]

  3. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UuJ6AOn9-1662454500905)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662368779968.png)]

路由断言工厂Route Predicate Factory

  1. 网关路由可以配置的内容包括

    1. 路由id:路由唯一标示
    2. uri:路由目的地址,支持lb和http两种
    3. predicates:路由断言,判断请求是否符合要求,符合则要转发到路由目的地
    4. filters:路由过滤器,处理请求或响应
  2. 我们在配置文件中写的断言规则只是字符串,这些字符串会被Predicate Factory读取并处理,转变为路由判断的条件

  3. spring提供的断言工厂

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YziXsIpK-1662454500906)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662369803730.png)]

路由过滤器GatewayFilter

  1. GatewayFilter是网关中提供的一种过滤器,可以对进入网关的请求和微服务的响应做处理

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6SvF3abs-1662454500906)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662370112916.png)]

  2. 实现方式

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nR2TiRmA-1662454500906)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662370233572.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XFldI01M-1662454500906)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662370290676.png)]

默认过滤器

如果要对所有路由都生效,则可以将过滤器工厂写到default

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-54E5tCGv-1662454500907)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662370414637.png)]

全局过滤器

  1. 全局过滤器作用也是处理一切进入网关的请求和微服务响应,如GatewayFilter作用一样

  2. 区别在于GatewayFilter通过配置定义,处理逻辑是固定的。而GlobalFilter的逻辑需要自己写代码实现

  3. 定义方式是实现GlobalFilter接口

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tV6BhuiT-1662454500907)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662370742822.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-043vbq15-1662454500907)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662371042308.png)]

过滤器执行顺序

  1. 请求进入网关会碰到三类过滤器:当前路由过滤器、DefaultFilter、GlobalFilter

  2. 请求路由后,会将当前路由过滤器和DefaultFilter、GlobalFilter,合并到一个过滤器链(集合)中,排序后一次执行每个过滤器

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-db0TqnAu-1662454500907)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662371512354.png)]

  3. 每一个过滤器都必须指定一个int类型的order值,order值越小,优先级越高,执行顺序越靠前

  4. GlobalFilter通过实现Ordered接口,或者添加@Order注解来指定order值,由我们自己指定

  5. 路由过滤器和defalutFilter的order由Spring指定,默认是按照声明顺序从1递增

  6. 当过滤器的order值一样时,会按照defaultFilter>路由过滤器>GlobalFilter的顺序执行

跨域问题处理

  1. 跨域:域名不一致就是跨域,主要包括

    1. 域名不同
    2. 域名相同,端口不同
  2. 跨域问题:浏览器进制请求的发起者与服务端发生跨域Ajax请求,请求被浏览器拦截的问题

  3. 解决方案:COPS

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dlmj1aAw-1662454500908)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662372009201.png)]

Docker

初识Docker

Docker

  1. 项目部署问题

    大型项目组件较多,运行环境也较为复杂,部署时会遇到一些问题

    1. 依赖关系复杂,容易出现兼容性问题
    2. 开发、测试、生产环境有差异
    3. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sh3QCTqD-1662454500908)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662372433824.png)]
  2. Docker如何解决兼容性问题

    1. 将应用的Libs(函数库)、Deps(依赖)、配置与应用一起打包
    2. 将每个应用放到一个隔离容器去运行,避免互相干扰
    3. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-klRnahtd-1662454500908)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662372561513.png)]
    4. 操作系统的结构
      1. 内核与硬件交互,提供操作硬件的指令
      2. 系统应用封装啮合指令为函数,便于程序员调用
      3. 用户基于系统函数库实现功能
  3. 总结

    1. 解决大型项目依赖关系复杂,不同组件依赖的兼容性问题
      1. Docker允许开发中将应用,依赖,函数库,配置一起打包,形成可移植镜像
      2. Docker应用运行在容器中,使用沙箱机制,相互隔离
    2. Docker如何解决开发,测试,生产环境有差异的问题
      1. Docker镜像中包含完整运行环境,包括系统函数库,仅依赖系统的Linux内核,因此可以在任意Linux操作系统上运行
  4. Docker是一个快速交付,运行应用的技术

    1. 可以将程序及其依赖,运行环境一起打包成一个镜像,可以迁移到任何Linux操作系统
    2. 运行时利用沙箱机制形成隔离容器,各个应用互不干扰
    3. 启动,移除都可以通过一行命令完成,方便快捷

Docker与虚拟机

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9Kn6FNN4-1662454500908)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662376132485.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hbI0zlXK-1662454500909)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662376147189.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dlzks63A-1662454500909)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662376162668.png)]

  1. Docker是一个系统进程,虚拟机是在操作系统中的操作系统
  2. Docker体积小,启动速度快,性能好;虚拟机体积大,启动速读慢,性能一般

镜像和容器

  1. 镜像:Docker将应用程序及其所需要的依赖,含数据,环境,配置文件打包在一起,称为镜像
  2. 容器:镜像中的应用程序运行后形成的进程就是容器,只是Docker会给容器做隔离,对外不可见

Docker和DcokerHub

  1. DockerHub:Docker镜像的托管品台,这样的平台称为Docker Registry
  2. 国内也有类似于DockerHub的公开服务,比如网易云镜像服务,阿里云镜像库等

Docker架构

Docker是个CS架构的程序,由两部分组成

  1. 服务端:Docker守护进程,负责处理Docker指令,管理镜像,容器等
  2. 客户端:通过命令或RestAPI向Docker服务端发送指令,可以在本地或远程向服务端发送指令
  3. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8ZGijVuq-1662454500909)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662376942017.png)]

Docker安装

Docker基本操作

镜像相关命令

  1. 镜像名称一般分为两部分组成:[repository]:[tag]

  2. 在没有指定tag时,默认是latest,代表最新版本

  3. 常见命令

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fLYVxTkJ-1662454500909)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662377840703.png)]

容器相关命令

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JEvmoBTo-1662454500909)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662379036316.png)]

docker run常见命令参数
  1. –name:指定容器名称
  2. -p:指定端口映射
  3. -d:让容器后台运行
查看容器日志命令
  1. docker logs
  2. 添加-f参数可以持续查看日志
查看容器状态
  1. docker ps
  2. 添加-a参数查看所有状态的容器
删除容器
  1. docker rm
  2. 不能删除运行中容器,除非添加-f参数
进入容器
  1. 命令是docker exec -it [容器名] [要执行的命令]
  2. exce命令可以进入容器修改文件,但是在容器内修改文件是不推荐的

数据卷

容器与数据耦合的问题

  1. 不便于修改

    当我们要修改Nginx的html内容时,需要进入容器内部修改,很不方便

  2. 数据不可复用

    在容器内的修改对外是不可见的。所有修改对新创建的容器是不可复用的

  3. 升级维护困难

    数据在容器内,如果要升级容器必然删除容器,所有数据都跟着删除了

数据卷

  1. 是一个虚拟目录,直线宿主机文件系统中的摸个目录

  2. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eBbyFNDO-1662454500910)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662382657601.png)]

  3. 数据卷操作的基本语法

    docker volume [COMMAND]

    1. create 创建一个volume
    2. inspect 显示一个或多个volume信息
    3. ls 列出所有的volume
    4. prune 删除未使用的volume
    5. rm 删除一个或多个指定的volume

挂载数据卷

  1. 方式一:基于数据卷

    1. 我们在创建容器时,可以通过-v参数来挂在一个数据卷到某个容器目录
    2. 如果容器运行时volume不存在,会自动被创建出来
  2. 方式二:基于目录

    语法类似基于数据卷,将宿主机目录直接挂载到容器

  3. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x0xdMply-1662454500910)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662385192170.png)]

  4. 比较

    1. docker run的命令中通过-v参数直接挂载文件或目录到容器中
      1. -v volume名称:容器内目录
      2. -v 宿主机文件:容器内文件
      3. -v 宿主机目录:容器内目录
    2. 数据卷挂载与目录直接挂载的
      1. 数据卷挂载耦合度低,由docker来管理目录,但是目录较深,不好找
      2. 目录改在耦合度高,需要我们自己管理目录,不过目录容易寻找查看

DockerFile自定义镜像

  1. 镜像结构

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TnA88eln-1662454500910)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662385616525.png)]

  2. 镜像是分层结构,每一层称为一个Layer

    1. BaseImage层:包含基本的系统函数库,环境变量,文件系统
    2. Entrypoint:入口,是镜像中应用启动的命令
    3. 其他:在BaseImage基础上添加依赖,安装程序,完成整个应用的安装和配置
  3. 自定义镜像

DockerCompose

  1. 什么是DockerCompose

    基于Compose文件帮助我们快速地部署分布式应用,而无需手动一个个创建和运行容器

  2. Compose是一个文本文件,通过指令定义集群中每个容器如何运行

  3. 部署

    1. 新建运行文件,在其中编写docker-compose文件
    2. 修改项目的数据库,nacos地址都命名为docker-compose中服务名
    3. 使用maven打包工具,将项目中的每个微服务都打包为app.jar
    4. 将打包好的app.jar拷贝到运行中每一个对应的子目录中
    5. 将运行文件上传至虚拟机,利用docker-compose up -d来部署

Docker镜像仓库

  1. 常见镜像仓库

    1. 公共仓库,例如Docker官方的Docker Hub,国内也有一些云服务商提供类似于Docker Hub的公开服务,比如网易云镜像服务,DaoCloud镜像服务,阿里云镜像服务等
    2. 除了使用公开仓库外,用户还可以在本地搭建私有Docker Registry。企业直接的镜像最好是采用私有Docker Registry来实现
  2. 搭建镜像仓库

    1. 简化版镜像仓库
    2. 带有图形化界面版本
    3. 配置Docker信任地址
  3. 在私有镜像仓库推送或拉取镜像

    1. 重新tag(版本)本地镜像,名称前缀为私有仓库的地址:192.168.150.101:8080/

      docker tag nginx:latest 192.168.150.101:8080/nginx:1.0

    2. 推送镜像

      docker push 192.168.150.101:8080/nginx:1.0

    3. 拉取镜像

      docker pull 192.168.150.101:8080/nginx:1.0

  4. 总结

    1. 推送本地镜像到仓库前都必须重命名(docker tag)镜像,以镜像仓库地址为前缀
    2. 镜像仓库推送前需要把仓库地址配置到docker服务的daemon.json文件中,被docker信任
    3. 推送使用docker push命令
    4. 拉取使用docker pull命令

异步通讯技术

初识MQ

同步通讯和异步通讯

  1. 同步调用问题

    1. 优点:时效性强,可以立即得到结果

    2. 微服务间基于Feign的调用就属于同步方式,存在一些问题

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-enVsKK8f-1662454500910)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662431272981.png)]

      1. 耦合度高:每次加入新的需求,都要修改原来的代码
      2. 性能下降:调用者需要等待服务提供者响应,如果调用链过长则响应时间等于每次调用的时间之和
      3. 资源浪费:调用链中的每个服务在等待响应过程中,不能释放请求占用的资源,高并发场景下会极度浪费系统资源
      4. 级联失败:如果服务提供者出现问题,所有调用方都会跟着出现问题,如同多米诺骨牌一样,迅速到最后整个微服务群故障
  2. 异步调用方案

    1. 缺点

      1. 依赖于Broker的可靠性,安全性,吞吐能力
      2. 架构复杂,业务没有明显的流程线,不好追踪管理
    2. 异步调用常见的就是事件驱动模式

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pdNjMMDA-1662454500911)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662435580877.png)]

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-85g5QrY5-1662454500911)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662435772339.png)]

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BLqjKExo-1662454500911)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662435800209.png)]

      1. 服务解耦。耦合度低
      2. 性能提升。吞吐量提高
      3. 故障隔离,服务没有强依赖关系
      4. 流量削峰

什么是MQ

  1. MQ(MessageQueue),中文是消息队列,字面来看就是存放消息的队列,也就是时间驱动架构中的Broker
  2. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Fe8m2emb-1662454500911)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662436657241.png)]

RabbitMQ

介绍和安装

  1. 概述:基于Erlang语言开发的开源消息通信中间件

  2. 安装

    1. 方式一:在线拉取

      docker pull rabbitmq:3-management

    2. 方式二:本地加载

      本地镜像上传至虚拟机后,使用命令加载镜像即可

      docker load -i mq.tar

    3. 执行命令来运行MQ程序

  3. 结构和概念

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-najlxYnA-1662454500912)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662437495474.png)]

    1. channel:操作MQ的工具
    2. exchange:路由消息到队列中
    3. queue:缓存消息
    4. virtual host:虚拟主机,是对queue,恶心嫦娥等资源的逻辑分组

常见消息模型

  1. 基本消息队列(BasicQueue)

    只包括三个角色

    1. publisher:消息发布者,将消息发送到队列queue
    2. queue:消息队列,负责接收并缓存消息
    3. consumer:订阅队列,处理队列中的消息
    4. 消息发送流程
      1. 建立connection
      2. 创建channel
      3. 利用channel声明队列
      4. 利用channel向队列发送消息
    5. 基本消息接收流程
      1. 建立connecting
      2. 创建channel
      3. 利用channel声明队列
      4. 定义consumer的消费行为handleDelivery()
      5. 利用channel将消费者与队列绑定

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZYQ5XTlT-1662454500912)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662442773085.png)]

  2. 工作消息队列(WorkQueue)

    可以提高消息的处理速度,避免消息堆积

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qD9UmzxE-1662454500912)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662444909593.png)]

  3. 发布订阅(Public、Subscribe)

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JYwWazjg-1662454500912)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662445993804.png)]

    根据交换机类型不同分为三种

    1. 广播(Fanout Exchange)
    2. 路由(Direct Exchange)
    3. 话题(Topic Exchange)
    4. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jp9IpQB0-1662454500913)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662437930002.png)]

SpringAMQP

消息队列

  1. AMQP:Advanced Message Queuing Protocol,是用于在应用程序或之间传递业务消息的开发标准。该协议与语言和平台无关,更符合微服务中独立性的要求

  2. Spring AMQP:是基于AMQP协议定义的一套API规范,提供了模板来发送和接收消息。包含两部分,其中spring-amqp是基础抽象,spring-rabbit是底层默认实现

  3. 消息发送

    1. 在父工程中引入spring-amqp依赖

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k6mJsHv3-1662454500913)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662444038240.png)]

    2. 在publisher服务中利用RabbitTemplate发送消息到队列中

      1. 编写配置文件,添加RabbitMQ地址

        [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8Io5RPRk-1662454500913)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662444099415.png)]

      2. 新建测试类,利用convertAndSent()发送消息

        [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6zKxaWpc-1662454500913)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662444307511.png)]

    3. 在consumer服务中绑定消息队列

      1. 编写配置信息,添加mq连接消息

        [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qPcHEgc9-1662454500914)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662444434480.png)]

      2. 新建方法,编写消息方法

        [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pvbtmR7W-1662454500914)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662444486671.png)]

    4. 消息一旦消费就会从队列中删除,RabbitMQ没有消息回溯功能

Work Queue工作队列

  1. 多个消费者绑定到一个队列,同一条消息只会被一个消费者处理
  2. 消息预取限制
    1. 修改application.yml文件,设置preFetch这个值,可以控制预取消息上限
    2. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q0JrnQtz-1662454500914)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662445651260.png)]

FanoutExchange广播

  1. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zuDnptL6-1662454500914)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662446302081.png)]
  2. 步骤
    1. 在consumer服务声明Exchange,Queue,Binding
    2. 在consumer服务声明两个消费者
    3. 在publisher服务发送消息到FountExchange
  3. 交换机的作用
    1. 接收publisher发送的消息
    2. 将消息按照规则路由到与之绑定的消息队列
    3. 不能缓存消息,路由失败,消息丢失
    4. FanoutExchange的会将消息路由到每个绑定的队列
  4. 声明队列、交换机、绑定关系的Bean是什么
    1. Queue
    2. FanoutExchange
    3. Bingding

DirectExchange发布订阅

  1. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BvCea8v4-1662454500915)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662447402906.png)]

  2. 将接收到的消息根据规则路由到指定的Queue

    1. 每发一个Queue都与Exchange设置一个BindingKey
    2. 发布者发送消息时,指定消息的RoutingKey
    3. Exchange将消息路由到BingingKey与消息RoutingKey一致的队列
  3. 实现

    1. 在consumer服务声明Exchange,Queue
    2. 在publisher服务发送消息到DirectExchange
  4. Direct交换机与Fanout交换机的差异

    1. Fanout交换机将消息路由给每一个与之绑定的队列
    2. Direct交换机根据RoutingKey判断路由给哪个队列
    3. 如果多个对列具有相同的RoutingKey,则与Fanout功能类似
  5. 基于@RabbitListener注解声明队列和交换机有哪些常见注解

    1. @Queue
    2. @Exchange

TopicExchange发布订阅

  1. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8iZsSZKs-1662454500915)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662448462610.png)]
  2. 与DirectExchange类似,去呗在于routingKey必须是多个单词的列表,并且以 . 分割
  3. Queue与Exchange指定BingingKey时可以使用通配符
    1. #: 代指0个或多个单词
    2. *: 代指一个单词

消息转换器

  1. 在SpringAMQP的发送方法中,接收消息的类型是Object,也就是说我们可以发送任意对象类型的消息,SpringAMQP对帮我们序列化为字节后发送

  2. Spring的对象消息默认实现是基于ObjectOutputStream完成序列化的,如果要修改只需要定义一个MessageConverter类型的Bean即可,推荐使用JSON方式序列化

  3. 发送方和接收方必须使用相同的MessageConverter

  4. 步骤

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gImAqOgn-1662454500915)(C:\Users\fanvil\AppData\Roaming\Typora\typora-user-images\1662449316576.png)]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值