Redis核心知识小结

news2024/9/21 10:45:24

基础

redis为什么快呢?

  1. 单线程
  2. 基于io多路复用
  3. 底层C语言对数据结构做了优化
  4. 完全内存的操作

Redis6.0使用多线程是怎么回事?

Redis不是说用单线程的吗?怎么6.0成了多线程的?
Redis6.0的多线程是用多线程来处理数据的读写和协议解析,但是Redis执行命令还是单线程的。

持久化

redis持久化方式有哪些?有什么区别?

持久化分为rdb和aof两种。

RDB持久化是把当前进程数据生成快照保存到硬盘的过程,触发RDB持久化过程分为手动触发和自动触发。分别使用命令save或者bgsave。
同时rdb是一个二进制的压缩文件,

以下几个场景会自动触发rdb持久化

  1. 使用save相关配置,如“save m n”。表示m秒内数据集存在n次修改时,自动触发bgsave。
  2. 如果从节点执行全量复制操作,主节点自动执行bgsave生成RDB文件并发送给从节点
  3. 执行debug reload命令重新加载Redis时,也会自动触发save操作
  4. 默认情况下执行shutdown命令时,如果没有开启AOF持久化功能则自动执行bgsave。

以独立日志的方式记录每次写命令, 重启时再重新执行AOF文件中的命令达到恢复数据的目的,整体工作过程为:

  1. 所有的写入命令会追加到aof_buf(缓冲区)中。
  2. AOF缓冲区根据对应的策略向硬盘做同步操作。
  3. 随着AOF文件越来越大,需要定期对AOF文件进行重写,达到压缩 的目的。
  4. 当Redis服务器重启时,可以加载AOF文件进行数据恢复。

rdb和aof各自有什么优缺点?

rdb优点:

  1. 只有一个紧凑的二进制文件 dump.rdb,非常适合备份、全量复制的场景。
  2. 容灾性好,可以把RDB文件拷贝道远程机器或者文件系统张,用于容灾恢复。
  3. 恢复速度快,RDB恢复数据的速度远远快于AOF的方式

rdb的缺点:

  1. 实时性低,RDB 是间隔一段时间进行持久化,没法做到实时持久化/秒级持久化。如果在这一间隔事件发生故障,数据会丢失。
  2. 存在兼容问题,Redis演进过程存在多个格式的RDB版本,存在老版本Redis无法兼容新版本RDB的问题。

aof优点:

  1. 实时性好,aof 持久化可以配置 appendfsync 属性,有 always,每进行一次命令操作就记录到 aof 文件中一次。
  2. 通过 append 模式写文件,即使中途服务器宕机,可以通过 redis-check-aof 工具解决数据一致性问题。

aof缺点:

  1. AOF 文件比 RDB 文件大,且 恢复速度慢。
  2. 数据集大 的时候,比 RDB 启动效率低。

rdb和aof如何选择?

  1. 如果想达到足以媲美数据库的 数据安全性,应该 同时使用两种持久化功能。在这种情况下,当 Redis 重启的时候会优先载入 AOF 文件来恢复原始的数据,因为在通常情况下 AOF 文件保存的数据集要比 RDB 文件保存的数据集要完整。
  2. 如果 可以接受数分钟以内的数据丢失,那么可以 只使用 RDB 持久化。
  3. 有很多用户都只使用 AOF 持久化,但并不推荐这种方式,因为定时生成 RDB 快照(snapshot)非常便于进行数据备份, 并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快,除此之外,使用 RDB 还可以避免 AOF 程序的 bug。
  4. 如果只需要数据在服务器运行的时候存在,也可以不使用任何持久化方式。

redis的数据恢复如何做到的?

  1. AOF持久化开启且存在AOF文件时,优先加载AOF文件。
  2. AOF关闭或者AOF文件不存在时,加载RDB文件。
  3. 加载AOF/RDB文件成功后,Redis启动成功。
  4. AOF/RDB文件存在错误时,Redis启动失败并打印错误信息。

redis4.0的持久化了解嘛?

将 rdb 文件的内容和增量的 AOF 日志文件存在一起。这里的 AOF 日志不再是全量的日志,而是 自持久化开始到持久化结束 的这段时间发生的增量 AOF 日志,通常这部分 AOF 日志很小。

缓存问题以及解决思路

缓存穿透

尽管我们将数据库中某些数据换到到内存中,但是若有些攻击者使用一些数据库中不存在的key进行恶意攻击,这时候,所有的查询请求就像穿透了缓存中间件一样直接在数据库中进行查询操作,在高并发场景,这样的攻击就会使得数据压力过大,从而导致数据库性能瓶颈。

  1. 使用过滤器,我们可以使用布隆过滤器来减少对数据库的请求,布隆过滤器的原理是将数据库的数据哈希到 bitmap 中(在initialBean阶段将数据缓存到内存中),每次查询之前,先使用布隆过滤器过滤掉一定不存在的无效请求,从而避免了无效请求给数据库带来的查询压力。
  2. 缓存空结果,我们可以把每次从数据库查询的数据都保存到缓存中,为了提高前台用户的使用体验 (解决长时间内查询不到任何信息的情况),我们可以将空结果的缓存时间设置得短一些,例如 3~5 分钟,但是有可能导致数据一致性问题,所以我们建议查询或者更新的时候要对这个类型的缓存上个锁进行进一步的操作。

缓存击穿

和上述问题情况一样,也是缓存中查不到用户数据,大量请求打到数据库上,但是这种情况的发生原因却非恶意攻击者所为,原因大抵如下:

1. 大量用户查询的某个数据,刚刚好在缓存中过期。
2. 大量用户查询的值都在数据中,缓存中没有。
解决策略
  1. 加锁排队。
  2. 设置热点数据永不过期。

缓存雪崩

大量缓存数据同一时间到期,所有查询一下子都打到数据库上。导致数据库压力过大进而直接宕机。

解决策略
  1. 加锁排队,示例代码如下所示,如果数据库中没有值的话直接上锁到数据库查在放到缓存中,有点类似于单例模式的双重锁校验。
// 缓存 key
String cacheKey = "userlist";
// 查询缓存
String data = jedis.get(cacheKey);
if (StringUtils.isNotBlank(data)) {
    // 查询到数据,直接返回结果
    return data;
} else {
    // 先排队查询数据库,再放入缓存
    synchronized (cacheKey) {
        data = jedis.get(cacheKey);
        if (!StringUtils.isNotBlank(data)) { // 双重判断
            // 查询数据库
            data = findUserInfo();
            // 放入缓存
            jedis.set(cacheKey, data);
        }
        return data;
    }
}
  1. 设计缓存时,对缓存设置随机时间
// 缓存原本的失效时间
int exTime = 10 * 60;
// 随机数生成类
Random random = new Random();
// 缓存设置
jedis.setex(cacheKey, exTime + random.nextInt(1000) , value);

缓存污染(缓存空间全满)

某些数据查询一次就被缓存在数据库中,随着时间推移,缓存空间已经满了,这时候redis就要根据缓存策略进行缓存置换。这就造成没意义的数据需要通过缓存置换策略来淘汰数据,而且还可能出现淘汰热点数据的情况。

解决方案
选定合适的缓存置换策略,而redis缓存策略主要分三类

不淘汰的

  1. noeviction (v4.0后默认的):不会淘汰任何过期键,满了就报错,对设置了过期时间的数据中进行淘汰
  2. volatile-random:随机删除过期key
  3. volatile-ttl:根据过期时间进行排序,越早过期的数据就优先被淘汰。
  4. volatile-lru:即最近最少使用算法(推荐),redis的lru缓存置换算法相比传统的算法做了一定优化,根据 maxmemory-samples从缓存中随机取出几个key值,然后进行比较在进行淘汰,这样就避免了缓存置换时需要操作一个大链表进行key值淘汰了。
  5. volatile-lfu:lru只知晓用户最近使用次数,而不知道该数据使用频率,所以lfu就是基于lru进一步的优化,进行淘汰时随机取出访问次数最少的数据,如果最少的数据有多个,按按照lru算法进行淘汰。但是redis只用8bit记录访问次数,超过255就无法进行自增了,所以我们可以使用lfu-log-factorlfu-decay-time来用户访问次数增加的频率。
  6. lfu-decay-time:控制访问次数衰减。LFU 策略会计算当前时间和数据最近一次访问时间的差值,并把这个差值换算成以分钟为单位。然后,LFU 策略再把这个差值除以 lfu_decay_time 值,所得的结果就是数据 counter 要衰减的值。若设置为0,则意味着每次扫描访问次数都会扣减。
  7. lfu-log-factor:用计数器当前的值乘以配置项 lfu_log_factor 再加 1,再取其倒数,得到一个 p 值;然后,把这个 p 值和一个取值范围在(0,1)间的随机数 r 值比大小,只有 p 值大于 r 值时,计数器才加 1。
    全部数据进行淘汰
  8. allkeys-random:从所有键值对中使用lru淘汰
  9. allkeys-lru:从所有键值对中随机删除
  10. allkeys-lfu:从所有键值对中使用lfu随机淘汰

具体可以查看redis配置文件描述

 MAXMEMORY POLICY: how Redis will select what to remove when maxmemory
# is reached. You can select one from the following behaviors:
#
# volatile-lru -> Evict using approximated LRU, only keys with an expire set.
# allkeys-lru -> Evict any key using approximated LRU.
# volatile-lfu -> Evict using approximated LFU, only keys with an expire set.
# allkeys-lfu -> Evict any key using approximated LFU.
# volatile-random -> Remove a random key having an expire set.
# allkeys-random -> Remove a random key, any key.
# volatile-ttl -> Remove the key with the nearest expire time (minor TTL)
# noeviction -> Don't evict anything, just return an error on write operations.
#
# LRU means Least Recently Used
# LFU means Least Frequently Used

假如Redis里面有1亿个key,其中有10w个key是以某个固定的已知的前缀开头的,如何将它们全部找出来?

使用 keys 指令可以扫出指定模式的 key 列表。但是要注意 keys 指令会导致线程阻塞一段时间,线上服务会停顿,直到指令执行完毕,服务才能恢复。这个时候可以使用 scan 指令,scan 指令可以无阻塞的提取出指定模式的 key 列表,但是会有一定的重复概率,在客户端做一次去重就可以了,但是整体所花费的时间会比直接用 keys 指令长。

redis如何保证命令原子性

使用原子命令

  1. Redis 提供了 INCR/DECR/SETNX 命令,把RMW三个操作转变为一个原子操作
  2. Redis 是使用单线程串行处理客户端的请求来操作命令,所以当 Redis 执行某个命令操作时,其他命令是无法执行的,这相当于命令操作是互斥执行的

加锁

加锁主要是考虑多个客户端对相同业务方法进行修改操作,我们可以使用加锁的方式保证原子性,大致的方式为:

  1. 使用setnx上锁
  2. 上锁成功后,执行业务修改操作
  3. 使用del释放锁。

这期间你可能会遇到两个问题:

  1. 假如在操作期间出现了业务异常(或者服务器宕机了),就会导致key未能及时释放,进而导致锁无法释放,我们必须对这个锁设置时效,并且在操作期间定时监测和续命。
SET key value [EX seconds | PX milliseconds] [NX]
  1. 误删除,比如用户1持有锁,用户2拿不到锁,用del命令把这个锁删除,对此我们可以使用setnx的value比对看看上锁和用户和解锁的用户是不是同一个进行进一步的操作。
 SET lock_key unique_value NX PX 10000 
  1. 使用lua脚本:多个操作写到一个 Lua 脚本中(Redis 会把整个 Lua 脚本作为一个整体执行,在执行的过程中不会被其他命令打断,从而保证了 Lua 脚本中操作的原子性)
local current current = redis.call("incr",KEYS[1]) 
if tonumber(current) == 1 
then redis.call("expire",KEYS[1],60) 
end

怎么处理热key

什么是热Key? 所谓的热key,就是访问频率比较的key。
比如,热门新闻事件或商品,这类key通常有大流量的访问,对存储这类信息的 Redis来说,是不小的压力。
假如Redis集群部署,热key可能会造成整体流量的不均衡,个别节点出现OPS过大的情况,极端情况下热点key甚至会超过 Redis本身能够承受的OPS。

怎么处理热key?

热key处理 对热key的处理,最关键的是对热点key的监控,可以从这些端来监控热点key:
客户端 客户端其实是距离key“最近”的地方,因为Redis命令就是从客户端发出的,例如在客户端设置全局字典(key和调用次数),每次调用Redis命令时,使用这个字典进行记录。
代理端 像Twemproxy、Codis这些基于代理的Redis分布式架构,所有客户端的请求都是通过代理端完成的,可以在代理端进行收集统计。

Redis服务端 使用monitor命令统计热点key是很多开发和运维人员首先想到,monitor命令可以监控到Redis执行的所有命令。

只要监控到了热key,对热key的处理就简单了:
把热key打散到不同的服务器,降低压⼒
加⼊⼆级缓存,提前加载热key数据到内存中,如果redis宕机,⾛内存查询

缓存预热怎么做?

所谓缓存预热,就是提前把数据库里的数据刷到缓存里,通常有这些方法:

  1. 直接写个缓存刷新页面或者接口,上线时手动操作
  2. 数据量不大,可以在项目启动的时候自动进行加载(我们目前就是执行这种操作,通过继承InitializingBean实现)
  3. 定时任务刷新缓存.

热点key重建问题了解过?你是如何解决的呢?

开发的时候一般使用“缓存+过期时间”的策略,既可以加速数据读写,又保证数据的定期更新,这种模式基本能够满足绝大部分需求。

但是有两个问题如果同时出现,可能就会出现比较大的问题:

  1. 当前key是一个热点key(例如一个热门的娱乐新闻),并发量非常大。
  2. 重建缓存不能在短时间完成,可能是一个复杂计算,例如复杂的 SQL、多次IO、多个依赖等。 在缓存失效的瞬间,有大量线程来重建缓存,造成后端负载加大,甚至可能会让应用崩溃。

怎么处理呢?

要解决这个问题也不是很复杂,解决问题的要点在于:

  1. 减少重建缓存的次数。

  2. 数据尽可能一致。

  3. 较少的潜在危险。
    所以一般采用如下方式:

  4. 互斥锁(mutex key) 这种方法只允许一个线程重建缓存,其他线程等待重建缓存的线程执行完,重新从缓存获取数据即可。

  5. 永远不过期 “永远不过期”包含两层意思:

  6. 从缓存层面来看,确实没有设置过期时间,所以不会出现热点key过期后产生的问题,也就是“物理”不过期,注意数据更新后要实时加锁更新。

  7. 从功能层面来看,为每个value设置一个逻辑过期时间,当发现超过逻辑过期时间后,会使用单独的线程去构建缓存。

redis运维

redis阻塞问题如何解决

API或数据结构使用不合理

通常Redis执行命令速度非常快,但是不合理地使用命令,可能会导致执行速度很慢,导致阻塞,对于高并发的场景,应该尽量避免在大对象上执行算法复杂 度超过O(n)的命令。

对慢查询的处理分为两步:

发现慢查询: slowlog get{n}命令可以获取最近 的n条慢查询命令;
发现慢查询后,可以从两个方向去优化慢查询: 1)修改为低算法复杂度的命令,如hgetall改为hmget等,禁用keys、sort等命 令 2)调整大对象:缩减大对象数据或把大对象拆分为多个小对象,防止一次命令操作过多的数据。

CPU饱和的问题

单线程的Redis处理命令时只能使用一个CPU。而CPU饱和是指Redis单核CPU使用率跑到接近100%。

针对这种情况,处理步骤一般如下:

判断当前Redis并发量是否已经达到极限,可以使用统计命令redis-cli-h{ip}-p{port}--stat获取当前 Redis使用情况
如果Redis的请求几万+,那么大概就是Redis的OPS已经到了极限,应该做集群化水品扩展来分摊OPS压力
如果只有几百几千,那么就得排查命令和内存的使用

持久化相关的阻塞

对于开启了持久化功能的Redis节点,需要排查是否是持久化导致的阻塞。

fork阻塞 fork操作发生在RDB和AOF重写时,Redis主线程调用fork操作产生共享 内存的子进程,由子进程完成持久化文件重写工作。如果fork操作本身耗时过长,必然会导致主线程的阻塞。
AOF刷盘阻塞 当我们开启AOF持久化功能时,文件刷盘的方式一般采用每秒一次,后台线程每秒对AOF文件做fsync操作。当硬盘压力过大时,fsync操作需要等 待,直到写入完成。如果主线程发现距离上一次的fsync成功超过2秒,为了 数据安全性它会阻塞直到后台线程执行fsync操作完成。
HugePage写操作阻塞 对于开启Transparent HugePages的 操作系统,每次写命令引起的复制内存页单位由4K变为2MB,放大了512 倍,会拖慢写操作的执行时间,导致大量写操作慢查询。

大key问题了解嘛?

Redis使用过程中,有时候会出现大key的情况, 比如:

单个简单的key存储的value很大,size超过10KB
hash, set,zset,list 中存储过多的元素(以万为单位)
大key会造成什么问题呢?

  1. 客户端耗时增加,甚至超时
  2. 对大key进行IO操作时,会严重占用带宽和CPU
  3. 造成Redis集群中数据倾斜
  4. 主动删除、被动删等,可能会导致阻塞

如何找到大key?

  1. bigkeys命令:使用bigkeys命令以遍历的方式分析Redis实例中的所有Key,并返回整体统计信息与每个数据类型中Top1的大Key
  2. redis-rdb-tools:redis-rdb-tools是由Python写的用来分析Redis的rdb快照文件用的工具,它可以把rdb快照文件生成json文件或者生成报表用来分析Redis的使用详情。

如何处理大key?

  1. 删除大key

当Redis版本大于4.0时,可使用UNLINK命令安全地删除大Key,该命令能够以非阻塞的方式,逐步地清理传入的Key。
当Redis版本小于4.0时,避免使用阻塞式命令KEYS,而是建议通过SCAN命令执行增量迭代扫描key,然后判断进行删除。

  1. 压缩和拆分key

当vaule是string时,比较难拆分,则使用序列化、压缩算法将key的大小控制在合理范围内,但是序列化和反序列化都会带来更多时间上的消耗。
当value是string,压缩之后仍然是大key,则需要进行拆分,一个大key分为不同的部分,记录每个部分的key,使用multiget等操作实现事务读取。
当value是list/set等集合类型时,根据预估的数据规模来进行分片,不同的元素计算后分到不同的片。

redis常见的性能问题和解决方案了解嘛?

  1. Master 最好不要做任何持久化工作,包括内存快照和 AOF 日志文件,特别是不要启用内存快照做持久化。
  2. 如果数据比较关键,某个 Slave 开启 AOF 备份数据,策略为每秒同步一次。
  3. 为了主从复制的速度和连接的稳定性,SlaveMaster 最好在同一个局域网内。 尽量避免在压力较大的主库上增加从库。
  4. Master 调用 BGREWRITEAOF 重写 AOF 文件,AOF 在重写的时候会占大量的 CPU 和内存资源,导致服务 load 过高,出现短暂服务暂停现象。
  5. 为了 Master 的稳定性,主从复制不要用图状结构,用单向链表结构更稳定,即主从关为:Master<–Slave1<–Slave2<–Slave3…,这样的结构也方便解决单点故障问题,实现 SlaveMaster 的替换,也即,如果 Master 挂了,可以立马启用 Slave1Master,其他不变。

redis的应用

redis管道了解嘛?

Pipelining(管道)

Redis 管道是三者之中最简单的,当客户端需要执行多条 redis 命令时,可以通过管道一次性将要执行的多条命令发送给服务端,其作用是为了降低 RTT(Round Trip Time) 对性能的影响,比如我们使用 nc 命令将两条指令发送给 redis 服务端。

Redis 服务端接收到管道发送过来的多条命令后,会一直执命令,并将命令的执行结果进行缓存,直到最后一条命令执行完成,再所有命令的执行结果一次性返回给客户端 。 Pipelining示意图`

Pipelining的优势

在性能方面, Pipelining 有下面两个优势:

节省了RTT:将多条命令打包一次性发送给服务端,减少了客户端与服务端之间的网络调用次数
减少了上下文切换:当客户端/服务端需要从网络中读写数据时,都会产生一次系统调用,系统调用是非常耗时的操作,其中设计到程序由用户态切换到内核态,再从内核态切换回用户态的过程。当我们执行 10 条 redis 命令的时候,就会发生 10 次用户态到内核态的上下文切换,但如果我们使用 Pipeining 将多条命令打包成一条一次性发送给服务端,就只会产生一次上下文切换。

redis分布式锁了解嘛?

Redis是分布式锁本质上要实现的目标就是在 Redis 里面占一个“茅坑”,当别的进程也要来占时,发现已经有人蹲在那里了,就只好放弃或者稍后再试。

在这里插入图片描述

V1:setnx命令
占坑一般是使用 setnx(set if not exists) 指令,只允许被一个客户端占坑。先来先占, 用完了,再调用 del 指令释放茅坑。 setnx(set if not exists)

> setnx lock:fighter true
OK
... do something critical ...
> del lock:fighter
(integer) 1

但是有个问题,如果逻辑执行到中间出现异常了,可能会导致 del 指令没有被调用,这样就会陷入死锁,锁永远得不到释放。

V2:锁超时释放
所以在拿到锁之后,再给锁加上一个过期时间,比如 5s,这样即使中间出现异常也可以保证 5 秒之后锁会自动释放。 锁超时释放

> setnx lock:fighter true
OK
> expire lock:fighter 5
... do something critical ...
> del lock:fighter
(integer) 1

但是以上逻辑还有问题。如果在 setnx 和 expire 之间服务器进程突然挂掉了,可能是因为机器掉电或者是被人为杀掉的,就会导致 expire 得不到执行,也会造成死锁。

在这里插入图片描述

这种问题的根源就在于 setnx 和 expire 是两条指令而不是原子指令。如果这两条指令可以一起执行就不会出现问题。

V3:set指令
这个问题在Redis 2.8 版本中得到了解决,这个版本加入了 set 指令的扩展参数,使得 setnx 和expire 指令可以一起执行。 set原子指令

在这里插入图片描述

set lock:fighter3 true ex 5 nx OK ... do something critical ... > del lock:codehole

上面这个指令就是 setnx 和 expire 组合在一起的原子指令,这个就算是比较完善的分布式锁了。

当然实际的开发,没人会去自己写分布式锁的命令,因为有专业的轮子——Redisson。

如何保证redis和数据库一致性

  1. 可以引入消息队列,把要删除的key或者删除失败的key丢尽消息队列,利用消息队列的重试机制,重试删除对应的key。但是对业务有侵入性。
  2. 数据库订阅+消息队列保证key被删除 可以用一个服务(比如阿里的 canal)去监听数据库的binlog,获取需要操作的数据,但是实现比较复杂。
  3. 延时双删,简单说,就是在第一次删除缓存之后,过了一段时间之后,再次删除缓存。更新数据库期间(缓存还没更新),某个线程读取到旧的缓存。

在这里插入图片描述

  1. 设置key的时效(这种我们比较常用,我们的缓存基本都是配置数据,或者一些用户个人信息接口,数据基本不会有太大的变化)

参考文献

Redis常见面试题总结(下)

Redis进阶 - 缓存问题:一致性, 穿击, 穿透, 雪崩, 污染等

Redis 缓存雪崩、缓存穿透、缓存击穿、缓存预热

【Redis】如何保证原子操作

面渣逆袭(Redis面试题八股文)必看👍

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

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

相关文章

段错误详细解读

一、摘要 段错误&#xff08;Segmentation Fault&#xff09;是在编程中常见的错误之一&#xff0c;通常会导致程序崩溃。常出现在Linux系统当中&#xff0c;而且目前关于这方面的解决教程较少。 什么人会使用Linux&#xff1f;Linux 是世界上最受欢迎的操作系统之一&#xf…

产品入门第四讲:Axure动态面板

&#x1f4da;&#x1f4da; &#x1f3c5;我是默&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; ​​​​​ &#x1f31f;在这里&#xff0c;我要推荐给大家我的专栏《Axure》。&#x1f3af;&#x1f3af; &#x1f680;无论你是编程小白&#xff0c;还…

TrustZone之强制隔离

TrustZone有时被称为一个强制执行的保护系统。请求者表示其访问的安全性,而内存系统决定是否允许该访问。内存系统基于何种方式进行检查呢? 在大多数现代系统中,内存系统的检查是由互连完成的。例如,Arm NIC-400允许系统设计人员为每个连接的完成者指定以下内容: • 安全…

ShenYu网关Http服务探活解析

文章目录 网关端服务探活admin端服务探活 Shenyu HTTP服务探活是一种用于检测HTTP服务是否正常运行的机制。它通过建立Socket连接来判断服务是否可用。当服务不可用时&#xff0c;将服务从可用列表中移除。 网关端服务探活 以divide插件为例&#xff0c;看下divide插件是如何获…

实现进程间的通信

本例程是开发一款能实现进程通信的DLL。本例程以Visual Studio 2015为例。在Visual Studio 2013&#xff0c;Visual Studio 2017都是可以。 第一步&#xff1a;在Visual Studio 2015中&#xff0c;创建DLL工程。如何创建DL&#xff0c;在这里就不作具体说明了。百度都有许多创建…

【九】python模板方法模式

9.1 模板方法模式概述 模板方法模式是一种行为设计模式&#xff0c;它使用一个抽象的基类定义了一个操作中的算法的骨架&#xff0c;而将一些步骤的实现延迟到子类中。模板方法模式允许子类在不改变算法结构的情况下重新定义算法中的某些步骤。 9.2 代码示例 在Python中使用…

SpringBoot接口开发

一、springboot官方demo开发 依赖包和父:pom.xml<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.14</version></dependency&g…

windows禁用系统更新

1.在winr运行框中输入services.msc&#xff0c;打开windows服务窗口。 services.msc 2.在服务窗口中&#xff0c;我们找到Windows update选项&#xff0c;如下图所示&#xff1a; 3.双击windows update服务&#xff0c;我们把启动类型改为禁用&#xff0c;如下图所示&#xff…

翻译: ChatGPT Token消耗粗略计算英文就是除以四分之三

在这个视频中&#xff0c;我想带你快速浏览一些例子&#xff0c;以建立对在软件应用中使用大型语言模型的实际成本的直观感受。让我们来看看。这是一些示例价格&#xff0c;用于从不同的大型语言模型获取提示和回应&#xff0c;这些模型对开发者可用。即&#xff0c;如果你在你…

page_title is not translated into en_US(American English)

提示&#xff1a;page_title is not translated into en_US(American English) 修改&#xff1a;三个string.json文件都需要出现相同的name和value才行&#xff0c;如果根据提示进行修改

JS获取当前系统电量情况

在前端浏览器中我们可以通过使用JavaScript的navigator.getBattery()方法来获取当前系统的电池情况。 这个API可以监测设备的电池状态&#xff0c;包括是否在充电、当前电量以及放电或充电所需的时间。本文将介绍如何使用这个API以及它在实际应用中的使用。 API使用 首先让我…

双指针算法(一)

目录 移动零 复写零 快乐数 盛水最多的容器 双指针与单调性结合 有效三角形的个数 查找总价格为目标值的两个商品 两数之和 Ⅱ - 输入有序数组 双指针算法是通过定义两个指针不断单向移动来解决问题的一种算法。但双指针算法&#xff0c;是一个抽象的思想概念&#xf…

京微齐力:基于H7的平衡控制系统(一、姿态解析)

目录 前言一、关于平衡控制系统二、实验效果三、硬件选择1、H7P20N0L176-M2H12、MPU6050 四、理论简述五、程序设计1、Cordic算法2、MPU6050采集数据3、fir&iir滤波4、姿态解算 六、资源消耗&工程获取七、总结 前言 很久之前&#xff0c;就想用纯FPGA做一套控制系统。可…

橘子学K8S01之容器中所谓的隔离

我们一直都在说容器就是一个沙盒&#xff0c;沙盒技术顾名思义就是像一个集装箱一样&#xff0c;把应用(服务&#xff0c;进程之类的)装起来的技术&#xff0c;这样每个进程在自己的沙盒中和其他的沙盒隔离开来&#xff0c;每个沙盒之间存在一个边界使得他们互不干扰&#xff0…

C# 字符串格式化

写在前面 在日常编程中&#xff0c;经常需要对字符串进行格式化操作&#xff0c;以便呈现为不同的格式&#xff0c;满足各种各样的显示需求&#xff0c;C#的字符串格式化参数是非常丰富的&#xff0c;这里做个简单的列举&#xff0c;以供后续参考和延伸。 代码实现 var curr…

Pr自动从视频脚本剪辑视频FirstCut插件免费下载

FirstCut 插件将自动从视频脚本中剪辑视频&#xff0c;在例如新闻、采访、自媒体视频等带有配音或字幕内容的视频制作中提高了粗剪效率。 使用 FirstCut&#xff0c;大大缩短了粗剪的时间&#xff0c;而不是转到每个视频文件并找到 IN 点和 OUT 点&#xff0c;然后将其插入到序…

yolov8常用命令

1.运行预测 &#xff08;1&#xff09;运行目标检测模型&#xff1a; yolo predict modelyolov8n.pt sourcebus.jpg &#xff08;2&#xff09;运行目标检测与分割模型 yolo predict modelyolov8n-seg.pt sourcebus.jpg 2.模型训练 复制coco128.yaml更名为myDetect.y…

c题目17:写一个swap函数,可以交换2个整数变量的值。(分别用普通方式和指针方式实现,对比结果)

每日小语 我坐着&#xff0c;观望世界上所有的忧患&#xff0c;所有的压迫和耻辱看着&#xff0c;听着&#xff0c;一声不响。——惠特曼 自己思考 最近这段时间新的感悟似乎也没有&#xff0c;但我发现我和别人的思想越来越不同&#xff0c;只能跟极少数人产生共鸣&#xff0…

JVM-接口响应时间很长解决办法

问题 在程序运行过程中&#xff0c;发现有几个接口的响应时间特别长&#xff0c;需要快速定位到是哪一个方法的代码执行过程中出现了性能问题。 解决思路 已经确定是某个接口性能出现了问题&#xff0c;但是由于方法嵌套比较深&#xff0c;需要借助于算法定位到具体的方法。 A…

为什么要有arp以及arp原理

今天给大家说说arp吧&#xff01;在学网络的时候&#xff0c;我们知道的是自顶向下交付数据包。但是我们在交付给数据链路层的时候&#xff0c;我们已经有了ip的报头&#xff0c;但是要注意的是&#xff0c;ip层可不会给我们传输数据包&#xff0c;他还要向下交付。我们学过ip协…