京东生产环境十万并发秒杀系统三高架构

文章目录

  • 三高——高并发、高可用、高可扩展
    • 用数据库乐观锁解决超卖
    • 阿里巴巴:为了提升数据库性能,对数据库的源码级别做了改造——在DB内部实现内存队列,一次性接收很多的请求,一次性更新。
    • 京东:redis,mq,也有用缓存的
    • redis集群架构部署
    • redis集群架构的数据倾斜怎么解决?
    • 热点商品问题——怎么解决并发?
    • MQ丢消息怎么解决?
    • MQ消息积压怎么解决?
    • 解决MQ下单消息重复消费幂等机制
    • Redis集群崩溃时如何保证秒杀系统高可用
      • 第一步:设计高可用的Redis集群
        • 1. Redis主从复制
        • 2. Redis Sentinel
        • 3. Redis Cluster
      • 第二步:秒杀系统的高可用设计
        • 1. 分布式架构
        • 2. 限流和排队
        • 3. 异步处理
      • 第三步:应对Redis集群崩溃
        • 1. 降级处理
        • 2. 数据同步
    • Redis主从切换导致库存同步异常以及超卖问题
    • MQ集群崩溃时如何保证秒杀系统高可用
    • 秒杀链路中Redis与MQ如何保证事务一致性

1、高并发场景秒杀抢购超卖Bug实战重现
2、阿里巴巴内部高并发秒杀下单方案首次揭秘
3、基于Redis与MQ实现秒杀下单架构
4、十万订单每秒热点数据架构优化实践
5、秒杀下单MQ如何保证不丢消息
6、解决MQ下单消息重复消费幂等机制详解
7、线上MQ百万秒杀订单积压优化实战
8、Redis集群崩溃时如何保证秒杀系统高可用
9、Redis主从切换导致库存同步异常以及超卖问题
10、MQ集群崩溃时如何保证秒杀系统高可用
11、秒杀链路中Redis与MQ如何保证事务一致性

三高——高并发、高可用、高可扩展

秒杀系统一般单独部署,省的影响其他服务,
在这里插入图片描述

在这里插入图片描述
这样的秒杀,在高并发情况下会产生超卖的情况,怎么办?

用数据库乐观锁解决超卖

在这里插入图片描述
数据库上千的并发已经是极限了,虽然没加分布式锁(分布式锁性能更差劲),那希望性能继续提升怎么办?

阿里巴巴:为了提升数据库性能,对数据库的源码级别做了改造——在DB内部实现内存队列,一次性接收很多的请求,一次性更新。

一般公司是没能力改这个的。

京东:redis,mq,也有用缓存的

先看一个用redis简单实现的
在这里插入图片描述
异步下单,下单的时候没有操作数据库,性能就提高了,先给用户返回抢购成功,前面加一个转圈圈的过程,后面的交给MQ,前段可以定时的往后端发送是否下单成功,直到查询到下单成功在跳转到支付页面。
在这里插入图片描述
但现在的方案,每秒能支撑十万的并发吗?——显然不行。
redis理论上每秒十万的请求(一般只有查询,等等等条件下)。

redis集群架构部署

在这里插入图片描述
redis集群,数据是分片存储的——有哈希分片算法
一个redis读写混合并发,撑死也就两三万。
那我们把秒杀商品均匀的分配到不同的redis节点上,理论上,只要节点足够多,可以抗住十万的并发,但是实际上,万一分片的全都到一个节点上了,就不行了
在这里插入图片描述

redis集群架构的数据倾斜怎么解决?

  1. 预热商品缓存的时候我们是清楚的,万一在预热的时候发生数据倾斜了,就通过一些命令把一部分数据迁移到其他节点上去,尽可能均匀分配。
  2. HashTag,在key前面加上HashTag,这样也可以解决数据倾斜

但是还有问题——热点商品也会导致某一个节点并发过量

热点商品问题——怎么解决并发?

做缓存预热的时候就应该把这个商品拆分开
在这里插入图片描述
可以做数据的分片,是对一个商品的库存做分片。

再看看这样的秒杀系统,还有什么问题?
在这里插入图片描述

MQ丢消息怎么解决?

肯定有丢消息的可能,不同的MQ有不同的方案

简单点的方案,在发MQ消息之前,存一份到消息发送表,等处理完成后在回去修改消息发送表。

在这里插入图片描述
虽然不至于丢,但是毕竟操作数据库了,并发肯定不高。
针对不同的MQ做对应的MQ消息丢失的方案

MQ消息积压怎么解决?

消息积压会导致前端一直转圈圈(哈哈哈),但是等十来分钟你会等吗?

插DB慢,我们可以插redis,那查的话怎么查询?如果查DB找不到,就找Redis
如果收到message的发送时间和当前的处理时间太长了,快速的插入到redis。这是临时的处理方案,最终后台还是要同步到DB的。

如何解决消息队列的延时以及过期失效问题?消息队列满了以后该怎么处理?有几百万消息持续积压几小时,说说怎么解决?

你看这问法,其实本质针对的场景,都是说,可能你的消费端出了问题,不消费了;或者消费的速度极其慢。接着就坑爹了,可能你的消息队列集群的磁盘都快写满了,都没人消费,这个时候怎么办?或者是这整个就积压了几个小时,你这个时候怎么办?或者是你积压的时间太长了,导致比如 RabbitMQ 设置了消息过期时间后就没了怎么办?

所以就这事儿,其实线上挺常见的,一般不出,一出就是大 case。一般常见于,举个例子,消费端每次消费之后要写 mysql,结果 mysql 挂了,消费端 hang 那儿了,不动了;或者是消费端出了个什么岔子,导致消费速度极其慢。
问题剖析
关于这个事儿,我们一个一个来梳理吧,先假设一个场景,我们现在消费端出故障了,然后大量消息在 mq 里积压,现在出事故了,慌了。
大量消息在 mq 里积压了几个小时了还没解决

几千万条数据在 MQ 里积压了七八个小时,从下午 4 点多,积压到了晚上 11 点多。这个是我们真实遇到过的一个场景,确实是线上故障了,这个时候要不然就是修复 consumer 的问题,让它恢复消费速度,然后傻傻的等待几个小时消费完毕。这个肯定不能在面试的时候说吧。

一个消费者一秒是 1000 条,一秒 3 个消费者是 3000 条,一分钟就是 18 万条。所以如果你积压了几百万到上千万的数据,即使消费者恢复了,也需要大概 1 小时的时间才能恢复过来。

一般这个时候,只能临时紧急扩容了,具体操作步骤和思路如下:

  • 先修复 consumer 的问题,确保其恢复消费速度,然后将现有 consumer 都停掉。
  • 新建一个 topic,partition 是原来的 10 倍,临时建立好原先 10 倍的 queue 数量。
  • 然后写一个临时的分发数据的 consumer 程序,这个程序部署上去消费积压的数据,消费之后不做耗时的处理,直接均匀轮询写入临时建立好的 10 倍数量的 queue。
  • 接着临时征用 10 倍的机器来部署 consumer,每一批 consumer 消费一个临时 queue 的数据。这种做法相当于是临时将 queue 资源和 consumer 资源扩大 10 倍,以正常的 10 倍速度来消费数据。
  • 等快速消费完积压数据之后,得恢复原先部署的架构,重新用原先的 consumer 机器来消费消息。

mq 中的消息过期失效了

假设你用的是 RabbitMQ,RabbtiMQ 是可以设置过期时间的,也就是 TTL。如果消息在 queue 中积压超过一定的时间就会被 RabbitMQ 给清理掉,这个数据就没了。那这就是第二个坑了。这就不是说数据会大量积压在 mq 里,而是大量的数据会直接搞丢。

这个情况下,就不是说要增加 consumer 消费积压的消息,因为实际上没啥积压,而是丢了大量的消息。我们可以采取一个方案,就是批量重导,这个我们之前线上也有类似的场景干过。就是大量积压的时候,我们当时就直接丢弃数据了,然后等过了高峰期以后,比如大家一起喝咖啡熬夜到晚上 12 点以后,用户都睡觉了。这个时候我们就开始写程序,将丢失的那批数据,写个临时程序,一点一点的查出来,然后重新灌入 mq 里面去,把白天丢的数据给他补回来。也只能是这样了。

假设 1 万个订单积压在 mq 里面,没有处理,其中 1000 个订单都丢了,你只能手动写程序把那 1000 个订单给查出来,手动发到 mq 里去再补一次。

mq 都快写满了
如果消息积压在 mq 里,你很长时间都没有处理掉,此时导致 mq 都快写满了,咋办?这个还有别的办法吗?没有,谁让你第一个方案执行的太慢了,你临时写程序,接入数据来消费,消费一个丢弃一个,都不要了,快速消费掉所有的消息。然后走第二个方案,到了晚上再补数据吧。

对于 RocketMQ,官方针对消息积压问题,提供了解决方案。

1. 提高消费并行度
大部分消息消费行为都属于 IO 密集型,即可能是操作数据库,或者调用 RPC,这类消费行为的消费速度在于后端数据库或者外系统的吞吐量,通过增加消费并行度,可以提高总的消费吞吐量,但是并行度增加到一定程度,反而会下降。所以,应用必须要设置合理的并行度。如下有几种修改消费并行度的方法:

同一个 ConsumerGroup 下,通过增加 Consumer 实例数量来提高并行度(需要注意的是超过订阅队列数的 Consumer 实例无效)。可以通过加机器,或者在已有机器启动多个进程的方式。提高单个 Consumer 的消费并行线程,通过修改参数 consumeThreadMin、consumeThreadMax 实现。
2. 批量方式消费
某些业务流程如果支持批量方式消费,则可以很大程度上提高消费吞吐量,例如订单扣款类应用,一次处理一个订单耗时 1 s,一次处理 10 个订单可能也只耗时 2 s,这样即可大幅度提高消费的吞吐量,通过设置 consumer 的 consumeMessageBatchMaxSize 返个参数,默认是 1,即一次只消费一条消息,例如设置为 N,那么每次消费的消息数小于等于 N。

3. 跳过非重要消息
发生消息堆积时,如果消费速度一直追不上发送速度,如果业务对数据要求不高的话,可以选择丢弃不重要的消息。例如,当某个队列的消息数堆积到 100000 条以上,则尝试丢弃部分或全部消息,这样就可以快速追上发送消息的速度。示例代码如下:

public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,ConsumeConcurrentlyContext context) {long offset = msgs.get(0).getQueueOffset();String maxOffset =msgs.get(0).getProperty(Message.PROPERTY_MAX_OFFSET);long diff = Long.parseLong(maxOffset) - offset;if (diff > 100000) {// TODO 消息堆积情况的特殊处理return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;}// TODO 正常消费过程return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}

4. 优化每条消息消费过程
举例如下,某条消息的消费过程如下:

•根据消息从 DB 查询【数据 1】•根据消息从 DB 查询【数据 2】•复杂的业务计算•向 DB 插入【数据 3】•向 DB 插入【数据 4】

这条消息的消费过程中有 4 次与 DB 的 交互,如果按照每次 5ms 计算,那么总共耗时 20ms,假设业务计算耗时 5ms,那么总过耗时 25ms,所以如果能把 4 次 DB 交互优化为 2 次,那么总耗时就可以优化到 15ms,即总体性能提高了 40%。所以应用如果对时延敏感的话,可以把 DB 部署在 SSD 硬盘,相比于 SCSI 磁盘,前者的 RT 会小很多。

解决MQ下单消息重复消费幂等机制

发消息重复了,重试一次,但实际上成功了,又发了一次,

重复消费会带来的问题呢?如果消费者的业务逻辑是执行一个查询的逻辑,那么无论消费几次,这对于业务来说是没有太大的影响的,但如果消费者的业务逻辑是向数据库中插入一条数据,那么重复消费将会导致至少插入两条相同的数据,自然导致了数据的异常。

那么幂等是什么意思呢?幂等(idempotent、idempotence)实际上是一个数学与计算机学概念,在编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同,通俗点说就是:同样的参数或者数据去调用同一个接口,无论重复调用多少次,总能保证数据的正确性,不能出错,这就是接口的幂等性。这里“数据的正确性”和具体的业务相关,不同的业务,对于幂等性的定义是不一样的。

基于幂等性的要求,我们需要改造业务处理逻辑,使得在重复消息的情况下也不会影响最终的结果。怎么改造呢?这得结合具体的业务来考虑:

  1. 如果一个业务是只读业务,或者是更新的业务,那么多次读取或者多次更新相同的数据基本上都没什么问题。
  2. 如果业务需要插入数据,但是插入的数据中有唯一key能够区分(比如订单id,或者生产者生成的token),那么业务逻辑就可以变成在插入前先查询这个唯一key是否在数据库中,如果消费方的业务表不需要存储这个key,那么消费方也可以单独建立一张唯一key表,插入唯一key表和插入业务表的sql逻辑一定要都在一个事务中,在插入前判断这个唯一key是否在数据库的唯一key表中,如果存在说明此前已经成功消费了这条消息,不再消费,否则就是没有成功消费,继续消费。
  3. 如果业务需要插入数据,但是插入的数据中没有唯一key能够区分,这种是无法完全避免因为多条重复的消息或者一条消息多次重复消费带来的问题。因此最好是让发送消息的同事向消息内容中添加一个唯一的字段,即使消费者方的业务不需要也没关系,因为这样就能的防止重复的消息和重复消费了。
  4. 上面通过数据库的方式来防止重复消费的都属于“强校验”类型,会一定程度上影响数据库性能,通常涉及到金钱的都需要强校验,如果不需要强校验,那么使用Redis来代替也行,比如生产者将id或者token作为key存入Redis,消费者消费时先判断是否存在id或者token,如果存在则消费,消费完毕之后消除key。很多的业务都不需要强校验,比如获取登陆短信验证码的时候,多发送两条,或者发送失败都没关系,我们都遇到过。
    上面的都是通用的办法,但处理重复消费的问题,始终要根据具体业务来考虑自己的解决办法,比如我们公司有很多监听一张表的binlog日志然后将操作同步到另一张表上的场景,这种情况下,某些消费者直接将原始表的id作为同步表的id,这样插入的时候,如果id重复肯定是插入不了的,天然的就保证了消息的幂等性。但有时候,同步的表是使用的自己的自增id,此时就需要在插入之前通过其他唯一的业务字段判断此数据是否已被消费过,如果被消费过,则不执行插入。

Redis集群崩溃时如何保证秒杀系统高可用

第一步:设计高可用的Redis集群

在构建高可用的秒杀系统之前,我们需要首先确保Redis集群本身是高可用的。这可以通过以下几种方式来实现:

1. Redis主从复制

使用Redis的主从复制机制,将主节点的数据复制到多个从节点上。当主节点发生故障时,可以立即切换到一个从节点,确保数据的持久性和可用性。

# Redis主从配置示例
# 主节点配置
bind 127.0.0.1
port 6379
# 从节点配置
replicaof 127.0.0.1 6379
2. Redis Sentinel

Redis Sentinel是Redis官方提供的高可用解决方案,它可以监控Redis集群中的主从节点,并在主节点故障时自动选举新的主节点。

# Redis Sentinel配置示例
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
3. Redis Cluster

Redis Cluster是Redis的分布式解决方案,它将数据分片存储在多个节点上,并提供了自动数据迁移和故障转移功能。

# Redis Cluster配置示例
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-slave-validity-factor 10

选择适合您需求的高可用方案,并确保Redis集群的稳定性和可用性。

第二步:秒杀系统的高可用设计

一旦Redis集群高可用性得到保证,接下来我们将关注秒杀系统本身的高可用性设计。

1. 分布式架构

将秒杀系统设计成分布式架构,将请求分散到多个节点上。这可以通过负载均衡器(如Nginx或HAProxy)来实现,确保请求不会集中在单一节点上。

# Nginx负载均衡配置示例
http {upstream backend {server app1.example.com;server app2.example.com;server app3.example.com;}server {listen 80;location / {proxy_pass http://backend;}}
}
2. 限流和排队

在秒杀活动开始时,可能会涌入大量请求。为了避免系统过载,可以实施请求限流和排队机制。使用Redis的有序集合(Sorted Set)来维护请求的排队顺序,并使用计数器来限制每秒的请求数量。

import redis# 连接到Redis集群
redis_client = redis.StrictRedis(host='redis-cluster-ip', port=6379, db=0)def handle_seckill_request(user_id):# 检查请求是否超过限流阈值if redis_client.incr('seckill_request_count') <= MAX_REQUEST_PER_SECOND:# 将用户加入秒杀队列redis_client.zadd('seckill_queue', {user_id: time.time()})else:# 返回请求失败信息return "秒杀请求过多,请稍后重试"
3. 异步处理

将秒杀请求的处理过程异步化,将请求加入消息队列(如RabbitMQ或Kafka)中,然后由后台任务处理器来执行秒杀操作。这可以降低系统负载,提高响应速度。

# 将秒杀请求加入消息队列
def enqueue_seckill_request(user_id):message_queue.push({'user_id': user_id})# 后台任务处理器
def process_seckill_request():while True:request = message_queue.pop()if request:handle_seckill_request(request['user_id'])

第三步:应对Redis集群崩溃

即使我们已经采取了多种措施来确保Redis集群的高可用性,但仍然有可能发生Redis集群的崩溃。在这种情况下,我们需要采取措施来保证秒杀系统的高可用性。

1. 降级处理

当Redis集群崩溃时,可以采取降级处理策略,将秒杀系统切换到一个临时的、基于数据库的模式。这可以通过配置文件来实现,将数据库作为备用数据源。
比如:rocksDB可以记录操作的流水日志

# 配置文件中的Redis切换策略
if redis_cluster_available:cache = RedisCache()
else:cache = DatabaseCache()
2. 数据同步

在Redis集群恢复之后,需要将数据库中的数据同步回Redis集群,以确保数据的一致性。可以使用数据同步工具或自定义脚本来实现这一过程。

# 数据同步脚本示例
def sync_data_to_redis():database_data = fetch_data_from_database()for key, value in database_data.items():redis_client.set(key, value)

Redis主从切换导致库存同步异常以及超卖问题

Redis的主从是异步同步的,redis的主从异步同步,假设某商品,主节点是100,从节点也是100,这是主节点减一成99,还没来得及同步,但这时候99的主节点挂了,另一个是100的节点成主节点了。在这里插入图片描述
一般互联网公司不解决,但面试官非要问你,要解决怎么办?
——红锁
直接修改redis源码,让主从同步,不仅难度太大,而且性能下降
那么怎么办,我们不搞从节点,全部搞成主节点。

在这里插入图片描述

MQ集群崩溃时如何保证秒杀系统高可用

在这里插入图片描述

秒杀链路中Redis与MQ如何保证事务一致性

在当今互联网时代,秒杀活动成为了各大电商平台吸引用户的重要手段。然而,秒杀活动的高并发场景对系统的性能和稳定性提出了巨大的挑战。为了保证秒杀链路中的事务一致性,我们需要借助Redis和MQ这两个强大的工具。本文将详细介绍Redis与MQ如何保证事务一致性,并给出相应的代码demo。

一、秒杀链路中的事务一致性问题

在秒杀活动中,用户在短时间内涌入系统,同时抢购同一商品,这就会导致高并发的读写请求。而在传统的数据库事务中,由于数据库的读写锁机制,会导致性能瓶颈,无法满足秒杀活动的高并发需求。因此,我们需要寻找一种更高效的解决方案。

二、Redis的应用

Redis是一种高性能的NoSQL数据库,其特点是快速、可持久化、支持多种数据结构等。在秒杀链路中,我们可以利用Redis的原子操作和高速读写特性来保证事务的一致性。

商品库存的管理
在秒杀活动中,商品的库存是一个重要的指标。我们可以将每个商品的库存数量存储在Redis中,并利用Redis的原子操作实现库存的减少和增加。
示例代码:

# 初始化商品库存
redis.set('product:stock', 100)# 减少库存
def decrease_stock():stock = redis.get('product:stock')if stock > 0:redis.decr('product:stock')return Trueelse:return False# 增加库存
def increase_stock():redis.incr('product:stock')

1.用户购买记录的管理
为了防止用户重复购买同一商品,我们需要记录用户的购买信息。同样地,我们可以利用Redis的原子操作和高速读写特性来管理用户的购买记录。
示例代码:

# 记录用户购买记录
def record_purchase(user_id, product_id):redis.sadd('user:%s:purchases' % user_id, product_id)# 检查用户是否已购买过该商品
def check_purchase(user_id, product_id):return redis.sismember('user:%s:purchases' % user_id, product_id)

三、MQ的应用

MQ(消息队列)是一种高效的异步通信机制,可以实现不同服务之间的解耦和削峰填谷。在秒杀链路中,我们可以利用MQ来异步处理订单的生成和支付等操作,从而保证事务的一致性。

订单生成
当用户成功秒杀到商品后,我们可以将生成订单的操作放入MQ中异步处理。这样可以减轻系统的压力,提高响应速度。
示例代码:

# 订单生成
def generate_order(user_id, product_id):# 生成订单逻辑...# 将订单信息放入MQ中mq.push('order', order_info)

2.订单支付
在用户生成订单后,我们可以将订单支付的操作放入MQ中异步处理。这样可以保证订单的支付和库存的减少是原子操作,从而保证事务的一致性。
示例代码:

# 订单支付
def pay_order(order_id):# 订单支付逻辑...# 将支付结果放入MQ中mq.push('pay', pay_result)

四、保证事务一致性的实现

通过Redis和MQ的应用,我们可以实现秒杀链路中的事务一致性。具体的实现步骤如下:

用户请求秒杀商品时,先检查用户是否已购买过该商品,如果已购买,则返回秒杀失败;
如果用户未购买过该商品,则先检查商品的库存是否大于0,如果大于0,则继续执行下一步;
从Redis中减少商品的库存,并记录用户的购买记录;
将生成订单的操作放入MQ中异步处理;
在订单生成的消费者中,处理订单的生成和支付操作,保证订单的支付和库存的减少是原子操作;
在订单支付的消费者中,处理订单的支付结果。
通过以上步骤,我们可以保证秒杀链路中的事务一致性,有效应对高并发场景下的性能和稳定性问题。

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

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

相关文章

【C++ 关键字】const 关键字详解

文章目录 1. const 概念2.常量指针 和 指针常量 的区别2.1 常量指针&#xff08;底层 const&#xff09;2.2 指针常量 (顶层 const) 3.const 关键字的作用4.const 和 define 的区别5.const 总结 1. const 概念 const 是一个关键字&#xff0c;被修饰的值不能改变&#xff0c;是…

AI模型:windows本地运行下载安装ollama运行Google CodeGemma可离线运行数据模型【自留记录】

AI模型&#xff1a;windows本地运行下载安装ollama运行Google CodeGemma可离线运行数据模型【自留记录】 CodeGemma 没法直接运行&#xff0c;需要中间软件。下载安装ollama后&#xff0c;使用ollama运行CodeGemma。 类似 前端本地需要安装 node.js 才可能跑vue、react项目 1…

字节和旷视提出HiDiffusion,无需训练,只需要一行代码就可以提高 SD 生成图像的清晰度和生成速度。代码已开源。

字节和旷视提出HiDiffusion&#xff0c;无需训练&#xff0c;只需要一行代码就可以提高 SD 生成图像的清晰度和生成速度。代码已开源。 支持将图像生成的分辨率提高至40964096&#xff0c;同时将图像生成速度提升1.5至6倍。 支持所有 SD 模型同时也支持 SD 模型的下游模型&…

在Unity中实现分页数据显示和分页控制

参考&#xff1a;用两种简单的方式实现unity的分页效果 using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.Rendering.VirtualTexturing; using UnityEngine.TerrainUtils;public class PageControll…

上网行为审计软件分享|三款热门上网行为监控软件推荐

“小王&#xff0c;去找一款软件给我们公司安上&#xff0c;你去搜上网行为审计软件&#xff0c;看看买哪家合适” 这是某公司老板交给助理的一项工作&#xff0c;原话是这样的。 可见其实这类软件大多是人还是比较陌生的。 上网行为审计软件顾名思义就是对上网行为也就是电…

PTA|小字辈

题目 本题给定一个庞大家族的家谱&#xff0c;要请你给出最小一辈的名单。 输入格式&#xff1a; 输入在第一行给出家族人口总数 N&#xff08;不超过 100 000 的正整数&#xff09; —— 简单起见&#xff0c;我们把家族成员从 1 到 N 编号。随后第二行给出 N 个编号&#x…

streamlit通过子目录访问

运行命令&#xff1a; streamlit hello 系统默认使用8501端口启动服务&#xff1a; 如果想通过子目录访问服务&#xff0c;可以这么启动服务 streamlit hello --server.baseUrlPath "app" 也可以通过以下命令换端口 streamlit hello --server.port 9999 参考&…

面试题:String类型长度有限制吗?最大多少?

简介 Java中String是有长度限制的。String还有长度限制?是的有,而且在JVM编译中还有规范,String长度限制的场景(将某固定文件转码成Base64的形式用字符串存储,在运行时需要的时候在转回来,当时文件比较大),那这个规范限制到底是怎么样的,我们分析下。 …

Unreal游戏GPU参数详解,游戏性能优化再升级

UWA GOT Online For Unreal GPU模式近期全新发布&#xff0c;方便开发者从渲染和带宽的角度进行GPU分析。同时&#xff0c;此次更新中UWA也增加了丰富的GPU参数&#xff0c;涵盖了GPU SoC和GPU Counter模块。这些新增的参数不仅能够帮助Unreal开发者从宏观层面监控GPU的压力状况…

12V系统车灯电源口浪涌过压防护方案及保护器件选型推荐

12V系统车灯驱动电源口浪涌过压防护方案图 12V系统车灯驱动电源口浪涌过压防护方案详解 从图中可知&#xff0c;方案针对车灯驱动电路电源输入口的浪涌过压保护。在车载12V系统中&#xff0c;电源线上面的瞬态浪涌主要来源于抛负载。在12V系统车灯驱动电源输入端&#xff0c;东…

怎么把图片尺寸在线修改?5种方法调整方式介绍

在日常生活和工作中&#xff0c;我们经常遇到需要调整图片尺寸的情况&#xff0c;无论是为了适应自媒体文章内容中的图片、还是上传社交媒体平台要求&#xff0c;调整图片尺寸是一项非常有用的技能。在本教程中&#xff0c;我们将介绍几个方便快捷的图片处理工具&#xff0c;帮…

MySql数据库(概念篇)

数据库概念 什么是数据库 数据库见名之意&#xff0c;就是用来存储数据的仓库&#xff0c;是一个长期存储在计算机内的、有组织的、可共享的、统一管理的大量数据的集合。 没接触数据库之前&#xff0c;一般都是将数据存储在文件中。比如execl文件&#xff0c;word文件中。但是…

Django之单文件上传(以图片为例)

一&#xff0c;创建项目 初始化&#xff0c;数据迁移&#xff0c;创建superuser&#xff0c;创建app等 二&#xff0c;配置settings.py 1&#xff0c;配置数据库&#xff08;本作者使用的mysql&#xff09;&#xff0c;以前文章有提到 2&#xff0c;配置静态文件存放路径 STAT…

计算机毕业设计 | springboot+vue小米商城 购物网站管理系统(源码+论文+讲解视频)

1&#xff0c;项目背景 国家大力推进信息化建设的大背景下&#xff0c;城市网络基础设施和信息化应用水平得到了极大的提高和提高。特别是在经济发达的沿海地区&#xff0c;商业和服务业也比较发达&#xff0c;公众接受新事物的能力和消费水平也比较高。开展商贸流通产业的信息…

纯血鸿蒙APP实战开发——Canvas实现模拟时钟案例

介绍 本示例介绍利用Canvas 和定时器实现模拟时钟场景&#xff0c;该案例多用于用户需要显示自定义模拟时钟的场景。 效果图预览 使用说明 无需任何操作&#xff0c;进入本案例页面后&#xff0c;所见即模拟时钟的展示。 实现思路 本例的的主要实现思路如下&#xff1a; …

最新版Ceph( Reef版本)块存储简单对接k8s

当前ceph 你的ceph集群上执行 1.创建名为k8s-rbd 的存储池 ceph osd pool create k8s-rbd 64 642.初始化 rbd pool init k8s-rbd3 创建k8s访问块设备的认证用户 ceph auth get-or-create client.kubernetes mon profile rbd osd profile rbd poolk8s-rbd部署 ceph-rbd-csi c…

Origin拟合EIS(电化学阻抗谱),怎么出来圆圈

1.先导入数据&#xff0c;以点图的形式画出来 2.重要的一步Fitting&#xff0c;按照我这个一步一步来就行 3.将其中的Function选择为Elipse&#xff0c;然后点拟合至最佳条件 4.第三步做完就会发现圆圈已经出来了&#xff0c;然后点OK就行 5.搞定

数仓开发中期:理论巩固

一、数仓以及商业智能&#xff08;Data Warehousing and Business Intelligence, DW/BI&#xff09;系统 1.1数据操作和数据获取的区别 对所有组织来说&#xff0c;信息都是其最重要的财富之一。信息几乎总是用作两个目的:操作型记录的保存和分析型决策的制定。简单来说&…

pytest教程-38-钩子函数-pytest_runtest_protocol

领取资料&#xff0c;咨询答疑&#xff0c;请➕wei: June__Go 上一小节我们学习了pytest_collection_finish钩子函数的使用方法&#xff0c;本小节我们讲解一下pytest_runtest_protocol钩子函数的使用方法。 pytest_runtest_protocol 钩子函数在 pytest 运行单个测试用例之前…

内容安全(IPS入侵检测)

入侵检测系统&#xff08; IDS &#xff09;---- 网络摄像头&#xff0c;侧重于风险管理&#xff0c;存在于滞后性&#xff0c;只能够进行风险发现&#xff0c;不能及时制止。而且早期的IDS误报率较高。优点则是可以多点进行部署&#xff0c;比较灵活&#xff0c;在网络中可以进…