一、Sentinel 描叙

1、Sentinel作用

Sentinel,中文翻译为哨兵,是为微服务提供流量控制、熔断降级的功能,它和Hystrix提供的功能一样,可以有效的解决微服务调用产生的“雪崩”效应,为微服务系统提供了稳定性的解决方案。随着Hytrxi进入了维护期,不再提供新功能,Sentinel是一个不错的替代方案。通常情况,Hystrix采用线程池对服务的调用进行隔离,Sentinel才用了用户线程对接口进行隔离,二者相比,Hystrxi是服务级别的隔离,Sentinel提供了接口级别的隔离,Sentinel隔离级别更加精细,另外Sentinel直接使用用户线程进行限制,相比Hystrix的线程池隔离,减少了线程切换的开销。另外Sentinel的DashBoard提供了在线更改限流规则的配置,也更加的优化。

2、Sentinel 具有以下特征

从官方文档的介绍,Sentinel 具有以下特征:

丰富的应用场景: Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、实时熔断下游不可用应用等。
完备的实时监控: Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
广泛的开源生态: Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
完善的 SPI 扩展点: Sentinel 提供简单易用、完善的 SPI 扩展点。您可以通过实现扩展点,快速的定制逻辑。例如定制规则管理、适配数据源等。

3、如何在Spring Cloud中使用Sentinel

Sentinel的使用分为两部分:

sentinel-dashboard:与hystrix-dashboard类似,但是它更为强大一些。除了与hystrix-dashboard一样提供实时监控之外,还提供了流控规则、熔断规则的在线维护等功能。

客户端整合:每个微服务客户端都需要整合sentinel的客户端封装与配置,才能将监控信息上报给dashboard展示以及实时的更改限流或熔断规则等。

4、Sentinel 和 hytrix的区别

二、Sentinel 控制台 Sentinel DashBoard

Sentinel DashBoard
Sentinel 控制台提供一个轻量级的控制台,它提供机器发现、单机资源实时监控、集群资源汇总,以及规则管理的功能.

1、下载

Sentinel DashBoard下载地址:https://github.com/alibaba/Sentinel/releases
下载 jar 文件即可

2、启动

下载完成后,以以下的命令启动

java -jar sentinel-dashboard-1.6.1.jar

启动端口为8080,启动修改端口添加命令 -Dserver.port=8081

3、访问

访问:http://localhost:8080
默认账号密码:sentinel / sentinel

登录成功展示如下,默认没有任何内容的

其他启动指定:
-Dsentinel.dashboard.auth.username=sentinel: 用于指定控制台的登录用户名为 sentinel;
-Dsentinel.dashboard.auth.password=123456: 用于指定控制台的登录密码为 123456;如果省略这两个参数,默认用户和密码均为 sentinel
-Dserver.servlet.session.timeout=7200: 用于指定 Spring Boot 服务端 session 的过期时间,如 7200 表示 7200 秒;60m 表示 60 分钟,默认为 30 分钟;

三、springboot 整合 Sentinel

Sentinel 有两种配置方式
1、使用代码+注解配置(看7)
2、使用控制台配置(看6)

3.1、pom.xml 依赖

        <!-- sentinel --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId><version>0.9.0.RELEASE</version></dependency>

3.2、application.yml

  • 在工程的配置文件application.yml文件中配置,需要新增2个配置:
  • spring.cloud.sentinel.transport.port: 8719 ,这个端口配置会在应用对应的机器上启动一个 Http Server,该 Server 会与 Sentinel 控制台做交互。比如 Sentinel 控制台添加了1个限流规则,会把规则数据 push 给这个 Http Server 接收,Http Server 再将规则注册到 Sentinel 中。
  • spring.cloud.sentinel.transport.dashboard: 8080,这个是Sentinel DashBoard的地址。
##  在工程的配置文件application.yml文件中配置,需要新增2个配置:
##  spring.cloud.sentinel.transport.port: 8719 ,这个端口配置会在应用对应的机器上启动一个 Http Server,该 Server 会与 Sentinel 控制台做交互。比如 Sentinel 控制台添加了1个限流规则,会把规则数据 push 给这个 Http Server 接收,Http Server 再将规则注册到 Sentinel 中。
##  spring.cloud.sentinel.transport.dashboard: 8080,这个是Sentinel DashBoard的地址。server:port: 8090
spring:application:name: alibaba-alibaba-sentinelcloud:nacos:discovery:server-addr: 192.168.177.128:8848###  sentinel:transport:### 当前项目Http Server ip,主要主要是和Sentinel  的DashBoard控制台系统进行通讯port: 8719###  Sentinel 控制台DashBoard的地址dashboard: http://localhost:8080

3.4、测试接口1(指定方法,不介意,代码都在一个地方)

关于@SentinelResource注解最主要的两个用法:限流控制和熔断降级的具体使用案例介绍完了。另外,该注解还有一些其他更精细化的配置,比如忽略某些异常的配置、默认降级函数等等

package com.example.alibabasentinel.service;import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;/*** TODO  服务熔断/限流/降级(指定方法)* @author 王松* @mail  1720696548@qq.com* @date  2020/1/22 0022 20:35*/
@RestController
public class TestService1Impl {/*** TODO   测试方法(当前类处理-服务降级)*  getName :限流名称,控制台添加一定要选择该值,勿添加为 /getName 默认名,否则exceptionHandler  参数无效*  exceptionHandler : 服务限流降级后执行的方法*/@GetMapping("/getName")@SentinelResource(value = "getName", blockHandler = "exceptionHandler")public String getName() {return "wangsong";}/*** TODO   处理限流与阻塞(服务降级返回友好提示),方法名对应 blockHandler的参数,服务限流降级后执行的方法* */public String exceptionHandler(BlockException ex) {System.out.println("====" + ex);return "当前访问人数过多,请稍后再试";}
}

参考返回值:
1、当前访问人数过多,请稍后再试
2、正在排队中…

3.5、测试接口2(指定Handler类的方法)

添加测试方法

 package com.example.alibabasentinel.service;import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.example.alibabasentinel.handler.MyBlockHandlerClass;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/*** TODO   服务熔断/限流/降级(指定Handler类的方法)* @author 王松* @mail  1720696548@qq.com* @date  2020/1/22 0022 20:40 */
@RestController
public class TestService2Impl {/*** TODO    测试方法(指定Handler类处理-服务降级),blockHandlerClass = MyBlockHandlerClass.class*  getName :限流名称,控制台添加一定要选择该值,勿添加为 /getName2 默认名,否则exceptionHandler  参数无效*  blockHandlerClass :服务限流/异常等指定类执行降级方法*  blockHandler: 服务限流执行的降级方法*  fallback :  服务异常执行的降级方法*/@GetMapping("/getName2")@SentinelResource(value = "getName2", blockHandlerClass = MyBlockHandlerClass.class, blockHandler = "blockHandlerFunc", fallback = "fallbackFunc")public String getName2(String a) {return "wangsong2";}
}

添加 MyBlockHandlerClass 类 处理服务熔断降级

import com.alibaba.csp.sentinel.slots.block.BlockException;
import lombok.extern.slf4j.Slf4j;@Slf4j
public class MyBlockHandlerClass {// 处理限流与阻塞(服务降级返回友好提示)public static String blockHandlerFunc(String a, BlockException e){log.warn("限流了==="+a,e);return "当前访问人数过多,请稍后再试";}// 服务异常(降级处理)public static String fallbackFunc(String a){log.warn("异常==="+a);return "";}
}

3.6、控制台添加流控并测试

qbs:阈值 = 每秒能调用该接口多少次
线程数:阈值 = 请求最多有多少个线程池来处理(默认1)
项目启动后等一下下,控制台在会出现当前服务信息
先访问接口 /getName 几次,控制台才会出现该接口信息,

3.6.1、添加流控(接口到达阈值自动熔断)

getName = @SentinelResource注解的value 值,如果流控添加到 /getName ,将无法使用服务降级功能

添加流控qbs,设置阈值为2
qbs:阈值 = 每秒能调用该接口多少次
线程数:阈值 = 请求最多有多少个线程池来处理(默认1)

3.6.2、访问接口(服务降级)

正常访问接口返回响应数据,如当前:wangsong
到达阈值上限 ,返回:Blocked by Sentinel (flow limiting)

设置 blockHandle, 到达阈值上限,返回如下:
如:@SentinelResource(value=“getName”, blockHandler = “exceptionHandler”),

四、@SentinelResource 注解说明

注解key 支持版本 注解value 说明
value 资源名称,必需项(不能为空)
entryType entry 类型,可选项(默认为 EntryType.OUT)
blockHandler / blockHandlerClass blockHandler对应处理 BlockException 的函数名称,可选项。blockHandler 函数访问范围需要是public,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockException。blockHandler 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 blockHandlerClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析
fallback fallback 函数名称,可选项,用于在抛出异常的时候提供 fallback 处理逻辑。fallback 函数可以针对所有类型的异常(除了exceptionsToIgnore里面排除掉的异常类型)进行处理。fallback 函数签名和位置要求: 返回值类型必须与原函数返回值类型一致; 方法参数列表需要和原函数一致,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。fallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
defaultFallback since 1.6.0 :默认的 fallback 函数名称,可选项,通常用于通用的 fallback 逻辑(即可以用于很多服务或方法)。默认 fallback 函数可以针对所有类型的异常(除了exceptionsToIgnore里面排除掉的异常类型)进行处理。若同时配置了 fallback 和 defaultFallback,则只有 fallback 会生效。defaultFallback 函数签名要求:返回值类型必须与原函数返回值类型一致; 方法参数列表需要为空,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。
defaultFallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
exceptionsToIgnore since 1.6.0 用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。

五、java 代码手动添加流控配置

pom 依赖,yml配置,看 3.1, 3.2
定义限流的接口添加注解看 3.4, 3.5
测试看 3.6


// 流控接口
private static final String GETORDER_KEY = "getOrder";// 调用接口方式添加流控
@RequestMapping("/initFlowQpsRule")
public String initFlowQpsRule() {List<FlowRule> rules = new ArrayList<FlowRule>();FlowRule rule1 = new FlowRule();rule1.setResource(GETORDER_KEY);// 设置QPS控制在2以内rule1.setCount(1);// 限流规则QPSrule1.setGrade(RuleConstant.FLOW_GRADE_QPS);rule1.setLimitApp("default");rules.add(rule1);// 添加流控集FlowRuleManager.loadRules(rules);return "....限流配置初始化成功..";
}

六、Sentinel 数据持久化

1、pom.xml 依赖添加sentinel-datasource-nacos

        <!-- sentinel ,可需启动dashboard 查看配置 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId><version>0.9.0.RELEASE</version></dependency><!-- sentinel 数据持久化到nacos  --><dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasource-nacos</artifactId><version>1.5.2</version></dependency>

2、nacos 添加 sentinel 配置

创建服务对应的 sentinel 配置文件,使用 json

选择json,添加数据

[{"resource": "/hello","limitApp": "default","grade": 1,"count": 5,"strategy": 0,"controlBehavior": 0,"clusterMode": false}
]
  • resource:资源名,即限流规则的作用对象
  • limitApp:流控针对的调用来源,若为 default 则不区分调用来源
  • grade:限流阈值类型(QPS 或并发线程数);0代表根据并发数量来限流,1代表根据QPS来进行流量控制
  • count:限流阈值
  • strategy:调用关系限流策略
  • controlBehavior:流量控制效果(直接拒绝、Warm Up、匀速排队)
  • clusterMode:是否为集群模式
    这里我们只做简单的配置解释,以便于理解这里的配置作用。实际上这里还有非常多可配置选项和规则,更复杂的配置后面我们单独开一篇来深入学习。

3、application.yml 完整配置

#  在工程的配置文件application.yml文件中配置,需要新增2个配置:
#  spring.cloud.sentinel.transport.port: 8719 ,这个端口配置会在应用对应的机器上启动一个 Http Server,该 Server 会与 Sentinel 控制台做交互。比如 Sentinel 控制台添加了1个限流规则,会把规则数据 push 给这个 Http Server 接收,Http Server 再将规则注册到 Sentinel 中。
#  spring.cloud.sentinel.transport.dashboard: 8080,这个是Sentinel DashBoard的地址。
server:port: 8090
spring:application:name: spring-cloud-alibaba-sentinelcloud:### nacos 注册中心nacos:discovery:server-addr: 192.168.177.132:8848sentinel:### 和 Sentinel控制台DashBoard通讯,|| port:当前项目Http Server ip地址,|| dashboard:Sentinel 控制台DashBoard的地址transport:port: 8719dashboard: http://localhost:8080### 配置数据源,支持file本地,nacos,zk,阿波罗,配置数据库0,读取 nacos 配置数据datasource:ds0:nacos:server-addr: 192.168.177.132:8848dataId: spring-cloud-alibaba-sentinel.jsongroupId: DEFAULT_GROUPrule-type: flow  ### 文件类型    data-type: json

sentinel 部分

spring:cloud:sentinel:transport:port: 8719dashboard: http://localhost:8080datasource:ds0:nacos:server-addr: 192.168.177.132:8848dataId: spring-cloud-alibaba-sentinel.jsongroupId: DEFAULT_GROUPrule-type: flowdata-type: json

4、查看是否配置成功

启动项目发现启动日志: [Sentinel Starter] DataSource ds0-sentinel-nacos-datasource load 1 FlowRule
表示配置成功了

进入Sentinel 控制台–> 流控规则,发现已经存在配置规则了,配置成功

  • 1、如是重新启动项目, 访问任意接口在等待几秒刷新
  • 2、配置了nacos 尽量从来nacos 添加和修改规则,Sentinel 控制台修改的下次重新启动项目将失效

七、gateway 整合 Sentinel 实现服务限流

1、添加sentinel 限流核心配置

package com.gateway.sentinel;import com.alibaba.csp.sentinel.adapter.gateway.sc.SentinelGatewayFilter;
import com.alibaba.csp.sentinel.adapter.gateway.sc.exception.SentinelGatewayBlockExceptionHandler;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.web.reactive.result.view.ViewResolver;import java.util.Collections;
import java.util.List;
/*** TODO  sentinel 限流核心配置* @author ws* @mail  1720696548@qq.com* @date  2020/2/17 0017 14:08*/
@Configuration
public class GatewayConfiguration {private final List<ViewResolver> viewResolvers;private final ServerCodecConfigurer serverCodecConfigurer;public GatewayConfiguration(ObjectProvider<List<ViewResolver>> viewResolversProvider,ServerCodecConfigurer serverCodecConfigurer) {this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);this.serverCodecConfigurer = serverCodecConfigurer;}@Bean@Order(Ordered.HIGHEST_PRECEDENCE)public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {// Register the block exception handler for Spring Cloud Gateway.return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);}@Bean@Order(Ordered.HIGHEST_PRECEDENCE)public GlobalFilter sentinelGatewayFilter() {return new SentinelGatewayFilter();}}

2、添加sentinel 限流规则

此配置可以配置到nacos,动态配置限流规则

package com.gateway.sentinel;import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule;
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayRuleManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;import java.util.HashSet;
import java.util.Set;/*** TODO  限流规则配置** @author ws* @mail 1720696548@qq.com* @date 2020/2/17 0017 14:09*/
@Slf4j
@Component
public class SentinelApplicationRunner implements ApplicationRunner {@Overridepublic void run(ApplicationArguments args) throws Exception {initGatewayRules();}/*** 配置限流规则*/private void initGatewayRules() {Set<GatewayFlowRule> rules = new HashSet<>();rules.add(new GatewayFlowRule("test")// 限流阈值.setCount(1)// 统计时间窗口,单位是秒,默认是 1 秒.setIntervalSec(1));GatewayRuleManager.loadRules(rules);}
}

3、配置自定义返回信息(如果配置了全局异常看四)

package com.gateway.sentinel;import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.reactive.result.view.ViewResolver;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebExceptionHandler;
import reactor.core.publisher.Mono;import java.nio.charset.StandardCharsets;
import java.util.List;
/*** TODO  限流错误返回信息* @author ws* @mail  1720696548@qq.com* @date  2020/2/17 0017 14:13*/
public class JsonSentinelGatewayBlockExceptionHandler implements WebExceptionHandler {public JsonSentinelGatewayBlockExceptionHandler(List<ViewResolver> viewResolvers, ServerCodecConfigurer serverCodecConfigurer) {}@Overridepublic Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {ServerHttpResponse serverHttpResponse = exchange.getResponse();serverHttpResponse.getHeaders().add("Content-Type", "application/json;charset=UTF-8");byte[] datas = "{\"code\":403,\"msg\":\"API接口被限流\"}".getBytes(StandardCharsets.UTF_8);DataBuffer buffer = serverHttpResponse.bufferFactory().wrap(datas);return serverHttpResponse.writeWith(Mono.just(buffer));}}

4、全局异常返回自定义信息

全局异常配置暂不做说明

本文参考文章1:https://blog.csdn.net/u013184307/article/details/95973022
本文参考文章2:https://blog.csdn.net/a772304419/article/details/99689562
数据持久化参考:http://blog.didispace.com/spring-cloud-alibaba-sentinel-2-1/

创作不易感谢大家的观看!

SpringCloudAlibaba 六、Sentinel 服务保护 ( 服务降级/ 熔断/ 数据持久化 / gateway 整合 Sentinel )相关推荐

  1. 微服务之Hystrix降级熔断

    前言 分布式系统面临的问题-----服务雪崩 多个微服务之间调用的时候,假设微服务A调用微服务B和微服务C,微服务B和微服务C又调用其它的微服务,这就是所谓的"扇出".如果扇出的链 ...

  2. Spring Cloud Alibaba 实战 | 第十二篇: 微服务整合Sentinel的流控、熔断降级,赋能拥有降级功能的Feign新技能熔断,实现熔断降级双剑合璧(JMeter模拟测试)

    文章目录 一. Sentinel概念 1. 什么是Sentinel? 2. Sentinel功能特性 3. Sentinel VS Hystrix 二. Docker部署Sentinel Dashbo ...

  3. 服务熔断与限流:Sentinel

    目录 第一章 Sentinel的介绍 1.1.Sentinel是什么 1.2.Sentinel的特性 1.3.Sentinel的对比 第二章 Sentinel的安装与运行 2.1.下载Sentinel ...

  4. 【云原生微服务>SCG网关篇十二】Spring Cloud Gateway集成Sentinel API实现多种限流方式

    文章目录 一.前言 二.Gateway集成Sentinel API 0.集成Sentinel的核心概念 1)GatewayFlowRule 和 ApiDefinition 2)GatewayFlowR ...

  5. Sentinel动态推拉数据持久化同步到Nacos

    前言 在我们使用Sentinel做熔断限流等操作时,一些设置好的配置默认是存放在当前服的内存中的,那么也就意味着每次重启服务,这些配置好的配置就会消失.在我们搭建微服务架构做测试的时候不是很友好.大家 ...

  6. Spring Cloud Gateway 整合阿里 Sentinel网关限流实战!

    前一篇文章介绍了Spring Cloud Gateway的一些基础知识点,今天陈某就来唠一唠网关层面如何做限流? 文章目录如下: 网关如何限流? Spring Cloud Gateway本身自带的限流 ...

  7. Spring Cloud Gateway 整合阿里 Sentinel网关限流实战

    文章目录如下: 网关如何限流? Spring Cloud Gateway本身自带的限流实现,过滤器是RequestRateLimiterGatewayFilterFactory,不过这种上不了台面的就 ...

  8. 通过Dapr实现一个简单的基于.net的微服务电商系统(十六)——dapr+sentinel中间件实现服务保护...

    dapr目前更新到了1.2版本,在之前4月份的时候来自阿里的开发工程师发起了一个dapr集成Alibaba Sentinel的提案,很快被社区加入到了1.2的里程碑中并且在1.2 release 相关 ...

  9. 【微服务】服务熔断降级 Sentinel

    目录 高并发带来的问题 结论: 服务器雪崩效应 常见容错方案 隔离机制: 超时机制 限流机制 熔断机制: 降级机制 常见的容错组件 Sentinel入门 什么是Sentinel 订单微服务集成Sent ...

最新文章

  1. 《动手学数据分析》开源教程完整发布!
  2. LeetCode 204. Count Primes--从一开始的质数个数--Python解法--面试算法题
  3. Matlab出现On Startup: Error using eval undefined function 'workspacefunc' for input arguments of type
  4. Win10如何设置IE为默认浏览器
  5. php k线图粒度计算,【k线】k线图中MA均线计算
  6. 巨人网络305亿并购海外棋牌类游戏公司审核遭暂停
  7. MVC之在实例中的应用
  8. linux安装kafka_巨杉Tech | 基于Kafka+Spark+SequoiaDB实时处理架构快速实战
  9. 2020系统架构设计师考试通过率,软件资格证书正在发生深刻历史变化
  10. doapk java环境_关于有的Apk无法反编译的探究
  11. 刨根究底字符编码之一——关键术语解释(上)
  12. python百钱买百鸡问题答案_Python学习-算法-百钱买百鸡的问题
  13. mmorpg小地图系统制作
  14. 奉上——手机版个人财务管理软件
  15. 解决重邮无法访问蓝鸽听力以及无法访问部分内网的解决方法
  16. 基于Visual C 2010开发Windows7应用 多点触摸图片处理应用程序 1 同时处理多张图片
  17. Eclipse 删除工作空间的记录
  18. 数组元素作为函数参数
  19. Jq实现刷新页面更换广告的简单效果
  20. 《李开复:人工智能十讲》

热门文章

  1. CAD图中如何插入Excel表格?
  2. 魔术里的集合、映射和关系(七)——情怀之作《连环预言》的魔术魅力
  3. 气象业务数据格式的介绍
  4. [转]logXX对所有的X0成立
  5. 使用Nuxt.js搭建VUE应用的SSR(服务端渲染)
  6. discuz7.2漏洞复现--python编写poc
  7. 无声的AI:昇腾AI如何用大模型破解手语学习的难题?
  8. c++——string的模拟实现
  9. 怎样测试电脑电源好坏
  10. 使用OpenFiler来模拟存储配置RAC中ASM共享盘及多路径(multipath)的测试