Springboot2.7整合Swagger3
Springboot2.7整合Swagger3Springboot2.7.x改动较大,Swagger3.0.0也是改动较大,两个一掺和,一堆问题就出来了。 引入依赖12345678910<dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>3.0.0</version></dependency><dependency> <groupId>io.springfox</groupId> <artifactId>springfox-boot-starter</artifactId> <version>3.0.0</version></dependency> 原先的springfox-swagger-ui依赖似乎不需要了。...
缓存穿透、缓存击穿、缓存雪崩是什么?在你的项目中是如何预防和解决这些问题的?
核心前置理解区分穿透和击穿的关键在于: 数据是否存在数据库中? 穿透:数据库中没有数据。 击穿:数据库中有数据。 问题的根源是什么? 穿透:无效的请求或者恶意攻击,导致缓存层永远无法被命中。 击穿:热点数据缓存失效瞬间,大量请求请求数据库。 缓存穿透原因/现象查询一个缓存层和数据库中本来就没有的数据key。每次请求都会打到数据库中,导致数据库压力过大甚至崩溃。 预防/解决方案 布隆过滤器:最推荐,在缓存加一个前置预处理阶段。将所有的key哈希到一个足够的bitmap中,查询时先查询布隆过滤器是否存在,不存在直接返回,减少数据库查询。 缓存空对象:数据库查询结果为空时,也将这个空结果缓存起来并设置一个较短的过期时。 缓存击穿原因/现象缓存中热点key突然失效,大量请求同时访问该key,导致大量请求打到数据库上。(数据库中有这个热点数据) 预防/解决方案 热点数据永不变过期:对热点数据key设置为永不过期,或者设置较长的过期时间,并配合后台线程定时刷新。 互斥锁(Mutex Lock):当热点key失效时,只允许一个线...
Redis持久化机制有哪些?它的优缺点和使用场景?
只针对写操作才会持久化Redis持久化是为了解决内存数据容易丢失的问题。既然是数据恢复,那么恢复的就是数据变化后的状态。而数据只有在写操作之后才有变化。读操作只是查询数据并不会改变数据的状态,所以操作不会被持久化。 RDB(Redis Database)持久化快照(Snapshotting)持久化,在指定的时间间隔内将内存中的数据写入到磁盘。 RDB持久化的触发方式手动触发 SAVE命令:同步保存操作,会阻塞主线程,知道RDB文件生成完毕。生产环境下不推荐使用。 BGSAVE命令:后台异步执行。Redis主线程会fork一个子进程进行RDB文件生成,主线程继续处理客户端响应。只会在fork子进程的时候会有短时的暂停阻塞响应,这是推荐的手动触发的方式。 自动触发 redis_conf配置:通过配置save 规则,当在秒内,触发至少次写操作时,Redis会自动执行一次BGSAVE操作。 123save 900 1: 900秒内至少有一次key被修改。save 300 10: 300秒内至少有个10次key被修改。save 60 10000: 60秒内至少有10000次key被修...
什么是CQRS模式?它解决了什么问题?在什么场景下会考虑使用它?
什么是CQRS ?CQRS(Command Query Responsibility Segregation),命令查询职责分离。它是一种软件架构模式,核心思想是将应用程序写入(命令)和查询(Query)分离。 核心概念命令端(写)负责处理业务逻辑、数据修改,通常是写入关系型数据库 查询端(读)负责处理数据读取逻辑,通常是读取经过优化后的数据,提供高性能的查询。 查询端读取经过优化后得到数据唯一目标就是尽可能高效、快速地满足各种查询请求。 结构上的优化:非规范化与扁平化传统的数据库设计为了减少数据冗余和保证数据一致性,通常会采用规范化(Normalization)的范式。这意味着数据会被分解到多张关联的表中。 读模型则倾向于采用非规范化(Denormalization)和扁平化的结构。 它的目标是: 减少 Join 操作:规范化的数据库在查询时往往需要大量的 JOIN 操作来组合来自不同表的数据。JOIN 操作是耗时的。读模型会把查询经常需要的数据预先组合好,存放在一张或几张“宽表”中,这样查询时可以直接从单张表获取数据,避免复杂的关联查询。 适应特定查询模式:例如,如果你...
实现数据库读写分离有哪几种方式?
方式1:Apache ShardingSphere 实现读写分离(推荐)简介Apache ShardingSphere(前身为 Sharding-JDBC)。ShardingSphere 提供了多种部署模式,其中 ShardingSphere-JDBC 是以 JDBC 驱动的方式嵌入到应用程序中,对应用透明,就像使用普通的 JDBC 连接一样。它通过解析 SQL 语句,自动将读操作路由到从库,写操作路由到主库。 核心思想配置多个数据源在 Spring Boot 配置中定义主库和从库的数据源。 规则配置配置读写分离规则,指定哪个数据源是主库,哪些是从库。 SQL解析和路由ShardingSphere 在底层拦截 JDBC 操作,解析 SQL 语句(SELECT 语句通常路由到读库,INSERT, UPDATE, DELETE 语句路由到写库),然后将请求转发到正确的数据源。 事务处理ShardingSphere 会自动处理读写分离下的事务,确保事务的原子性。 代码实现引入依赖123456789101112131415161718192021222324<dependencie...
在进行数据库查询优化时,除了索引和SQL语句优化,你还会考虑哪些方面?
读写分离将读请求分发到从库,写请求分发到主库,减轻主库的压力。 实现方式,可以参考这篇文章:实现数据库读写分离有哪几种方式? 手动AOP + ThreadLocal实现 通用组件,例如 Apache ShardingSphere QA:上述两种实现方式的比较? QA:AOP的原理? QA:ThreadLocal原理? QA:Apache ShardingSphere的实现原理? QA:主从同步如何实现? 分库分表应对海量数据,分散存储和查询压力。 QA:如何做分库分表? 业务缓存引用Redis等缓存,存储热点数据或者高频查询数据,缓解数据库压力。 QA:如何识别数据位热数据和冷数据? QA:缓存数据淘汰机制? 批量操作批量插入、删除、更新,减少网络IO和事务开销。 慢查询日志分析定期分析MySQL慢日志,找出耗时SQL优化。 QA:如何进行慢SQL查找和分析优化? 数据参数调优调整MySQL的innodb_buffer_pool_size、query_cache_size大小。 QA: 这两个参数是干什么的? 硬件优化优化数据库服务器硬件资源: 升级SS...
事件驱动架构(EDA)在微服务中的优势和挑战是什么?你认为它在未来会有怎样的发展?
对事务驱动架构的理解事件驱动架构(Event-Driven Architecture, EDA)是一种软件架构的模式,通过事件的产生、事件订阅、事件消费来进行业务流转和处理。服务之间通过发布/订阅进行通信,而不是直接调用。 EDA是一种架构模式,MQ是一种实现这种模式的手段。 事件驱动架构的核心组件事件生产者负责生成事件并将其发布出去,它不关心谁会消费这些事件,也不关心消费者的具体逻辑。 事件消费者订阅感兴趣的事件,并在接收到事件时执行相应的业务逻辑,它不关心事件是如何产生的,只关心事件的内容。 事件通道/代理负责接收事件、存储事件,并将事件路由或分发给订阅者。 事件驱动架构的优势高度解耦服务之间完全解耦,生产者无需知道消费者,消费者无需知道生产者。 高扩展性易于增加新的消费者来响应事件,不影响现有服务。 可靠性/高韧性生产者和消费者都是独立运行,即使一方这哪是不可用,事件也不会丢失。 实时性适合处理实时数据流和快速响应业务变化。 事件驱动架构的挑战一致性问题分布式事务一致性需要通过补偿或者本地消息表的方式进行实现,最终一致性。 难以调试和追踪缺乏直...
你知道BFF模式吗?解决了哪些问题?适用于哪些场景?
什么是BFF模式?BFF(Backend For Fronted),后端服务于前端。是一个API网关的特例,为特定的前端(移动端、Web端)提供定制化接口的聚合层。没有前端都有一个专属的BFF服务。 BFF解决了哪些问题?前端数据聚合提供一个聚合服务,避免了前端直接调用多个后端服务接口,减少了复杂性。BFF层从多个微服务中获取数据,进行转换、聚合,形成一个前端容易解析和易读的API数据格式。 前端API细粒度为不同的前端提供不同颗粒度的API,避免了一个大而全的接口。 协议转换数据转换层的功能。如果后端服务提供的API是一个RPC接口,可以通过BFF层进行协议转换为Restful风格接口。 安全和性能优化BFF层针对不同的前端进行认证鉴权、数据脱敏、缓存等,提供安全和性能优化。 BFF适用场景?多端应用iOS、Android、Web、小程序等多端应用,对后端数据结构差异大。 微服务拆分粒度较细后端微服务拆分粒度较细,前端直接调用会非常复杂。
如何通过Kafka实现死信队列?
什么是死信队列?存放那些无法被正确处理的消息。这些消息可能因为格式错误、业务逻辑异常、下游服务不可用导致。 Kafka中没有类似于RabbitMQ那样的内置死信队列。 如果通过Kafka实现死信队列?创建一个独立的专门用于存放消息的死信Topic 工作流程: 消费者判断失败:消费者处理消息时,判断消息无法被正常消费,例如格式错误、消费异常等。 消息转发:将原始消息发送到死信Topic。 死信消费者:启动一个独立的消费者组,专门消费死信消息。例如人工干预、日志记录等。 微服务架构中的作用 故障隔离: 避免因少量异常消息导致整个消费者组阻塞或崩溃。 错误分析: 集中管理异常消息,方便运维人员和开发人员分析错误原因。 数据修复与重试: 对于临时性错误,可以在DLQ中对消息进行修复后重新投递;对于永久性错误,则进行记录和人工处理。 提高系统韧性: 即使部分消息处理失败,也不会影响主业务流程的正常运行。
在Kafka中,你如何处理消息的重复消费和消息丢失问题?请结合实际场景说明
什么是消息重复消费?消费者订阅MQ消费时,收到多条消息内容一致的数据进行处理,对业务造成重复处理。 重复消费的原因有哪些? 生产者重试发送 消费者提交偏移量失败导致重复拉取 如何解决重复消费?唯一ID每条消息的消息体内添加一个全局唯一ID字段(订单号、流水号),在消费数据时查看数据是否被处理过。 数据库唯一索引对业务关键字段创建唯一索引,重复插入会报错。 业务流程状态机业务流程通过状态机流转,每个操作只允许在特定的状态下进行操作。如果之前处理过流转到下一个状态,出现重复消息时因为状态不匹配不处理。 场景:购物支付,即时收到多次支付请求也只扣款一次。 什么是消息丢失?生产者生产的消息无法正确让消费者消费,中间过程出现消息丢失的现象。 消息丢失的原因有哪些?生产者丢失 如果ack设置为0,不等待broker响应确认,消息发送失败 网络抖动 Broker丢失 Leader宕机,消息未及时同步到Follower 消息未及时刷盘。pageCache -> 硬盘 消费者丢失先提交偏移量,后消费时出现异常 如何解决消息丢失?生产者端 ack=all,等待所有的ISR副...

