hystrix 的相关代码学习1
parent
6d01440d3f
commit
70b0eb3cbe
@ -1,29 +0,0 @@
|
|||||||
## SpringCloud Netflix Hystrix
|
|
||||||
|
|
||||||
|
|
||||||
### SpringCloud Netflix Hystrix 概览
|
|
||||||
|
|
||||||
|
|
||||||
### 使用注解方式实现服务的容错、降级
|
|
||||||
|
|
||||||
|
|
||||||
### 使用编程方式实现服务的容错、降级
|
|
||||||
|
|
||||||
|
|
||||||
### 编程方式开启 Hystrix 请求缓存
|
|
||||||
|
|
||||||
|
|
||||||
### 注解方式开启 Hystrix 请求缓存
|
|
||||||
|
|
||||||
|
|
||||||
### 编程方式应用 Hystrix 请求合并
|
|
||||||
|
|
||||||
|
|
||||||
### 注解方式应用 Hystrix 请求合并
|
|
||||||
|
|
||||||
### OpenFeign 集成 Hystrix 开启后备模式
|
|
||||||
|
|
||||||
|
|
||||||
### 使用 Hystrix 监控面板监测客户端容错
|
|
||||||
|
|
||||||
### SpringCloud Netflix Hystrix 容错组件总结
|
|
@ -0,0 +1,38 @@
|
|||||||
|
target/
|
||||||
|
!.mvn/wrapper/maven-wrapper.jar
|
||||||
|
!**/src/main/**/target/
|
||||||
|
!**/src/test/**/target/
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea/modules.xml
|
||||||
|
.idea/jarRepositories.xml
|
||||||
|
.idea/compiler.xml
|
||||||
|
.idea/libraries/
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
|
||||||
|
### Eclipse ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
build/
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
### Mac OS ###
|
||||||
|
.DS_Store
|
@ -0,0 +1,45 @@
|
|||||||
|
## SpringCloud Netflix Hystrix
|
||||||
|
|
||||||
|
|
||||||
|
### SpringCloud Netflix Hystrix 概览
|
||||||
|
- Hystrix 是什么、设计目标是什么
|
||||||
|
- Hystrix 是一个库,通过添加延迟容忍和容错逻辑,帮助你控制这些分布式服务之间的交互
|
||||||
|
- Hystrix 通过隔离服务之间的访问点、停止级联失败和提供回退选项来实现服务之间的容错
|
||||||
|
- Hystrix 有四大设计目标
|
||||||
|
- 对客户端访问的延迟和故障进行保护和控制
|
||||||
|
- 在复杂的分布式系统中阻止级联故障
|
||||||
|
- 快速失败,快速恢复
|
||||||
|
- 兜底回退,尽可能优雅的降级
|
||||||
|
---
|
||||||
|
- Hystrix 解决了什么问题
|
||||||
|
- 复杂分布式系统中服务之间存在许多依赖项,依赖项可能会存在故障,如果不做故障隔离整个服务可能会被拖垮
|
||||||
|
---
|
||||||
|
- Hystrix 是如何实现它的目标的
|
||||||
|
- 对依赖项(服务)进行包装代理,不直接与依赖项交互
|
||||||
|
- 调用超时时间允许自行设定,超时之后立刻熔断报错
|
||||||
|
- 每一个依赖项都在自己的空间内(线程池或信号量隔离),依赖项之间不存在干扰
|
||||||
|
- 请求依赖项失败后,可以选择出错或者是兜底回退
|
||||||
|
|
||||||
|
### 使用注解方式实现服务的容错、降级
|
||||||
|
|
||||||
|
|
||||||
|
### 使用编程方式实现服务的容错、降级
|
||||||
|
|
||||||
|
|
||||||
|
### 编程方式开启 Hystrix 请求缓存
|
||||||
|
|
||||||
|
|
||||||
|
### 注解方式开启 Hystrix 请求缓存
|
||||||
|
|
||||||
|
|
||||||
|
### 编程方式应用 Hystrix 请求合并
|
||||||
|
|
||||||
|
|
||||||
|
### 注解方式应用 Hystrix 请求合并
|
||||||
|
|
||||||
|
### OpenFeign 集成 Hystrix 开启后备模式
|
||||||
|
|
||||||
|
|
||||||
|
### 使用 Hystrix 监控面板监测客户端容错
|
||||||
|
|
||||||
|
### SpringCloud Netflix Hystrix 容错组件总结
|
@ -0,0 +1,17 @@
|
|||||||
|
package org.example;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
|
||||||
|
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||||
|
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
@EnableDiscoveryClient
|
||||||
|
@RefreshScope // 刷新配置
|
||||||
|
@EnableCircuitBreaker // 启动 Hystrix
|
||||||
|
public class HystrixApplication {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(HystrixApplication.class, args);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package org.example.controller;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.example.hystrix.UseHystrixCommandAnnotation;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.cloud.client.ServiceInstance;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h1>Hystrix Controller</h1>
|
||||||
|
* */
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/hystrix")
|
||||||
|
public class HystrixController {
|
||||||
|
|
||||||
|
private final UseHystrixCommandAnnotation hystrixCommandAnnotation;
|
||||||
|
|
||||||
|
public HystrixController(UseHystrixCommandAnnotation useHystrixCommandAnnotation) {
|
||||||
|
this.hystrixCommandAnnotation = useHystrixCommandAnnotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试使用注解的方式, 1500ms 是否会进行熔断 -> 关联http测试脚本
|
||||||
|
*/
|
||||||
|
@GetMapping("/hystrix-command-annotation")
|
||||||
|
public List<ServiceInstance> getNacosClientInfoUseAnnotation(
|
||||||
|
@RequestParam String serviceId) {
|
||||||
|
log.info("request nacos client info use annotation: [{}], [{}]",
|
||||||
|
serviceId, Thread.currentThread().getName());
|
||||||
|
return hystrixCommandAnnotation.getNacosClientInfo(serviceId);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
package org.example.hystrix;
|
||||||
|
|
||||||
|
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
|
||||||
|
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.example.service.NacosClientService4HystrixDemo;
|
||||||
|
import org.springframework.cloud.client.ServiceInstance;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h1>使用 HystrixCommand 注解</h1>
|
||||||
|
* */
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class UseHystrixCommandAnnotation {
|
||||||
|
private final NacosClientService4HystrixDemo nacosClientService4HystrixDemo;
|
||||||
|
|
||||||
|
public UseHystrixCommandAnnotation(NacosClientService4HystrixDemo nacosClientService4HystrixDemo) {
|
||||||
|
this.nacosClientService4HystrixDemo = nacosClientService4HystrixDemo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@HystrixCommand(
|
||||||
|
// 用于对 Hystrix 命令进行分组, 分组之后便于统计展示于仪表盘、上传报告和预警等等
|
||||||
|
// 内部进行度量统计时候的分组标识, 数据上报和统计的最小维度就是 groupKey
|
||||||
|
groupKey = "NacosClientService",
|
||||||
|
// HystrixCommand 的名字, 默认是当前类的名字, 主要方便 Hystrix 进行监控、报警等
|
||||||
|
commandKey = "NacosClientService",
|
||||||
|
// 舱壁模式
|
||||||
|
threadPoolKey = "NacosClientService",
|
||||||
|
// 后备模式 - 一定要写在当前类中, 要不不生效
|
||||||
|
fallbackMethod = "getNacosClientInfoFallback",
|
||||||
|
// 断路器模式
|
||||||
|
commandProperties = {
|
||||||
|
// 超时时间, 单位毫秒, 超时进 fallback
|
||||||
|
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1500"),
|
||||||
|
// 判断熔断的最少请求数, 默认是10; 只有在一定时间内请求数量达到该值, 才会进行成功率的计算
|
||||||
|
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),
|
||||||
|
// 熔断的阈值默认值 50, 表示在一定时间内有50%的请求处理失败, 会触发熔断
|
||||||
|
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "10"),
|
||||||
|
},
|
||||||
|
// 舱壁模式
|
||||||
|
threadPoolProperties = {
|
||||||
|
@HystrixProperty(name = "coreSize", value = "30"),
|
||||||
|
@HystrixProperty(name = "maxQueueSize", value = "101"),
|
||||||
|
@HystrixProperty(name = "keepAliveTimeMinutes", value = "2"),
|
||||||
|
@HystrixProperty(name = "queueSizeRejectionThreshold", value = "15"),
|
||||||
|
// 在时间窗口中, 收集统计信息的次数; 在 1440ms 的窗口中一共统计 12 次
|
||||||
|
@HystrixProperty(name = "metrics.rollingStats.numBuckets", value = "12"),
|
||||||
|
// 时间窗口, 从监听到第一次失败开始计时
|
||||||
|
@HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "1440")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public List<ServiceInstance> getNacosClientInfo(String serviceId) {
|
||||||
|
|
||||||
|
log.info("use hystrix command annotation to get nacos client info: [{}], [{}]",
|
||||||
|
serviceId, Thread.currentThread().getName());
|
||||||
|
return nacosClientService4HystrixDemo.getNacosClientInfo(serviceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h2>getNacosClientInfo 的兜底策略 - Hystrix 后备模式</h2>
|
||||||
|
* */
|
||||||
|
public List<ServiceInstance> getNacosClientInfoFallback(String serviceId) {
|
||||||
|
|
||||||
|
log.warn("can not get nacos client, trigger hystrix fallback: [{}], [{}]",
|
||||||
|
serviceId, Thread.currentThread().getName());
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package org.example.service;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.cloud.client.ServiceInstance;
|
||||||
|
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class NacosClientService4HystrixDemo {
|
||||||
|
|
||||||
|
private final DiscoveryClient discoveryClient;
|
||||||
|
|
||||||
|
public NacosClientService4HystrixDemo(DiscoveryClient discoveryClient) {
|
||||||
|
this.discoveryClient = discoveryClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <h2>打印 Nacos Client 信息到日志中</h2>
|
||||||
|
* */
|
||||||
|
public List<ServiceInstance> getNacosClientInfo(String serviceId) {
|
||||||
|
|
||||||
|
// 测试 UseHystrixCommandAnnotation 的超时
|
||||||
|
try {
|
||||||
|
Thread.sleep(2000);
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 测试 NacosClientHystrixCommand 熔断
|
||||||
|
// throw new RuntimeException("has some error");
|
||||||
|
|
||||||
|
log.info("request nacos client to get service instance info: [{}]", serviceId);
|
||||||
|
return discoveryClient.getInstances(serviceId);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
server:
|
||||||
|
port: 8111
|
||||||
|
servlet:
|
||||||
|
context-path: /dev-protocol-springcloud-hystrix
|
||||||
|
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: dev-protocol-springcloud-hystrix # 应用名称也是构成 Nacos 配置管理 dataId 字段的一部分 (当 config.prefix 为空时)
|
||||||
|
cloud:
|
||||||
|
nacos:
|
||||||
|
# 服务注册发现
|
||||||
|
discovery:
|
||||||
|
enabled: true # 如果不想使用 Nacos 进行服务注册和发现, 设置为 false 即可
|
||||||
|
server-addr: 127.0.0.1:8848
|
||||||
|
# server-addr: 127.0.0.1:8848,127.0.0.1:8849,127.0.0.1:8850 # Nacos 服务器地址
|
||||||
|
namespace: 1ccc74ae-9398-4dbe-b9d7-4f9addf9f40c
|
||||||
|
metadata:
|
||||||
|
management:
|
||||||
|
context-path: ${server.servlet.context-path}/actuator
|
||||||
|
# 配置管理
|
||||||
|
# config:
|
||||||
|
# prefix: imooc-e-commerce
|
||||||
|
# file-extension: yaml # 配置内容的数据格式, 默认为 properties
|
||||||
|
# enabled: true # 如果不想使用 Nacos 进行配置管理, 设置为 false 即可
|
||||||
|
# group: DEFAULT_GROUP # 组, 默认为 DEFAULT_GROUP
|
||||||
|
# namespace: 1ccc74ae-9398-4dbe-b9d7-4f9addf9f40c
|
||||||
|
# server-addr: 127.0.0.1:8848
|
||||||
|
kafka:
|
||||||
|
bootstrap-servers: 127.0.0.1:9092
|
||||||
|
producer:
|
||||||
|
retries: 3
|
||||||
|
consumer:
|
||||||
|
auto-offset-reset: latest
|
||||||
|
sleuth:
|
||||||
|
sampler:
|
||||||
|
# ProbabilityBasedSampler 抽样策略
|
||||||
|
probability: 1.0 # 采样比例, 1.0 表示 100%, 默认是 0.1
|
||||||
|
# RateLimitingSampler 抽样策略, 设置了限速采集, spring.sleuth.sampler.probability 属性值无效
|
||||||
|
rate: 100 # 每秒间隔接受的 trace 量
|
||||||
|
zipkin:
|
||||||
|
sender:
|
||||||
|
type: kafka # 默认是 web
|
||||||
|
base-url: http://localhost:9411/
|
||||||
|
|
||||||
|
# Feign 的相关配置
|
||||||
|
feign:
|
||||||
|
# feign 开启 gzip 压缩
|
||||||
|
compression:
|
||||||
|
request:
|
||||||
|
enabled: true
|
||||||
|
mime-types: text/xml,application/xml,application/json
|
||||||
|
min-request-size: 1024
|
||||||
|
response:
|
||||||
|
enabled: true
|
||||||
|
# 禁用默认的 http, 启用 okhttp
|
||||||
|
httpclient:
|
||||||
|
enabled: false
|
||||||
|
okhttp:
|
||||||
|
enabled: true
|
||||||
|
# OpenFeign 集成 Hystrix
|
||||||
|
hystrix:
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
# 暴露端点
|
||||||
|
management:
|
||||||
|
endpoints:
|
||||||
|
web:
|
||||||
|
exposure:
|
||||||
|
include: '*'
|
||||||
|
endpoint:
|
||||||
|
health:
|
||||||
|
show-details: always
|
@ -0,0 +1,58 @@
|
|||||||
|
### 获取 Token
|
||||||
|
POST http://127.0.0.1:8000/ecommerce-nacos-client/communication/rest-template
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"username": "Qinyi@imooc.com",
|
||||||
|
"password": "25d55ad283aa400af464c76d713c07ad"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
### 获取 Token, 带有负载均衡
|
||||||
|
POST http://127.0.0.1:8000/ecommerce-nacos-client/communication/rest-template-load-balancer
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"username": "Qinyi@imooc.com",
|
||||||
|
"password": "25d55ad283aa400af464c76d713c07ad"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
### 通过 Ribbon 去获取 Token
|
||||||
|
POST http://127.0.0.1:8000/ecommerce-nacos-client/communication/ribbon
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"username": "Qinyi@imooc.com",
|
||||||
|
"password": "25d55ad283aa400af464c76d713c07ad"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
### 通过原生 Ribbon Api 去获取 Token
|
||||||
|
POST http://127.0.0.1:8000/ecommerce-nacos-client/communication/thinking-in-ribbon
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"username": "Qinyi@imooc.com",
|
||||||
|
"password": "25d55ad283aa400af464c76d713c07ad"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
### 通过 OpenFeign 获取 Token
|
||||||
|
POST http://127.0.0.1:8000/ecommerce-nacos-client/communication/token-by-feign
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"username": "Qinyi@imooc.com",
|
||||||
|
"password": "25d55ad283aa400af464c76d713c07ad"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
### 通过原生 Feign Api 获取 Token
|
||||||
|
POST http://127.0.0.1:8000/ecommerce-nacos-client/communication/thinking-in-feign
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"username": "Qinyi@imooc.com",
|
||||||
|
"password": "25d55ad283aa400af464c76d713c07ad"
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
### 根据提供的 serviceId 获取实例信息
|
||||||
|
GET http://127.0.0.1:8000/dev-protocol-springcloud-hystrix/hystrix/hystrix-command-annotation?serviceId=e-commerce-nacos-client
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
### 根据提供的 serviceId 获取实例信息
|
||||||
|
GET http://127.0.0.1:8000/dev-protocol-springcloud-hystrix/hystrix/simple-hystrix-command?serviceId=e-commerce-nacos-client
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
### 根据提供的 serviceId 获取实例信息
|
||||||
|
GET http://127.0.0.1:8000/dev-protocol-springcloud-hystrix/hystrix/hystrix-observable-command?serviceId=e-commerce-nacos-client
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
### 根据提供的 serviceId 获取实例信息
|
||||||
|
GET http://127.0.0.1:8000/dev-protocol-springcloud-hystrix/hystrix/cache-hystrix-command?serviceId=e-commerce-nacos-client
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
### 根据提供的 serviceId 获取实例信息
|
||||||
|
GET http://127.0.0.1:8000/dev-protocol-springcloud-hystrix/hystrix/cache-annotation-01?serviceId=e-commerce-nacos-client
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
### 根据提供的 serviceId 获取实例信息
|
||||||
|
GET http://127.0.0.1:8000/dev-protocol-springcloud-hystrix/hystrix/cache-annotation-02?serviceId=e-commerce-nacos-client
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
### 根据提供的 serviceId 获取实例信息
|
||||||
|
GET http://127.0.0.1:8000/dev-protocol-springcloud-hystrix/hystrix/cache-annotation-03?serviceId=e-commerce-nacos-client
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
### 根据提供的 serviceId 获取实例信息
|
||||||
|
GET http://127.0.0.1:8000/dev-protocol-springcloud-hystrix/hystrix/request-merge
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
### 根据提供的 serviceId 获取实例信息
|
||||||
|
GET http://127.0.0.1:8000/dev-protocol-springcloud-hystrix/hystrix/request-merge-annotation
|
||||||
|
Content-Type: application/json
|
@ -0,0 +1,13 @@
|
|||||||
|
### 查询服务实例信息
|
||||||
|
GET http://127.0.0.1:8000/ecommerce-nacos-client/nacos-client/service-instance
|
||||||
|
Accept: application/json
|
||||||
|
|
||||||
|
### 动态从 Nacos Server 中获取配置信息
|
||||||
|
GET http://127.0.0.1:8000/ecommerce-nacos-client/nacos-client/project-config
|
||||||
|
Accept: application/json
|
||||||
|
|
||||||
|
### 查看 Sleuth 跟踪信息
|
||||||
|
GET http://127.0.0.1:9001/imooc/ecommerce-nacos-client/sleuth/trace-info
|
||||||
|
Accept: application/json
|
||||||
|
e-commerce-user: eyJhbGciOiJSUzI1NiJ9.eyJlLWNvbW1lcmNlLXVzZXIiOiJ7XCJpZFwiOjE3LFwidXNlcm5hbWVcIjpcIkltb29jUWlueWlAaW1vb2MuY29tXCJ9IiwianRpIjoiMGIxNzQyYWItMWU3OC00OTZjLWIyNTAtMjNkZGQ1ZGEyZTU1IiwiZXhwIjoxNjI0MjA0ODAwfQ.QKGHzohSHdYDHzUVHpe9gNPUgzfkPwrSbB-WiMWYjLlt2tr9BufzZM8bSt-whb_bd0hKoC6rkYYO0WUVR67uSML-2yaTL1xMIn8GH9Flyig3rpO4vefL3Hp2TXIpwHHa7WlKsLzcUpNk9lxWs2B5k0ICdYCH_jD5Tx6N7CzfSUG9u4fOnVeM9UFE2nX_DURupUh_DKCc2oOoMeyCSR7Ma8-Ab4WQU3r-U0YivR8G1A0kmKOIoTeRhM3LcPuxUPh3rCbrjzMg--fexRGw0O38Qsby6pz-ku2IlTyFXY6_jNOG1BZR34-jBOnaIciP1TExw9bFumeuC2GcowTHJVH1Nw
|
||||||
|
token: imooc
|
Loading…
Reference in New Issue