中间件复习之-消息队列

消息队列在分布式架构的作用

消息队列:在消息的传输过程中保存消息的容器,生产者和消费者不直接通讯,依靠队列保证消息的可靠性,避免了系统间的相互影响。
主要作用:

  • 业务解耦
  • 异步调用
  • 流量削峰

业务解耦

将模块间的 RPC调用改为通过消息队列中转,解除系统间的耦合。

  • 提升系统稳定性(自身模块不受其他模块影响)
  • 通过广播消息避免多次调用(调用下游多次改为下游自己订阅,自己只发一次消息通知)
  • 提高编码效率(不用关注下游代码更改)
    在这里插入图片描述

异步调用

对于无需关注调用结果的场景,可以通过消息队列异步处理。
下单链路的通知卖家以及数据记录都可以改为异步流程,不影响主流程。
下单处理原逻辑:风控拦截->扣减库存->通知卖家->记录数据
下单优化后流程:风控拦截->扣减库存->消息异步通知卖家->消息异步记录数据
在这里插入图片描述
在这里插入图片描述

流量削峰

系统的吞吐量往往取决于底层存储服务的处理能力,数据访问层可以调整消费速度缓解存储服务压力,避免短暂的高峰将系统压垮。
在这里插入图片描述

主流消息队列选型对比

  • Kafka:系统间的数据流通道
  • RocketMQ:高性能可靠消息传输
  • RabbitMQ:可靠消息传输
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

RocketMQ深入剖析

RocketMQ功能特性

  • 支持事务型消息
  • 支持延时消息
  • 支持消息重发
  • 支持consumer端tag过滤
  • 支持消息回放

RocketMQ拓扑图

  • NameServer: 类似注册中心的定位。他们之间完全独立,互相没有交互。所有的broker把自己的信息注册到所有的NameServer上(IP、key-cluser-value-[brokers]、key-broker-value-主从节点、key-topic-value-[brokers],可以后面把这个结构debug一下放到这里todo)。
  • Broker:用于消息存储
  • Producer:生产者,投递消息到broker上。从NameServer做服务发现。
  • Consumer:消费者,从broker上消费消息。从NameServer做服务发现。
    在这里插入图片描述

RocketMQ架构

  • Broker主从部署,自身注册信息在NameServer中
  • Client(Producer、Consumer)从NameServer中获取Broker信息
  • NameServer节点相对独立,无数据交互
    在这里插入图片描述

RocketMQ消息存储

在这里插入图片描述

  • CommitLog:存储消息主体
    • 所有topic的消息都写在CommitLog文件中
    • 顺序写、随机读,当某几个topic的消费速度比较快的时候数据就相对比较离散,怎么去优化?
  • ConsumeQueue:消息消费队列
    • dispatch线程将CommitLog里的消息按主题-topic分发到ConsumeQueue队列里(ConsumeQueue也是物理文件,一个topic可能对应多个ConsumeQueue队列,注1:这里的负载均衡是Producer做的,每个消息都会带上要存储的队列序号。注2:这里只存储commitLog的偏移量-commitLogOffset和大小msgSize,实际消费时还是去CommitLog里拿
    • maxOffset:下次消息往这里写。
    • cusomerOffset:消费者当前消费到的位置。
    • minOffset:rocketMQ使用这个字段保证消息不丢。consumer消费每次会拉一批数据,拉完之后就会更新cusomerOffset,但是minOffset到cusomerOffset之间还存在没消费完的。当consumer成功把所有拉去的数据消费完之后,会给broker发一个ack,此时minOffset才会移动到上次拉走数据的位置。这样能保证拉走的数据都能成功消费完。比如consumer拉了10条数据,但是只消费了9条,然后cosumer端服务挂了重启之后就会从minOffset再去拉数据。
  • IndexFile:消息索引文件

优化手段

RocketMQ应对CommitLog随机读顺序写的性能优化

  • CommitLog切分,默认1G
  • MMap提升文件访问性能
  • 磁盘升级SSD

消息存储流程

broker消息接收入口
  • 获取主题信息
  • 获取队列信息
  • 延时消息,事务消息处理
    在这里插入图片描述
CommitLog写入
  • 获取CommitLog文件
    • 判断CommitLog是不是满了,满了就获取一个新的CommitLog(对应代码mapedFile)
  • 追加写入
    • 写入不成功则创建新文件
  • 刷盘
  • 复制
    在这里插入图片描述
Dispatch消息分发
  • 获取消息类型,如延时消息、事务消息
  • 普通消息则获取消息信息
    • topic、队列id、大小等
  • 通过主题和队列id找到队列
  • 往队列里写值
    在这里插入图片描述

特性分析

  • 可靠性分析
  • 可用性分析
  • 生产、消费方式
  • 负载均衡

可靠性分析

可靠性的问题主要是存的数据会不会丢? 按需配置

单机情况下的优化
  • 同步刷盘
    • 性能低,可靠性高
  • 异步刷盘
    • 性能高,可靠性低
      在这里插入图片描述
集群下的优化

这里主要是主从之间的数据同步

  • 异步复制
    • 生产者发送消息至master后,master就会反馈给生产者消息发送成功。master会单独开启一个线程,将数据copy到slave中。这样造成的风险就是如果master挂了,而数据还没有copy到slave节点,就会造成数据的丢失。
  • 同步双写
    • 生产者发送消息至master节点后,master节点copy数据到slave节点。当copy成功时,master节点才会告诉生产者,消息发送成功。这样保证了数据的备份,但是会影响性能。为了高可用,还是要选择这种模式,因为选用异步模式,根本没解决多master模式所造成的问题。

最可靠的方式就是 同步刷盘+同步双写。一般情况下用异步刷盘、异步复制就够了。

可用性分析

这里需要引入RocketMQ集群架构
公司目前使用rocketMQ,raft协议Dledger搭建集群。
RocketMQ Dledger高可用集群的Leader消息写入是同步刷盘的方式。在Dledger中,当Leader节点收到消息后,会首先将消息写入本地磁盘并进行同步刷盘,以保证数据的可靠性和一致性。只有当消息被成功写入本地磁盘后,Leader节点才会将消息发送给Follower节点进行复制。
而在Dledger中,Leader和Follower之间的同步是异步复制的方式。当Leader节点将消息写入本地磁盘并进行同步刷盘后,会异步地将消息发送给Follower节点进行复制。这样可以提高消息发送的性能和吞吐量。

普通集群:

  • Master
    • 主节点,可以进行读和写操作。
  • Slave
    • 从节点,只可以读,不进行写操作。

也就是 Producer 只能和 Master 角色的 Broker 连接写入消息;Consumer 可以连接 Master 角色的 Broker,也可以连接 Slave 角色的 Broker 来读取消息。

Master 和 Slave 的区别:在 Broker 的配置文件中,参数 brokerId 的值为 0 表明这个 Broker 是 Master,大于 0 表明这个 Broker 是 Slave,同时 brokerRole 参数也会说明这个 Broker 是 Master 还是 Slave。

  • 主从模式Master宕机
    • Broker可读不可写
  • 集群搭建方式
    • 单Master模式(线上一般不考虑)
    • 多Master模式
      • 优点:多master集群,一个topic在每个master中都有,相当于对topic进行了横向扩展。当有很多生产者往topic中发送消息时,可以负载到多个master节点上,提高写入数据的效率。
      • 缺点:如果某个master宕机,则这个master上的数据将不可用。根本原因还是没有对master上的数据进行主从备份的原因。多个master节点各自存着自己的数据,不会相互备份。如当主1挂了、主2还在时,主2还可以投递,但是主1没消费完的消息就丢失了,直到主1恢复以后才能继续消费。
  • 多Master模式多Slave模式-异步复制
  • 多Master模式多Slave模式-同步双写
RcoketMQ普通集群与Dledger高可用集群

普通集群:
这种集群模式下会给每个节点分配一个固定的角色,master负责响应客户端的请求,并存储消息。slave则只负责对master的消息进行同步保存,并响应部分客户端的读请求。消息同步方式分为同步同步和异步同步。这种集群模式下各个节点的角色无法进行切换,也就是说,master节点挂了,这一组Broker就不可用了。

Dledger高可用集群:
Dledger是RocketMQ自4.5版本引入的实现高可用集群的一项技术。这个模式下的集群会随机选出一个节点作为master,而当master节点挂了后,会从slave中自动选出一个节点升级成为master。Dledger技术做的事情:

  1. 接管Broker的CommitLog消息存储,普通集群是由broker自己去写CommitLog消息存储,现在是由Dledger去写CommitLog消息存盘
  2. 从集群中选举出master节点,Dledger最主要的功能
  3. 完成master节点往slave节点的消息同步

Dledger是怎样进行leader选举的呢?
在探究这个问题之前,我们先要明确一件事情,Dledger使RocketMQ集群的每个节点都有三个状态:

  1. **Leader 主节点:**主要用于接收客户端请求
  2. **Follower 从节点 :**主要用于Leader节点的数据备份,当有客户端请求到Follower时,Follower节点会把请求转到Leader节点
  3. **Candidate 候选者节点:**只有Candidate状态的节点才会参与主节点的选举。

原文链接:https://blog.csdn.net/qq_45076180/article/details/113775278

生产方式

  • 同步(sync)
    • 投递完后等待MQ回ACK 生产者一般都用同步的方式去发消息
  • 异步(async)
    • 投递过去后不关注结果
  • 单向(oneway)
    • 投递过去MQ不用回包

消息消费

消息消费一般分Pull和Push的两种消费方式,两种方式都有各自的特点,同时也会带来不同的影响。

  • PUSH
    • 消息队列主动地将消息推送给消费者。
    • 优点:消息实时性高。
    • 缺点:没有考虑到客户端的消费能力,导致客户端消息堆积。
  • PULL
    • 由消费者客户端主动向消息队列拉取消息。
    • 优点:客户端按消费能力拉取消息。
    • 缺点:消息实时性低,可能造成大量无效请求。
RocketMQ消费模式

RocketMQ的消费方式基于拉模式,但是使用了一种长轮询机制,来平衡上面Push/Pull模型的各自缺点。

  • LongPoll
    • Consumer发送拉取消息
    • Broker hold住请求,直到有新消息再返回(类似一个push的动作)
    • 请求超时,Consumer再次发起请求
    • 请求超时时间默认30s
消息消费方式
  • 集群消费
    • 集群内竞争消费,单条消息只消费一次
  • 广播消费
    • 各集群消费全量消息,单条消息在每个集群都会被消费一次
    • 集群内广播消费
      • 集群内每个消费者消费一次消息
    • 大部分场景下都是集群内竞争,集群间广播

负载均衡

  • Producer端负载均衡
  • Consumer端负载均衡
Producer端负载均衡
  • 定时获取Queue信息
    • 从NameServer定时获取队列信息
  • 负载均衡算法:随机递增取模(轮询)
    • 按照队列数量轮询分发
  • 容错机制:故障延迟
    • eg.500ms发送超时,下次发送到这个队列的延迟改为1s。
Consumer端负载均衡
  • 客户端定时上报数据
    • 服务端知道有多少的客户端
  • 定时Rebalance 20S
    • 获取队列信息
    • 获取消费者信息
    • 排序平均分配(按照获得的信息平均分配)在这里插入图片描述
    • 与上次结果对比(左边是本次计算出的队列,entity1、entity2是上次负载均衡计算的结果,需要去除。entity3、entity4是上次就在的,entity5、entity6是本次新分配的)在这里插入图片描述

消息消费失败

消费失败策略

  • 默认重试16次
    • 失败后消息重新投递到重试队列
  • 重试时间间隔递增
  • 失败进入死信队列
    实现原理
  • 自动创建失败消息主题
  • 客户端默认订阅
  • 结合延时消息实现重试间隔 支持18种延时,先进入延时队列,再进入重试队列。默认的一个topic重试队列只有一个,导致只有一个consumer能消费。

RocketMQ高级功能

  • 事务消息
  • 延时消息

事务消息

业务场景分析:

  • 用户下单
    • 创建订单 + 减库存
  • 发布或更新商品信息
    • 写商品库 + 更新外置索引
分布式事务
  • 强一致
  • 柔性事务
  • 事务消息
强一致性协议
  • 一致性协议
    • 两阶段提交 2PC在这里插入图片描述

      • 事务协调者:程序
      • 事务参与者A:数据库A
      • 事务参与者B:数据库B
      • 缺陷:第一阶段没问题,第二阶段假如只commit了事务参与者A,发完后事务协调者挂了,则B未提交。
    • 三阶段提交 3PC在这里插入图片描述

      • 将第二阶段拆成两段,第二阶段对齐事务状态,所有事务参与者在此刻都知道事务可以提交了。
      • 第三阶段参与者等待事务协调者触发,若事务协调者挂了未执行触发。则指定一个超时时间,超过超时时间未触发则事务参与者自动提交。
  • 落地规范
    • XA规范(很少使用,性能衰减严重
      • 资源管理器 - 事务参与者
        • 写入加锁
      • 事务管理器 - 事务协调者
        • 本地记录事务执行状态
柔性事务(最终一致性方案)
  • TCC (Try-Confirm-Cancel)

    • 尝试执行业务,预留资源
    • 确认执行业务,使用Try阶段资源
    • 取消执行业务,释放Try阶段预留的资源
    • TCC成功处理流程在这里插入图片描述
    • TCC失败处理流程在这里插入图片描述
    • 缺点:逻辑全部由开发处理。非常复杂
  • SAGA 模型

    • 一个分布式事务拆分为多个本地事务;
    • 本地事务都有相应的执行模块(commit事务)和补偿模块(对补偿模块做逆操作);
    • 事务管理器负责在事务失败时调度执行补偿逻辑;
事务消息
  • 简化了分布式事务模型
    • 两次RPC调用 -> 一次RPC + 一次事务消息。只保证落DB + 消息发送的事务。
  • 对业务友好
RocketMQ事务消息机制

两阶段提交:

  • 发送半消息
    • 投递到MQ里不会被消费,发送完后MQ返回半消息发送成功通知。
  • 执行本地事务
    • 写db等操作
  • 发送Commit/Rollback
  • 提供回查接口(业务侧提供,缺点就是侵入业务)
    • 如果MQ-server很久都没有接收到业务系统发送commit或者rollback的消息的话,MQ-Server就会做半消息的回查,查业务系统来获取这个Message是该提交还是该Rollback。
      在这里插入图片描述
RocketMQ事务消息原理

半消息主题(Topic)

  • HALF消息:RMQ_SYS_TRANS_HALF_TOPIC(临时存放消息信息)
    • MQ会有一个HALF消息的topic:RMQ_SYS_TRANS_HALF_TOPIC(临时存放消息信息)
    • 在发送消息的时候用半消息的主题替换原主题去做投递,保存原主题和队列信息(数据投递到半消息队列中)
    • 半消息对Consumer不可见,不会被投递
  • OP消息:RMQ_SYS_TRANS_OP_HALF_TOPIC(记录二阶段操作)
    • Rollback:只做记录
    • Commit:根据备份信息重新构造消息并投递
  • 回查
  • 对比HALF消息和OP消息进行回查
    在这里插入图片描述

延时消息

延迟需求:由业务场景或现实情况决定,需要在当前时候之后某一时间触发指定的业务逻辑或操作。
业务场景分析

  • 即时通讯消息重发
    • IM系统为了确保消息触达接收方,消息发出几秒后没有收到ack,需要重发 消息。
  • 订单状态流转
    • 取消规定时间内未付款的订单。商家发货后,长时间未确认的订单自动确认收货。
RocketMQ延时消息

RocketMQ支持18个级别的延时等级,默认值为“1s5s10s30s1m2m3m4m5m6m7m8m9m10m20m30m1h2h”,生产者发消息时通过设置delayLevel选择

客户端调用
  • 消息体里设置延时属性,值为延时的级别
public void setDelayTimeLevel(intlevel{this.putProperty(MessageConst.PROPERTY_DELAY_TIME_LEVEL,String.valueOf(level));
}
实现原理
  • 缓存缓存消息
    • 替换主题SCHEDULE_TOPIC_XXX,根据延时级别放入对应的队列
  • 18个Queue对应18个延时级别
  • 每个队列创建定时任务进行调度
  • 恢复到期消息重新投递到真实的Topic(Delay queue投递到CommitLog)
    在这里插入图片描述
代码分析
  • 替换主题代码
    • 替换主题
    • 根据延时级别放到对应的延时队列中去
      在这里插入图片描述
特点
  • 不支持任意时间延时
  • Broker配置中指定,只支持18个level
  • 不灵活、配置调整需要重启

消息队列拓展功能实现

RocketMQ可扩展功能:

  • 事务消息
    • 业务侵入大
  • 延时消息
    • 支持场景有限

事务消息

  • 通过客户端实现
  • 事务消息表记录发消息事件
    • 数据库每个实例里面都创建一个事务消息表
  • 本地事务保证业务数据与写消息表原子性
  • 事务管理器维护事务消息表
    • 扫库发送、清理
      在这里插入图片描述
      5 - 消息投递成功了,删除消息记录
客户使用示例
  • 本地数据库写入
  • 事务消息客户端发送消息(把落db和发送消息都封装起来)
  • con.getAutoCommit代表本次有没有开启事务。
    在这里插入图片描述
MybatisransactionMsgClient类设计
  • 获取数据库连接
  • 调用sendMsg
    在这里插入图片描述
事务消息客户端实现
  • 消息内容落库

    • con.getAutoCommit代表本次有没有开启事务
  • 发送消息(消息放到队列)
    在这里插入图片描述

  • 后台发送队列设计

    • 发送失败将消息放到优先级队列里
      在这里插入图片描述
  • 发送消息后台任务

    • 因为事务还没处理完队列里就已经有消息了
      在这里插入图片描述
  • 若事务还没提交,则可以将消息放到重试队列。

  • 若消息发送成功,修改数据库状态
    在这里插入图片描述

  • 后台优先队列维护

    • 从队列中取出数据,判断是否到期,到期则重新放入待发送队列
      在这里插入图片描述
  • 事务消息表设计

    • status 是否已投递出去
      在这里插入图片描述

延时消息

时间轮算法

时间轮算法:可以用于高效的执行大量的定时任务,实现简单并且有非常高的精度。

  • 基本概念
    • 事件:可以认为是一个个定时任务,比如下单未支付事件。
    • 桶:每个数组元素可以认为是一个桶,桶内的链表为一个个事件(桶里的事件的特点是同一时刻到期、触发)
    • 游标:指到哪个桶,那这个桶里的事件就要触发了
    • 时间精度:游标移动的速度,1s移动一次,表示支持秒级别的触发。1分钟移动一次,表示支持分钟级别的触发。
    • 循环数组
  • 数据结构
    • 数组+链表
      在这里插入图片描述
长时间跨度问题

如果要支持高精度调度,15天的长度,那数组空间的占用就会非常大!

  • 使用文件+内存的方式处理
    磁盘文件的内容按时间倒序,每个文件存储半小时。若过来一个请求,在当前半小时内的,直接将半小时内的这条数据落在redis,如果在半小时之外的,则落到磁盘文件中。然后每经过半小时时间(提前个5分钟),将文件中的内容读取到redis内存中。
    在这里插入图片描述
延时消息服务端设计
  • Dispatch改造
  • 延时消息存储
    • 使用内存+文件替代RocketMQ原来的18个队列
  • 内存索引(时间轮)
  • 延时消息投递
    在这里插入图片描述
Dispatch改造
  • 拓展消息类型
  • 根据类型标记判断延时消息
  • 根据时间分发到ScheduleLog或内存时间轮
    在这里插入图片描述
延时消息存储设计(ScheduleLog)

存放延时消息的一组文件,将延时消息按到期时间划分,以半小时为一个区间,存放到指定的ScheduleLog文件中。

  • 文件命名:时间 + 偏移量(将文件切分,因为每个时间周期内的ScheduleLog文件大小太不固定了,因此按128M将文件做多个切分,该时段内的时间都一样,偏移量按文件顺序排序)
    • 202002171430(时间)+ 000000000
  • 文件大小:默认128M
  • 存储内容
    • 消息体 OR 消息索引(offset + length)

存储内容是按消息体存还是消息索引存??

  • 消息索引
    • 优点:节省空间
    • 缺点:
      • 随机读
      • CommitLog里的历史文件(15天前)无法删除,而且这15天前的commitLog还得加载到内存里。
        在这里插入图片描述
  • 消息体
    • 消息存两份
    • 避免随机读
      在这里插入图片描述

结论:空间目前不是瓶颈,性能是瓶颈,因此按消息体存储。

ScheduleLog文件管理
  • 大文件切分
    • 一对多
  • 文件命名规则
    • 时间 + 偏移量
      在这里插入图片描述
      一个逻辑上的ScheduleLog文件由多个小文件组成。
      在这里插入图片描述
代码实现
  • DelayLogManager
    • Key:所代表时间;Value:ScheduleLog
      在这里插入图片描述
  • DelayLog
    • 管理一个区间内所有文件
  • mapedFIles(Key:启始偏移量;Value:文件内容
    • 文件名到内存文件映射
      在这里插入图片描述
  • ScheduleLog文件写入
    • 判读是否需要新建文件
      • 根据要写的数据长度来判断
      • 按照DelayLog整体文件维度偏移量与128M大小(mapedFileSize)取余得到当前偏移量
      • 当前偏移量 + 数据大小 + 结束标识长度是否大于mapedFileSize
    • 定位要写入的文件
    • 数据写入
      在这里插入图片描述
      在这里插入图片描述
内存时间轮

TimeWheel: 内存时间轮,其中保存的是30分钟内到期的延时消息索引

  • TimeWheel类

    • 使用Map(Key 消息到期时间,Value 相同时间的消息队列) + Queue
    • addToWheel(DelayMsgIndex delayMsgIndex)
      • 从ScheduleLog中装载数据进时间轮
    • getQueue(long delayEndSecond)
      • 拿到当前到期的队列
    • remove(long delayEndSecond)
      • 投递完之后清空队列
        在这里插入图片描述
  • 时间轮写入在这里插入图片描述

  • 数据装载(非实时写入)

    • 获取当前ScheduleLog
      • 根据时间从delayLog中取出下一个要到期的文件
    • 逐条装载消息索引信息
      • 迭代器逐条读取信息生成索引信息
    • 将索引信息装载到时间轮内
      在这里插入图片描述
  • 实时写入

    • 在当前时段内的消息需要同时写入时间轮
      在这里插入图片描述
  • 到期投递

    • 获取当前ScheduleLog
    • 逐条装载消息索引信息
      在这里插入图片描述

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

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

相关文章

MySQL之创建高性能的索引(八)

创建高性能的索引 覆盖索引 通常大家都会根据查询的WHERE条件来创建合适的索引,不过这只是索引优化的一个方面。设计优秀的索引应该考虑到整个查询,而不单单是WHERE条件部分。索引确实是一种查找数据的高效方式,但是MySQL也可以使用索引来直…

向量数据库引领 AI 创新——Zilliz 亮相 2024 亚马逊云科技中国峰会

2024年5月29日,亚马逊云科技中国峰会在上海召开,此次峰会聚集了来自全球各地的科技领袖、行业专家和创新企业,探讨云计算、大数据、人工智能等前沿技术的发展趋势和应用场景。作为领先的向量数据库技术公司,Zilliz 在本次峰会上展…

【漏洞复现】电信网关配置管理系统 rewrite.php 文件上传漏洞

0x01 产品简介 中国电信集团有限公司(英文名称"China Telecom”、简称“"中国电信”)成立于2000年9月,是中国特大型国有通信企业、上海世博会全球合作伙伴。电信网关配置管理系统是一个用于管理和配置电信网络中网关设备的软件系统。它可以帮助网络管理员…

在线IP检测如何做?代理IP需要检查什么?

当我们的数字足迹无处不在,隐私保护显得愈发重要。而代理IP就像是我们的隐身斗篷,让我们在各项网络业务中更加顺畅。 我们常常看到别人购买了代理IP服务后,通在线检测网站检查IP,相当于一个”售前检验““售后质检”的作用。但是…

2024-5-31 石群电路-19

2024-5-31,星期五,10:53,天气:阴雨,心情:晴。今天就要回学校啦,当大家看到这篇推文的时候我已经要收拾收拾去赶返校的火车啦,和女朋友短暂分别,不过小别胜新婚吗&#xf…

笔记-docker基于ubuntu22.04安装Jitsi Meet

背景 利用JitsiMeet打造一个可以在线会议的环境,根据躺的坑,做个记录 参考 JitsMeet部署安装说明 开始操作 环境 docker run -it --name ubuntu22.04 ubuntu:22.04 /bin/bash问题 1、安装 openjdk-11 apt install openjdk-11-jdk配置环境变量&…

自媒体必用的50 个最佳 ChatGPT 社交媒体帖子提示prompt通用模板教程

在这个信息爆炸的时代,社交媒体已经成为我们生活中不可或缺的一部分。无论是品牌宣传、个人展示,还是日常交流,我们都离不开它。然而,要在众多信息中脱颖而出,吸引大家的关注并不容易。这时候,ChatGPT这样的…

uniapp的tooltip功能放到表单laber

在uniapp中,tooltip功能通常是通过view组件的hover-class属性来实现的,而不是直接放在form的label上。hover-class属性可以定义当元素处于hover状态时的样式类,通过这个属性,可以实现一个类似tooltip的效果。 以下是一个简单的例…

跨境经营的艺术:中资企业海外市场售后服务创新与挑战

出海,已不再是企业的“备胎”,而是必须面对的“大考”!在这个全球化的大潮中,有的企业乘风破浪,勇攀高峰,也有的企业在异国他乡遭遇了“水土不服”。 面对“要么出海,要么出局”的抉择&#xff…

一分钟学习数据安全——自主管理身份SSI基本概念

之前我们已经介绍过数字身份的几种模式。其中,分布式数字身份模式逐渐普及演进的结果就是自主管理身份(SSI,Self-Sovereign Identity)。当一个人能够完全拥有和控制其数字身份,而无需依赖中心化机构,这就是…

FreeRTOS实时系统 在任务中增加数组等相关操作 导致单片机起不来或者挂掉

在调试串口任务中增加如下代码,发现可以用keil进行仿真,但是烧录程序后,调试串口没有打印,状态灯也不闪烁,单片机完全起不来 博主就纳了闷了,究竟是什么原因,这段代码可是公司永流传的老代码了&…

香橙派OrangePi AIpro上手笔记——之USB摄像头目标检测方案测试(三)

整期笔记索引 香橙派OrangePi AIpro上手笔记——之USB摄像头目标检测方案测试(一) 香橙派OrangePi AIpro上手笔记——之USB摄像头目标检测方案测试(二) 香橙派OrangePi AIpro上手笔记——之USB摄像头目标检测方案测试(…

【MySQL数据库】:MySQL复合查询

目录 基本查询回顾 多表查询 自连接 子查询 单行子查询 多行子查询 多列子查询 在from子句中使用子查询 合并查询 前面我们讲解的mysql表的查询都是对一张表进行查询,在实际开发中这远远不够。 基本查询回顾 【MySQL数据库】:MySQL基本查…

【测试】linux快捷指令工具cxtool

简介 登录linux时,我们经常需要重复输入一些指令. 这个工具可以把这些指令预置,需要的时候鼠标一点,会自动按预置的字符敲击键盘,敲击出指令. 下载地址 https://download.csdn.net/download/bandaoyu/89379371 使用方法 1,编辑配置文件,自定义自己的快捷指令。 2…

运算符重载(下)

目录 前置和后置重载前置的实现Date& Date::operator()代码 后置的实现Date Date::operator(int )代码 前置--和后置--重载前置--的实现Date& Date::operator--( )代码 后置--的实现Date Date::operator--(int )代码 流插入运算符重载流插入运算符重载的实现流提取运算…

任何图≌自己这一几何最起码常识推翻直线公理让R外标准实数一下子浮出水面

黄小宁 h定理:点集AB≌B的必要条件是A≌B。 证:若AB则A必可恒等变换地变为BA≌A,而恒等变换是保距变换。证毕。 如图所示R轴即x轴各元点x沿x轴正向不保距平移变为点y2x就使x轴沿本身拉伸(放大)变换为y2x轴不≌x轴&…

校园疫情防控|基于SprinBoot+vue的校园疫情防控系统(源码+数据库+文档)

校园疫情防控系统 目录 基于SprinBootvue的校园疫情防控系统 一、前言 二、系统设计 三、系统功能设计 1系统功能模块 2后台功能模块 5.2.1管理员功能 5.2.2学生功能 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#x…

Linux网络编程:传输层协议|UDP|TCP

知识引入: 端口号: 当应用层获得一个传输过来的报文时,这时数据包需要知道,自己应该送往哪一个应用层的服务,这时就引入了“端口号”,通过区分同一台主机不同应用程序的端口号,来保证数据传输…

【ai】pycharm安装github copilot解决chat一直无法初始化loading的问题

github copilot github-copilot 插件安装后:在工具里找到它 底部也有它 侧边可以chat 更新到2014.1.2copilot 也是最新但是chat 就是一直无法loading成功显示一直在初始化copilot中fix :

python基础-数据结构-int类型——你知道python的最大整数是什么吗?无限大?还是sys.maxsize?

文章目录 int底层源码最大整数推断 int底层源码 python 的int类型貌似并没有一个位数上线,然而我们知道其他语言的整数都是有位数,一般为32位或者64位等,那么python是怎么实现int类型没有位数限制的呢,下面这段代码是cpython仓库…