sentinel 使用说明

相关依赖

        <!-- sentinel starter --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency><!-- dubbo限流适配器 --><dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-apache-dubbo-adapter</artifactId></dependency><!-- sentinel规则存储 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-sentinel-datasource</artifactId></dependency><!-- sentinel网关限流 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId></dependency>

自动配置类

spring-cloud-starter-alibaba-sentinel/spring.factories

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.alibaba.cloud.sentinel.SentinelWebAutoConfiguration,\
com.alibaba.cloud.sentinel.SentinelWebFluxAutoConfiguration,\
com.alibaba.cloud.sentinel.endpoint.SentinelEndpointAutoConfiguration,\
com.alibaba.cloud.sentinel.custom.SentinelAutoConfiguration,\
com.alibaba.cloud.sentinel.feign.SentinelFeignAutoConfigurationorg.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker=\
com.alibaba.cloud.sentinel.custom.SentinelCircuitBreakerConfiguration

SentinelAutoConfiguration

@Configuration(proxyBeanMethods = false
)
@ConditionalOnProperty(name = {"spring.cloud.sentinel.enabled"},matchIfMissing = true
)
@EnableConfigurationProperties({SentinelProperties.class})  //从配置文件中读取数据,装配SentinelProperties类
public class SentinelAutoConfiguration {@Value("${project.name:${spring.application.name:}}")private String projectName;@Autowiredprivate SentinelProperties properties;public SentinelAutoConfiguration() {}@PostConstructprivate void init() {   //初始化属性配置if (StringUtils.isEmpty(System.getProperty("csp.sentinel.log.dir")) && StringUtils.hasText(this.properties.getLog().getDir())) {System.setProperty("csp.sentinel.log.dir", this.properties.getLog().getDir());}if (StringUtils.isEmpty(System.getProperty("csp.sentinel.log.use.pid")) && this.properties.getLog().isSwitchPid()) {System.setProperty("csp.sentinel.log.use.pid", String.valueOf(this.properties.getLog().isSwitchPid()));}if (StringUtils.isEmpty(System.getProperty("csp.sentinel.app.name")) && StringUtils.hasText(this.projectName)) {System.setProperty("csp.sentinel.app.name", this.projectName);}if (StringUtils.isEmpty(System.getProperty("csp.sentinel.api.port")) && StringUtils.hasText(this.properties.getTransport().getPort())) {System.setProperty("csp.sentinel.api.port", this.properties.getTransport().getPort());}if (StringUtils.isEmpty(System.getProperty("csp.sentinel.dashboard.server")) && StringUtils.hasText(this.properties.getTransport().getDashboard())) {System.setProperty("csp.sentinel.dashboard.server", this.properties.getTransport().getDashboard());}if (StringUtils.isEmpty(System.getProperty("csp.sentinel.heartbeat.interval.ms")) && StringUtils.hasText(this.properties.getTransport().getHeartbeatIntervalMs())) {System.setProperty("csp.sentinel.heartbeat.interval.ms", this.properties.getTransport().getHeartbeatIntervalMs());}if (StringUtils.isEmpty(System.getProperty("csp.sentinel.heartbeat.client.ip")) && StringUtils.hasText(this.properties.getTransport().getClientIp())) {System.setProperty("csp.sentinel.heartbeat.client.ip", this.properties.getTransport().getClientIp());}if (StringUtils.isEmpty(System.getProperty("csp.sentinel.charset")) && StringUtils.hasText(this.properties.getMetric().getCharset())) {System.setProperty("csp.sentinel.charset", this.properties.getMetric().getCharset());}if (StringUtils.isEmpty(System.getProperty("csp.sentinel.metric.file.single.size")) && StringUtils.hasText(this.properties.getMetric().getFileSingleSize())) {System.setProperty("csp.sentinel.metric.file.single.size", this.properties.getMetric().getFileSingleSize());}if (StringUtils.isEmpty(System.getProperty("csp.sentinel.metric.file.total.count")) && StringUtils.hasText(this.properties.getMetric().getFileTotalCount())) {System.setProperty("csp.sentinel.metric.file.total.count", this.properties.getMetric().getFileTotalCount());}if (StringUtils.isEmpty(System.getProperty("csp.sentinel.flow.cold.factor")) && StringUtils.hasText(this.properties.getFlow().getColdFactor())) {System.setProperty("csp.sentinel.flow.cold.factor", this.properties.getFlow().getColdFactor());}if (StringUtils.hasText(this.properties.getBlockPage())) {SentinelConfig.setConfig("csp.sentinel.web.servlet.block.page", this.properties.getBlockPage());}if (this.properties.isEager()) {InitExecutor.doInit();}}@Bean@ConditionalOnMissingBeanpublic SentinelResourceAspect sentinelResourceAspect() {return new SentinelResourceAspect();}@Bean@ConditionalOnMissingBean@ConditionalOnClass(name = {"org.springframework.web.client.RestTemplate"})@ConditionalOnProperty(name = {"resttemplate.sentinel.enabled"},havingValue = "true",matchIfMissing = true)public SentinelBeanPostProcessor sentinelBeanPostProcessor(ApplicationContext applicationContext) {return new SentinelBeanPostProcessor(applicationContext);}   //处理@SentinelRestTemplate@Bean@ConditionalOnMissingBeanpublic SentinelDataSourceHandler sentinelDataSourceHandler(DefaultListableBeanFactory beanFactory, SentinelProperties sentinelProperties, Environment env) {return new SentinelDataSourceHandler(beanFactory, sentinelProperties, env);}   //sentinel规则数据源处理@ConditionalOnClass({ObjectMapper.class})@Configuration(proxyBeanMethods = false)protected static class SentinelConverterConfiguration {protected SentinelConverterConfiguration() {}@ConditionalOnClass({XmlMapper.class})@Configuration(proxyBeanMethods = false)protected static class SentinelXmlConfiguration {  //解析xml格式规则private XmlMapper xmlMapper = new XmlMapper();public SentinelXmlConfiguration() {this.xmlMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);}@Bean({"sentinel-xml-flow-converter"})public XmlConverter xmlFlowConverter() {return new XmlConverter(this.xmlMapper, FlowRule.class);}   //解析限流规则@Bean({"sentinel-xml-degrade-converter"})public XmlConverter xmlDegradeConverter() {return new XmlConverter(this.xmlMapper, DegradeRule.class);}   //解析熔断降级规则@Bean({"sentinel-xml-system-converter"})public XmlConverter xmlSystemConverter() {return new XmlConverter(this.xmlMapper, SystemRule.class);}   //解析系统限流规则@Bean({"sentinel-xml-authority-converter"})public XmlConverter xmlAuthorityConverter() {return new XmlConverter(this.xmlMapper, AuthorityRule.class);}   //解析黑白名单规则@Bean({"sentinel-xml-param-flow-converter"})public XmlConverter xmlParamFlowConverter() {return new XmlConverter(this.xmlMapper, ParamFlowRule.class);}   //解析热点限流规则}@Configuration(proxyBeanMethods = false)protected static class SentinelJsonConfiguration {    //解析json格式规则private ObjectMapper objectMapper = new ObjectMapper();public SentinelJsonConfiguration() {this.objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);}@Bean({"sentinel-json-flow-converter"})public JsonConverter jsonFlowConverter() {return new JsonConverter(this.objectMapper, FlowRule.class);}   //解析限流规则@Bean({"sentinel-json-degrade-converter"})public JsonConverter jsonDegradeConverter() {return new JsonConverter(this.objectMapper, DegradeRule.class);}   //解析熔断降级规则@Bean({"sentinel-json-system-converter"})public JsonConverter jsonSystemConverter() {return new JsonConverter(this.objectMapper, SystemRule.class);}   //解析系统限流规则@Bean({"sentinel-json-authority-converter"})public JsonConverter jsonAuthorityConverter() {return new JsonConverter(this.objectMapper, AuthorityRule.class);}   //解析黑白名单规则@Bean({"sentinel-json-param-flow-converter"})public JsonConverter jsonParamFlowConverter() {return new JsonConverter(this.objectMapper, ParamFlowRule.class);}   //解析热点限流规则}}
}

SentinelProperties

@ConfigurationProperties(prefix = "spring.cloud.sentinel"
)
@Validated
public class SentinelProperties {private boolean eager = false;private boolean enabled = true;private String blockPage;private Map<String, DataSourcePropertiesConfiguration> datasource;private SentinelProperties.Transport transport;private SentinelProperties.Metric metric;private SentinelProperties.Servlet servlet;private SentinelProperties.Filter filter;private SentinelProperties.Flow flow;private SentinelProperties.Log log;private Boolean httpMethodSpecify;private Boolean webContextUnify;*********
Transportpublic static class Transport {private String port = "8719";private String dashboard = "";private String heartbeatIntervalMs;private String clientIp;*********
Metricpublic static class Metric {private String fileSingleSize;private String fileTotalCount;private String charset = "UTF-8";*********
Servletpublic static class Servlet {private String blockPage;*********
Filterpublic static class Filter {private int order = -2147483648;private List<String> urlPatterns = Arrays.asList("/**");private boolean enabled = true;*********
Flowpublic static class Flow {private String coldFactor = "3";*********
Logpublic static class Log {private String dir;private boolean switchPid = false;

DataSourcePropertiesConfiguration

public class DataSourcePropertiesConfiguration {private FileDataSourceProperties file;     //本地文件存储private NacosDataSourceProperties nacos;   //nacos存储private ZookeeperDataSourceProperties zk;  //zookeeper存储private ApolloDataSourceProperties apollo; //apollo存储private RedisDataSourceProperties redis;   //redis存储private ConsulDataSourceProperties consul; //consul存储

NacosDataSourceProperties

public class NacosDataSourceProperties extends AbstractDataSourceProperties {private String serverAddr;private String username;private String password;@NotEmptyprivate String groupId = "DEFAULT_GROUP";@NotEmptyprivate String dataId;private String endpoint;private String namespace;private String accessKey;private String secretKey;public NacosDataSourceProperties() {super(NacosDataSourceFactoryBean.class.getName());}

AbstractDataSourceProperties

public class AbstractDataSourceProperties {@NotEmptyprivate String dataType = "json";   //数据默认用json格式存储@NotNullprivate RuleType ruleType;          //规则类型private String converterClass;@JsonIgnoreprivate final String factoryBeanName;@JsonIgnoreprivate Environment env;public AbstractDataSourceProperties(String factoryBeanName) {this.factoryBeanName = factoryBeanName;}

RuleType:限流、熔断降级、热点限流、系统限流、黑白名单、网关限流、网关api限流

public enum RuleType {FLOW("flow", FlowRule.class),DEGRADE("degrade", DegradeRule.class),PARAM_FLOW("param-flow", ParamFlowRule.class),SYSTEM("system", SystemRule.class),AUTHORITY("authority", AuthorityRule.class),GW_FLOW("gw-flow", "com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule"),GW_API_GROUP("gw-api-group", "com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiDefinition");private final String name;private Class clazz;private String clazzName;private RuleType(String name, Class clazz) {this.name = name;this.clazz = clazz;}private RuleType(String name, String clazzName) {this.name = name;this.clazzName = clazzName;}

相关注解

@SentinelResource

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface SentinelResource {String value() default "";        //资源名称,必填EntryType entryType() default EntryType.OUT;int resourceType() default 0;String blockHandler() default "";  //处理blockException的方法,参数及返回类型需相同,//方法参数最后也可添加BlockException(可不添加)Class<?>[] blockHandlerClass() default {};  //处理blockException的类,对应的函数必需为static函数String fallback() default "";        //处理所有异常,指定异常时的服务降级方法,同时配置fallback、defaultFallback,fallback生效String defaultFallback() default ""; //处理所有异常,异常时默认的服务降级处理方法Class<?>[] fallbackClass() default {};  //处理所有异常,异常时服务降级处理类Class<? extends Throwable>[] exceptionsToTrace() default {Throwable.class};  //需要追踪处理的异常类Class<? extends Throwable>[] exceptionsToIgnore() default {};  //忽略处理的异常类,不会统计异常,不会用fallback处理,直接抛出异常
}

EntryType

public enum EntryType {IN("IN"),OUT("OUT");private final String name;private EntryType(String s) {this.name = s;}public boolean equalsName(String otherName) {return this.name.equals(otherName);}public String toString() {return this.name;}
}

@SentinelResource使用示例

public class TestService {// 原函数@SentinelResource(value = "hello", blockHandler = "exceptionHandler", fallback = "helloFallback")public String hello(long s) {return String.format("Hello at %d", s);}// Fallback 函数,函数签名与原函数一致或加一个 Throwable 类型的参数.public String helloFallback(long s) {return String.format("Halooooo %d", s);}// Block 异常处理函数,参数最后多一个 BlockException,其余与原函数一致.public String exceptionHandler(long s, BlockException ex) {// Do some log here.ex.printStackTrace();return "Oops, error occurred at " + s;}// 这里单独演示 blockHandlerClass 的配置.// 对应的 `handleException` 函数需要位于 `ExceptionUtil` 类中,并且必须为 public static 函数.@SentinelResource(value = "test", blockHandler = "handleException", blockHandlerClass = {ExceptionUtil.class})public void test() {System.out.println("Test");}
}

限流降级规则

RuleConstant:限流降级规则常量

public final class RuleConstant {public static final int FLOW_GRADE_THREAD = 0;public static final int FLOW_GRADE_QPS = 1;public static final int DEGRADE_GRADE_RT = 0;public static final int DEGRADE_GRADE_EXCEPTION_RATIO = 1;public static final int DEGRADE_GRADE_EXCEPTION_COUNT = 2;public static final int DEGRADE_DEFAULT_SLOW_REQUEST_AMOUNT = 5;public static final int DEGRADE_DEFAULT_MIN_REQUEST_AMOUNT = 5;public static final int AUTHORITY_WHITE = 0;public static final int AUTHORITY_BLACK = 1;public static final int STRATEGY_DIRECT = 0;public static final int STRATEGY_RELATE = 1;public static final int STRATEGY_CHAIN = 2;public static final int CONTROL_BEHAVIOR_DEFAULT = 0;public static final int CONTROL_BEHAVIOR_WARM_UP = 1;public static final int CONTROL_BEHAVIOR_RATE_LIMITER = 2;public static final int CONTROL_BEHAVIOR_WARM_UP_RATE_LIMITER = 3;public static final String LIMIT_APP_DEFAULT = "default";public static final String LIMIT_APP_OTHER = "other";public static final int DEFAULT_SAMPLE_COUNT = 2;public static final int DEFAULT_WINDOW_INTERVAL_MS = 1000;private RuleConstant() {}
}

AbstractRule

public abstract class AbstractRule implements Rule {private String resource;    //限制的资源名称private String limitApp;    //规则针对的调用来源:some_origin、default(不区分来源,默认)、otherpublic AbstractRule() {}

FlowRule:限流规则

public class FlowRule extends AbstractRule {private int grade = 1;                  //限流阈值类型:0(并发线程数限流)、1(QPS限流)private double count;                   //限流阀值private int strategy = 0;               //调用关系限流策略:直接(默认)、链路、关联private String refResource;             //关联资源名称private int controlBehavior = 0;        //流控效果:直接拒绝(默认)、WarmUp、匀速+排队等待private int warmUpPeriodSec = 10;       //流控效果为warm up时,冷启动时长,默认10sprivate int maxQueueingTimeMs = 500;    //流控效果为匀速+排队等待时,最长排队时间private boolean clusterMode;            //是否是集群模式private ClusterFlowConfig clusterConfig;      //集群限流配置private TrafficShapingController controller;  //自定义流控效果public FlowRule() {this.setLimitApp("default");}public FlowRule(String resourceName) {this.setResource(resourceName);this.setLimitApp("default");}

ClusterFlowConfig:集群流控策略

public class ClusterFlowConfig {private Long flowId;               //集群流控id,需保证全局唯一private int thresholdType = 0;     //阀值模式:0(单机均摊)、1(全局模式)private boolean fallbackToLocalWhenFail = true;  //在 client 连接失败或通信失败时,是否退化到本地的限流模式private int strategy = 0;            //限流策略:直接(资源本深,默认)、链路、关联private int sampleCount = 10;        //窗口数量private int windowIntervalMs = 1000; //窗口统计时长,默认1spublic ClusterFlowConfig() {}

DegradeRule:降级策略

public class DegradeRule extends AbstractRule {private int grade = 0;            //熔断策略:慢调用比例(默认)、异常比例、异常数策略private double count;             //熔断阀值(慢调用为最长响应时间)private int timeWindow;           //熔断时间窗口private int minRequestAmount = 5; //最小请求数,请求数小于该值时即使异常比率超出阈值也不会熔断private double slowRatioThreshold = 1.0D;  //慢调用比例阈值private int statIntervalMs = 1000;         //统计时长(单位为ms)public DegradeRule() {}public DegradeRule(String resourceName) {this.setResource(resourceName);}

ParamFlowRule:热点限流规则

public class ParamFlowRule extends AbstractRule {private int grade = 1;                //限流模式,默认为QPS限流private Integer paramIdx;             //热点参数的索引private double count;                 //限流阀值private int controlBehavior = 0;      //流控策略:快速失败(默认)、匀速排队模式private int maxQueueingTimeMs = 0;    //最大排队等待时长(仅在匀速排队模式生效), 默认0msprivate int burstCount = 0;           //应对突发流量额外允许的数量,默认为0private long durationInSec = 1L;      //统计窗口时间长度(单位为秒),默认1sprivate List<ParamFlowItem> paramFlowItemList = new ArrayList();  //参数例外项,针对指定的参数值单独设置限流阈值,//不受count阈值限制,仅支持基本类型和字符串类型private Map<Object, Integer> hotItems = new HashMap();  //额外参数private boolean clusterMode = false;                    //是否是集群模式private ParamFlowClusterConfig clusterConfig;           //集群流控配置public ParamFlowRule() {}public ParamFlowRule(String resourceName) {this.setResource(resourceName);}

SystemRule:系统流控规则

public class SystemRule extends AbstractRule {private double highestSystemLoad = -1.0D;   //系统最高负载private double highestCpuUsage = -1.0D;     //系统cpu最高使用率private double qps = -1.0D;                 //入口资源的QPSprivate long avgRt = -1L;                   //入口流量的平均响应时间private long maxThread = -1L;               //入口流量的最大并发数public SystemRule() {}

AuthorityRule:访问控制规则(黑白名单规则)

public class AuthorityRule extends AbstractRule {private int strategy = 0;   //限制模式:白名单模式(默认)、黑名单模式

SentinelgateWayConstants:网关限流常量

public final class SentinelGatewayConstants {public static final int APP_TYPE_GATEWAY = 1;public static final int RESOURCE_MODE_ROUTE_ID = 0;public static final int RESOURCE_MODE_CUSTOM_API_NAME = 1;public static final int PARAM_PARSE_STRATEGY_CLIENT_IP = 0;public static final int PARAM_PARSE_STRATEGY_HOST = 1;public static final int PARAM_PARSE_STRATEGY_HEADER = 2;public static final int PARAM_PARSE_STRATEGY_URL_PARAM = 3;public static final int PARAM_PARSE_STRATEGY_COOKIE = 4;public static final int URL_MATCH_STRATEGY_EXACT = 0;public static final int URL_MATCH_STRATEGY_PREFIX = 1;public static final int URL_MATCH_STRATEGY_REGEX = 2;public static final int PARAM_MATCH_STRATEGY_EXACT = 0;public static final int PARAM_MATCH_STRATEGY_PREFIX = 1;public static final int PARAM_MATCH_STRATEGY_REGEX = 2;public static final int PARAM_MATCH_STRATEGY_CONTAINS = 3;public static final String GATEWAY_CONTEXT_DEFAULT = "sentinel_gateway_context_default";public static final String GATEWAY_CONTEXT_PREFIX = "sentinel_gateway_context$$";public static final String GATEWAY_CONTEXT_ROUTE_PREFIX = "sentinel_gateway_context$$route$$";public static final String GATEWAY_NOT_MATCH_PARAM = "$NM";public static final String GATEWAY_DEFAULT_PARAM = "$D";private SentinelGatewayConstants() {}
}

GateWayFlowRule:网关限流规则

public class GatewayFlowRule {private String resource;          //限流资源private int resourceMode = 0;     //资源模式:RESOURCE_MODE_ROUTE_ID(0,默认)、RESOURCE_MODE_CUSTOM_API_NAME(1)private int grade = 1;            //限流阈值类型:并发线程模式(0)、QPS模式(1,默认)private double count;             //限流阀值private long intervalSec = 1L;    //统计时间窗口,默认1sprivate int controlBehavior = 0;  //流控效果:快速失败、匀速排队private int burst;                //应对突发请求时额外允许的请求数目private int maxQueueingTimeoutMs = 500;   //匀速排队模式下的最长排队时间,单位毫秒private GatewayParamFlowItem paramItem;   //参数限流配置,若不提供,则代表不针对参数进行限流public GatewayFlowRule() {}public GatewayFlowRule(String resource) {this.resource = resource;}

sentinel 使用说明相关推荐

  1. Sentinel使用教程

    文章目录 一.Sentinel简介 1.sentinel介绍 2.sentinel应用场景 3.sentinel与hystrix 4.sentinel组件介绍 二.Sentinel使用说明 1.控制台 ...

  2. java xml 推模式 拉模式_Alibaba Sentinel规则持久化-推模式-手把手教程(基于Nacos)...

    点击上方"IT牧场",选择"设为星标"技术干货每日送达! 一.推模式架构图 TIPS 图片来自官方. 引用自 https://github.com/alibab ...

  3. Sentinel: 分布式系统的流量防卫兵 1

    Sentinel 是什么? 随着微服务的流行,服务和服务之间的稳定性变得越来越重要.Sentinel 以流量为切入点,从流量控制.熔断降级.系统负载保护等多个维度保护服务的稳定性. Sentinel ...

  4. Sentinel圣天诺加密狗简单使用教程(Linux)

    前言:帮学校的学长做了个Ubuntu的软件,需要给软件加密,用到了加密狗,在网上挑了很多,大都不支持Linux下ELF文件的加密,最后终于找到了Sentinel加密狗支持我们的需求,当然这个进口货也很 ...

  5. sentinel 限流熔断神器详细介绍

    一.限流熔断神器 sentinel 1.什么是 sentinel: 在基于 SpringCloud 构建的微服务体系中,服务间的调用链路会随着系统的演进变得越来越长,这无疑会增加了整个系统的不可靠因素 ...

  6. Sentinel(二)之Quick Start

    转载自 Sentinel Quick Start 1.1 公网 Demo 如果希望最快的了解 Sentinel 在做什么,我们可以通过 Sentinel 新手指南 来运行一个例子,并且能在云上控制台上 ...

  7. Alibaba Sentinel规则持久化-推模式-手把手教程【基于Nacos】

    前面,已经为Sentinel实现了 基于拉模式的规则持久化 ,本文来实现基于 推模式的规则持久化. 文章目录 一.推模式架构图 二.原理简述 三.微服务改造 3.1. 加依赖 3.2. 添加配置 四. ...

  8. Hard Disk Sentinel Pro v5.70.8 硬盘哨兵 电脑硬盘检测工具

    前言 Hard Disk Sentinel是一款国外的硬盘检测软件,持winpe也支持win10,支持ssd固态硬盘.它使用 SMART 技术监控硬盘健康.性能,及温度等重要参数.此软件最大的作用就是 ...

  9. Sentinel 高可用流量管理框架

    Sentinel 是面向分布式服务架构的高可用流量防护组件,主要以流量为切入点,从限流.流量整形.熔断降级.系统负载保护.热点防护等多个维度来帮助开发者保障微服务的稳定性. Sentinel 具有以下 ...

最新文章

  1. 启动Tomcat一闪而过解决
  2. 重构智能合约(中):平行宇宙与无限扩展
  3. SpringCloud F.RC2 整合Zipkin简单步骤
  4. gradle各版本下载地址
  5. coolite TreeNode NodeClick传id到后台的方法
  6. 新手学html 第一节:html简介
  7. Python开发第一篇 基础篇(下)
  8. brave浏览器_火狐联创、Java Script之父,居然也来倒腾区块链浏览器?
  9. 【渝粤教育】国家开放大学2019年春季 45烹饪原料学(1) 参考试题
  10. 工具推荐-极速全文搜索工具、文档内容搜索引擎
  11. java 换行分割_java – 如何通过换行分割字符串?
  12. 小程序input绑定输入保存数据
  13. 工业镜头的主要参数与选型
  14. 上亿用户,如何高效统计独立用户访问量?
  15. 如何安装配置eosjs并连接到EOS区块链
  16. python中mysqldb的用法
  17. 微信小程序 | 基于ChatGPT实现电影推荐小程序
  18. Microsoft SQL Server 2008 R2(Microsoft SQL Server,错误: 2)
  19. N4BiasFieldCorrection
  20. 一年级计算机课画画用什么,一年级学画画入门教程

热门文章

  1. 遥控器对码与飞控解锁
  2. Bootstrap 框架详解
  3. 损失函数(lossfunction)的全面介绍(简单易懂版)
  4. 故人西辞黄鹤楼,烟花三月下扬州
  5. 【docker】docker概述及基础入门
  6. EOF on Windows
  7. 基于Python的智能分班系统
  8. 处理火焰的MATLAB程序,炉膛火焰图像预处理的MATLAB实现
  9. JavaWeb学习笔记(三)—— JavaScript
  10. UESTC 1712 七夜雪寂,一世人心