【Redis】缓存击穿、缓存穿透、缓存雪崩原理以及多种解决方案

news2024/11/17 16:04:45

一、前言

在 Spring Cloud 微服务集群项目中,客户端的请求首先会经过 Nginx,Nginx 会将请求反向代理到 Gateway 网关层,接着才会将请求发送到具体的服务 service。

在 service 中如果要查询数据,则会到缓存中查询,如果缓存未命中,再到数据库中查询数据。

作为缓存的 Redis 扛住了系统中大量的请求,极大的减小了数据库的压力。

但是当流量很大、高并发时,倘若 Redis 没能扛住,便会导致缓存穿透、缓存击穿、缓存雪崩

二、缓存击穿

当一个被大量并发访问且缓存重建过程比较复杂的键(key)突然失效时,大量的请求会在瞬间直接打到数据库,给数据库带来巨大的压力。

比如,某个电商网站上有一款非常热销的商品,很多人都在不断刷新页面查看商品详情。这个商品详情被缓存了起来,访问速度很快。但是,如果缓存突然失效了,所有用户的请求都会直接发送到数据库服务器,短时间内数据库会承受巨大的访问压力,可能导致数据库响应变慢或甚至宕机。

解决方案:解决缓存击穿问题的关键在于防止在缓存失效时大量请求直接打到数据库。

通过使用乐观锁、分布式锁等策略,可以有效地减轻数据库的压力,提高系统的稳定性和响应速度。

乐观锁

使用乐观锁机制来防止多个客户端同时重建缓存。

  1. 当缓存中找不到数据时,尝试更新缓存。

  2. 如果更新失败(例如因为数据版本冲突),则重试。

示例代码(伪代码):

while (true) {
    data = redis.get(key);
    if (data != null) {
        break;
    }
    try {
        data = db.getData(key);
        redis.set(key, data);
        break;
    } catch (OptimisticLockingFailureException e) {
        // 更新失败,重试
    }
}

 

互斥锁(Mutex Lock)

使用分布式锁(如 Redis 的 SETNX 或 Redlock 算法)来确保同一时间内只有一个请求可以重建缓存。

  1. 当缓存中找不到数据时,尝试获取分布式锁。

  2. 如果获取锁成功,再查询数据库并将数据写回缓存。

  3. 如果获取锁失败,等待一段时间后重试。

示例代码(伪代码):

if (redis.setnx(lockKey, lockValue)) {
    // 获取锁成功
    try {
        // 查询数据库
        data = db.getData(key);
        // 将数据写回缓存
        redis.set(key, data);
    } finally {
        // 释放锁
        redis.del(lockKey);
    }
} else {
    // 获取锁失败,等待并重试
    Thread.sleep(100);
    // 递归调用自己
    getDataFromCacheOrDb(key);
}

优点:

  1. 没有额外的内存消耗

  2. 保证一致性

  3. 实现简单

缺点:

  1. 线程需要等待,性能受影响

  2. 可能有死锁风险

这里还存在一个问题:分布式锁 key 的时间应该设置多长?

如果设置得太短,可能会导致线程还没有执行完业务逻辑锁就失效了;

如果设置得太长,则可能导致锁占用时间过长,影响其他请求的处理效率。

为了解决这个问题,可以使用 Redisson 这样的分布式协调工具,它提供了看门狗机制(Watchdog Mechanism)来动态延长锁的超时时间。

Redisson 的看门狗机制可以自动续期锁的过期时间,确保锁持有者在执行业务逻辑期间锁不会过期。

当一个线程获得了锁之后,Redisson 会在后台启动一个定时任务(看门狗),每隔一段时间自动延长锁的过期时间。

这样,只要锁持有者还在执行业务逻辑,锁就不会过期。

下面是一个使用 Redisson 实现分布式锁的例子,包括如何利用看门狗机制:

  • 引入依赖

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.16.4</version>
</dependency>
  • 配置 Redisson 客户端

创建一个 Redisson 客户端实例,连接到 Redis 服务器

public class DistributedLockExample {

    private static final String LOCK_NAME = "myDistributedLock";

    public static void main(String[] args) {
        Config config = new Config();
        config.useSingleServer().setAddress("redis://127.0.0.1:6379");

        RedissonClient redisson = Redisson.create(config);

        RLock lock = redisson.getLock(LOCK_NAME);

        try {
            // 尝试获取锁,如果没有获取到,则等待
            lock.lock();
            // 执行业务逻辑
            System.out.println("Executing business logic...");
            Thread.sleep(5000); // 模拟耗时操作
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            System.err.println("Interrupted while waiting for lock.");
        } finally {
            // 释放锁
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
                System.out.println("Lock released.");
            }
            redisson.shutdown();
        }
    }
}
  • 看门狗机制的细节

Redisson 的看门狗机制是自动启用的。

调用 lock.lock() 方法获取锁时,Redisson 会自动启动一个后台任务(看门狗),每隔一段时间(默认为锁的超时时间的一半)自动续期锁的过期时间。

这样,只要持有锁的线程还在执行业务逻辑,锁就不会过期。

如果希望自定义看门狗续期的时间间隔,可以通过 lock.tryLock(long waitTime, long leaseTime, TimeUnit unit) 方法来指定:

try {
    lock.tryLock(10, 30, TimeUnit.SECONDS); // 尝试获取锁,等待 10 秒,锁的过期时间为 30 秒
    // 执行业务逻辑
    System.out.println("Executing business logic...");
    Thread.sleep(5000); // 模拟耗时操作
} catch (InterruptedException e) {
    Thread.currentThread().interrupt();
    System.err.println("Interrupted while waiting for lock.");
}

优势:

  1. 自动续期:看门狗机制自动续期锁的过期时间,确保锁持有者在执行业务逻辑期间锁不会过期。

  2. 简化代码:使用 Redisson 可以简化分布式锁的实现代码,避免手动管理锁的续期逻辑。

  3. 容错性:如果持有锁的线程因异常而提前结束,Redisson 会自动释放锁,避免死锁。

通过使用 Redisson 的看门狗机制,可以有效地解决分布式锁的超时问题,确保锁在执行业务逻辑期间不会过期,同时也提高了系统的健壮性和可用性。

为什么不建议使用布隆过滤器解决缓存击穿问题?

  1. 误报问题:布隆过滤器的误报特性意味着它可能会错误地认为一个不在缓存中的数据项存在于缓存中。如果这个数据项实际上并不存在,那么误报会导致不必要的缓存查找,反而增加了系统负担。

  2. 缓存更新问题:布隆过滤器不能用于存储具体的值,只能用于标记存在性。因此,它不能替代缓存来存储实际的数据。

  3. 缓存重建问题:缓存击穿问题的核心在于缓存重建时如何避免大量并发请求直接打到数据库。布隆过滤器无法解决这个问题,因为它并不涉及缓存重建的逻辑。

 

三、缓存穿透 

缓存穿透是指当你要访问的数据既不在缓存中,也不在数据库中时,导致请求先去访问缓存,发现缓存中没有数据,于是再去访问数据库,结果发现数据库中也没有这个数据。这样一来,应用无法从数据库中读取数据并写入缓存,导致后续请求还是会直接打到数据库,缓存就失去了作用。

想象一下,你正在使用一个购物网站,用户输入了一个根本不存在的商品编号(比如一个随机生成的编号)。第一次请求时,缓存中没有这个商品的信息,于是请求会去数据库查找。但是数据库中也没有这个商品的信息。这时,应用无法把数据缓存起来,因为根本就没有数据可以缓存。接下来,如果其他用户也输入同样的编号,他们的请求还是会直接打到数据库,因为缓存中还是没有这条数据。

存在一种情况,恶意用户伪造了大量不存在的 id 发起请求,这将会直接导致 DB 宕机

解决方案:可以通过缓存空值、布隆过滤器、前端请求校验

缓存空值

当查询结果为空时,也将这个空结果缓存起来,并设置一个较短的过期时间。

优点:

  • 简单易行,可以立即减少数据库的压力。

  • 适用于偶尔出现的空查询。

缺点:

  • 如果大量请求查询的都是不存在的数据,缓存中会积累大量的空值,占用缓存空间。

  • 如果空值的过期时间设置不合理,可能会导致频繁的缓存失效。

// 查询缓存
String value = redisTemplate.opsForValue().get(key);

if (value == null) {
    // 查询数据库
    value = databaseService.getValue(key);
    
    if (value == null) {
        // 缓存空值
        redisTemplate.opsForValue().set(key, "NULL", 5, TimeUnit.MINUTES);
    } else {
        // 正常缓存数据
        redisTemplate.opsForValue().set(key, value, 30, TimeUnit.MINUTES);
    }
} else {
    // 从缓存中获取数据
}

 

布隆过滤器

使用布隆过滤器来判断某个数据项是否可能存在。如果布隆过滤器表明数据项不存在,则直接返回;否则再进行正常的缓存和数据库查询。

优点

  • 几乎不会占用太多内存,可以高效地过滤掉不存在的数据项。

  • 减少了数据库的压力。

缺点

  • 存在一定的误报率(false positive),即有可能把不存在的数据误认为存在。

  • 需要维护布隆过滤器,有一定的复杂度。

布隆过滤器可能会产生误判(即把不在集合中的元素误认为在集合中),但它不会漏掉任何一个实际在集合中的元素。

布隆过滤器存在一定的误报率,因此设计时需要考虑到这一点,并合理选择布隆过滤器的容量和哈希函数数量,以降低误报的概率。

如果数据频繁增删改,是不太适合用布隆过滤器的。

因为一个数据变更之后,布隆过滤器无法删除 key,因此,只能重新创建一个布隆过滤器,再加载一遍所有的数据,创建出新的 bitmap。

可以使用带删除功能的布谷鸟布隆过滤器,来满足动态变化的需求。

// 初始化布隆过滤器
BloomFilter<String> bloomFilter = BloomFilter.create(Funnels.stringFunnel(Charsets.UTF_8), expectedInsertions, fpp);

// 检查数据项是否存在
if (!bloomFilter.mightContain(key)) {
    // 数据项不存在,直接返回
    return null;
}

// 查询缓存
String value = redisTemplate.opsForValue().get(key);

if (value == null) {
    // 查询数据库
    value = databaseService.getValue(key);
    
    if (value == null) {
        // 缓存空值
        redisTemplate.opsForValue().set(key, "NULL", 5, TimeUnit.MINUTES);
    } else {
        // 正常缓存数据
        redisTemplate.opsForValue().set(key, value, 30, TimeUnit.MINUTES);
    }
} else {
    // 从缓存中获取数据
}

前端请求校验

在前端对请求进行检查确实可以帮助减轻缓存穿透问题,但这通常不是唯一的解决方案,而是与其他后端策略相结合的一种补充措施。

  • 在前端对用户输入进行验证,确保请求的数据项是合法的。

  • 在前端维护一个黑名单或白名单,确保只有合法的数据项才能发起请求。

  • 在前端通过UI提示用户输入无效的数据项,并阻止提交请求。

  • 分析用户的行为,检测异常的请求模式。

前端的检查和验证可以作为一种预防措施来减少缓存穿透的风险,但它并不是万能的。为了全面解决缓存穿透问题,还需要结合后端的技术手段。前端和后端的结合使用可以更有效地应对缓存穿透问题,提高系统的整体性能和稳定性。

四、缓存雪崩 

缓存雪崩是指很多个缓存数据项同时过期,导致大量请求在同一时间涌向数据库。

不像缓存击穿那样,只是一个单独的数据项过期,但即使是一个数据项过期,也会给数据库带来很大的压力。因此,可以把缓存雪崩看作是由很多个缓存击穿组合而成的现象。

在实际应用中,缓存雪崩是一个更常见的问题。

它不像缓存击穿那样极端,一个数据项过期就能引发成千上万的并发请求,直接把数据库打垮。

相反,缓存雪崩可能是因为每一个数据项只带来几十到几百个并发请求,但当大量数据项同时过期时,这些并发请求叠加在一起,累积到成千上万个,从而把数据库压垮。

想象一下,你在一个大型电商网站上购物,有很多商品的信息都被缓存起来了。如果这些商品的信息都在同一时间过期了,那么所有的用户在查询这些商品信息时,都会直接向数据库发起请求。虽然每个商品的请求量不算太大,但加在一起就变得非常庞大,足以让数据库不堪重负。

相比之下,缓存击穿更像是一个单一的热点商品突然过期了,所有的用户都在同一时间查询这个商品的信息,短时间内数据库会受到极大的压力。

解决方案:

设置不同的过期时间

为了避免大量缓存条目同时过期,可以为每个缓存条目设置一个随机的过期时间,使得缓存条目不会在同一时间失效。

示例代码:

import java.util.concurrent.TimeUnit;

public void cacheData(String key, Object value, int baseExpirationTime) {
    // 为每个缓存条目设置一个随机的过期时间
    int expirationTime = baseExpirationTime + new Random().nextInt(60); // 例如,基础过期时间 ± 30 秒
    redisTemplate.opsForValue().set(key, value, expirationTime, TimeUnit.SECONDS);
}

 

降级策略

当缓存失效时,如果数据库压力过大,可以采用降级策略,以减轻数据库压力。

  • 返回固定值或默认值

public String fetchDataWithFallback(String key) {
    String value = redisTemplate.opsForValue().get(key);
    if (value == null) {
        // 数据库压力过大时返回默认值
        return "Default Value";
    }
    return value;
}
  • 返回错误信息

public ResponseEntity<String> fetchDataWithFallback(String key) {
    String value = redisTemplate.opsForValue().get(key);
    if (value == null) {
        // 数据库压力过大时返回错误信息
        return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).body("Too many requests, please try again later.");
    }
    return ResponseEntity.ok(value);
}
  • 直接拒绝请求

public ResponseEntity<String> fetchDataWithDirectRejection(String key) {
    String value = redisTemplate.opsForValue().get(key);
    if (value == null) {
        // 数据库压力过大时直接拒绝请求
        return ResponseEntity.status(HttpStatus.TOO_MANY_REQUESTS).body("Request rejected due to high load.");
    }
    return ResponseEntity.ok(value);
}
  • 重定向到降级页面

public ResponseEntity<String> fetchDataWithRedirect(String key) {
    String value = redisTemplate.opsForValue().get(key);
    if (value == null) {
        // 数据库压力过大时重定向到降级页面
        return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).header("Location", "/high-load").build();
    }
    return ResponseEntity.ok(value);
}
  • 延迟响应

public String fetchDataWithDelay(String key) {
    String value = redisTemplate.opsForValue().get(key);
    if (value == null) {
        try {
            // 延迟响应
            Thread.sleep(5000); // 延迟 5 秒
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            System.err.println("Interrupted while sleeping.");
        }
        // 数据库压力过大时返回默认值
        return "Default Value";
    }
    return value;
}

在实际应用中,通常会结合多种降级策略来处理高负载情况。例如,可以先尝试返回默认值或错误信息,如果仍然无法缓解压力,则进一步采取直接拒绝请求或延迟响应的措施。  

public ResponseEntity<String> fetchDataWithCombinedFallback(String key) {
    String value = redisTemplate.opsForValue().get(key);
    if (value == null) {
        // 数据库压力过大时尝试返回默认值
        return ResponseEntity.ok("Default Value");
    }

    // 检测系统负载,如果负载过高,则进一步降级
    if (isSystemUnderHighLoad()) {
        return ResponseEntity.status(HttpStatus.TOO_MANY_REQUESTS).body("Request rejected due to high load.");
    }

    return ResponseEntity.ok(value);
}

private boolean isSystemUnderHighLoad() {
    // 检测系统负载的方法
    return false; // 根据实际情况实现
}

不过,要考虑一种情况,如果你的业务对时点性要求高,必须每天的指定时间,去更新我们的数据,比如游戏排行每日零点更新。

在某一个固定的时间,由于业务要求,必须使得数据刷新,并且不允许出现旧数据,让缓存全部失效。

像这样的业务应该怎么办?

既然 redis 无法分散过期时间,那就在业务层下功夫。

时间一到,redis 数据全部失效,大量并发前来查询,在 service 服务层查询时,设置一个短暂的随机延迟时间。

这样,少量的请求先查询,就会读数据库,然后存入 redis;其他请求,由于随机时间稍稍慢了点,就可以去 redis 读出数据。

在业务层设置一个短暂的随机延迟时间,可以有效平滑请求。

import java.util.concurrent.ThreadLocalRandom;

public String fetchDataWithRandomDelay(String key) {
    String value = redisTemplate.opsForValue().get(key);
    if (value == null) {
        // 设置一个短暂的随机延迟时间
        try {
            Thread.sleep(ThreadLocalRandom.current().nextInt(1000)); // 随机延迟 0 到 1000 毫秒
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            System.err.println("Interrupted while sleeping.");
        }

        value = databaseService.getValue(key);
        if (value != null) {
            redisTemplate.opsForValue().set(key, value, 30, TimeUnit.MINUTES);
        }
    }
    return value;
}

参考文章:

不用背八股文!一文搞懂redis缓存击穿、穿透、雪崩!

【面试】redis缓存穿透、缓存击穿、缓存雪崩区别和解决方案 

 

一  叶  知  秋,奥  妙  玄  心 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2104204.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

COT思维链,TOT思维树,GOT思维图,这些都是什么?

1. 导入 hallucinations 1. 什么是幻觉&#xff1f; 大模型出现幻觉&#xff0c;简而言之就是“胡说八道”。 用《A Survey on Hallucination in Large Language Models》文中的话来讲&#xff0c;是指模型生成的内容与现实世界事实或用户输入不一致的现象。 研究人员将大模型…

基于精益六西格玛管理方法进行生产线综合改善

生产线精益六西格玛改善是一个系统工程&#xff0c;只有对其进行系统的策划与组织&#xff0c;才能收到良好的改善效果。一般来说&#xff0c;需要成立一个专门的精益六西格玛推进组织&#xff0c;由其完成一系列的组织、准备工作。具体如下&#xff1a; &#xff08;1&#xf…

AutosarMCAL开发——基于EB FlsLoader驱动

目录 1.FlsLoader原理2.EB配置以及接口应用3.总结 1.FlsLoader原理 FlsLoader模块提供对Dflash bank0以及整个Pflash的操作。Dflash数据存储器Pflash程序储存器&#xff0c;因此在实际运用中 2.EB配置以及接口应用 EB配置步骤 1.取消安全检查&#xff0c;其他所有配置保持默…

《物流工程与管理》是什么级别的期刊?是正规期刊吗?能评职称吗?

​问题解答 问&#xff1a;《物流工程与管理》是不是核心期刊&#xff1f; 答&#xff1a;不是&#xff0c;是知网收录的第一批认定学术期刊。 问&#xff1a;《物流工程与管理》级别&#xff1f; 答&#xff1a;国家级。主管单位&#xff1a; 全国商品养护科技情报中心站 …

mongodb在Java中条件分组聚合查询并且分页(时间戳,按日期分组,年月日...)

废话不多说&#xff0c;先看效果图&#xff1a; SQL查询结果示例&#xff1a; 多种查询结果示例&#xff1a; 原SQL&#xff1a; db.getCollection("hbdd_order").aggregate([{// 把时间戳格式化$addFields: {orderDate: {"$dateToString": {"for…

分类预测|基于蜣螂优化极限梯度提升决策树的数据分类预测Matlab程序DBO-Xgboost 多特征输入单输出 含基础模型

分类预测|基于蜣螂优化极限梯度提升决策树的数据分类预测Matlab程序DBO-Xgboost 多特征输入单输出 含基础模型 文章目录 一、基本原理1. 数据准备2. XGBoost模型建立3. DBO优化XGBoost参数4. 模型训练5. 模型评估6. 结果分析与应用原理总结 二、实验结果三、核心代码四、代码获…

龙兴物联5G物联网主机:开启电力智能化新篇章

在当今时代&#xff0c;电力行业的智能化已成为不可阻挡的趋势。随着社会对电力需求的持续增长以及对供电质量和可靠性要求的不断提高&#xff0c;传统的电力系统管理模式逐渐难以满足需求。 智能化技术的融入为电力系统带来了革命性的变革。通过先进的传感器、通信网络和数据分…

ELK系列之一---探索ELK奇妙世界:初识日志界大名鼎鼎的ES集群!

目录 一、为什么要使用ELK 二、ELK简介 三、Elaticsearch入门 3.1、什么是elaticsearch 3.2、elaticsearch的底层优点 3.2.1、全文检索 3.2.2、倒排索引 3.3、elaticsearch集群原理 一、为什么要使用ELK 一般我们需要进行日志分析场景&#xff1a;直接在日志文件中 gre…

Linux -文件I/O操作

文章目录 C语言文件I/O相关函数操作fopen/fcolsefwritefseekfprintf/fscanffgets/fputs 系统调用相关接口open/closewrite/read C语言文件I/O相关函数操作 fopen/fcolse fopen 函数用于打开一个文件&#xff0c;并根据指定的模式&#xff08;如只读、只写、读写等&#xff09…

SaaS行业渠道管理的深度探索:两种增长模式哪个更强?

在当今数字化时代&#xff0c;SaaS&#xff08;Software-as-a-Service&#xff09;行业正以前所未有的速度重塑企业运营模式。随着市场的日益成熟与竞争的加剧&#xff0c;渠道管理不再仅仅是产品销售的通道&#xff0c;而是成为了SaaS企业构建生态体系、实现业务飞跃的重要策略…

分类预测|基于粒子群优化轻量级梯度提升机算法数据预测Matlab程序PSO-LightGBM 多特征输入多类别输出

分类预测|基于粒子群优化轻量级梯度提升机算法数据预测Matlab程序PSO-LightGBM 多特征输入多类别输出 文章目录 一、基本原理二、实验结果三、核心代码四、代码获取五、总结 分类预测|基于粒子群优化轻量级梯度提升机算法数据预测Matlab程序PSO-LightGBM 多特征输入多类别输出 …

电脑录屏软件哪家强?这6款高效免费工具让你轻松捕捉电脑屏幕

在数字化浪潮的推动下&#xff0c;电脑录屏软件的选择变得琳琅满目&#xff0c;本文旨在帮助您挑选出最适合您需求的录屏工具。 电脑录屏软件在我们的日常工作、学习乃至娱乐活动中扮演着越来越重要的角色。无论是为了记录PPT的演示过程、捕捉QQ、微信、腾讯会议等设计软件的对…

C8T6超绝模块--按键检测点亮LED

C8T6超绝模块–按键检测点亮LED 大纲 按键原理初始化LED初始化按键编写main 具体案例 按键原理 (这里针对的是我的板子的原理图&#xff0c;具体的查看自己的板子)注意看&#xff0c;这里按键一端接到的是地&#xff0c;当我们没按下按键时&#xff0c;其默认是低电压&…

linux环境下升级nodejs版本

文章目录 简介清除缓存信息确保已安装Node.js和npm安装n模块使用n来升级Node.js查看可用的Node.js版本升级Node.js到最新版本注意事项版本兼容性考虑 简介 在Linux环境下&#xff0c;使用npm的n模块来升级Node.js版本是一种非常流行且便捷的方法。n是一个Node.js版本管理工具&…

【OpenCV】通过迭代器获取图像的像素

文章目录 1. 前置知识2. 通过迭代器获取图像的像素 1. 前置知识 &#x1f427; 什么叫做像素&#xff1f; 最小的 图像单元&#xff0c;每个像素可以看成图像中的一个点&#xff0c;它具有颜色、亮度等属性。 cv::Mat是OpenCV中用来处理图像数据的主要数据结构&#xff0c;他实…

tomato靶场通关攻略

1.御剑2014找到IP地址 2.dirb扫描目录 3.再次详细扫描目录 4.访问找到的目录文件 进入antibots中 5.搜寻一会再info.php里面发现有东西 6.这个地方貌似可以进行利用 7.查看源代码发现包含include文件上传漏洞 8.网址后面跟?image../../../../../../../etc/passwd 9.既然可以查…

ceph-iscsi 手动安装过程中的一些问题记录以及解决办法

ceph-iscsi 手动安装教程 安装教程&#xff0c;建议直接看官方文档&#xff0c;猛戳传送门。官方教程是英文版的&#xff08;不知道有没有中文版&#xff09;&#xff0c;都是一些基础英语&#xff0c;问题不大&#xff0c;实在不行找个翻译软件帮帮忙&#xff0c;哈哈哈。 多…

黄力医生揭秘血栓‘成长’之路,七类人群需高度警惕!

血栓&#xff0c;这个潜伏在血液中的“隐形杀手”&#xff0c;悄无声息地阻塞着生命的通道。它如同道路上的障碍&#xff0c;一旦形成&#xff0c;便可能随着血液流向身体各处&#xff0c;引发脑梗、心梗甚至肺栓塞等严重后果。然而&#xff0c;大多数血栓在形成初期并无明显症…

CodeMeter赋能工业应用程序市场,实现安全与灵活的应用管理

面临挑战 在快速发展的工业自动化领域&#xff0c;软件保护和许可成为各行业决策者日常面临的关键问题。无论是自制还是购买&#xff0c;都需应对复杂的集成任务和多样化的用户需求。对于软件开发者来说&#xff0c;将先进的保护和许可技术&#xff08;如CodeMeter&#xff09;…

ISO 26262中的失效率计算:SN 29500-11 Expected values for contactors

目录 引言 1 基准条件下的失效率 2 失效率转换 2.1 失效率预测模型 2.2 开关速率应力系数 2.3 电压应力系数 2.3.1 电压应力系数计算模型 2.3.2 电压应力系数计算 2.4 电流应力系数 2.4.1 电流应力系数计算模型 2.4.2 电流应力系数计算 2.5 温度应力系数 2.6 环境…