场景题-1

news2025/6/5 19:11:53

场景题-1

订单到期关闭

1、DelayQueue

无界阻塞队列,用于放置实现了Delayed接口的对象,基于PriorityQueue实现,可用于实现在指定的延迟时间之后处理元素。订单创建后放入队列中,然后使用一个常驻任务不停地执行扫描取出超时订单,理论上可用,但是实际因为DelayQueue是基于JVM内存的,所以订单量大的时候容易OOM,而且数据无法持久化,在机器重启后数据会丢失。虽然配合数据库或者rediis等可以解决持久化问题,但是目前应用基本是集群部署,多个实例上的DelayQueue如何配合使用也是个问题,所以综合来说并不推荐(单机、订单量小可尝试)。

2、时间轮

时间轮可以理解为一种像钟表一样的环形结构,圆环上被划分出许多槽位(粒度可以是毫秒、秒、分钟、小时等),每个槽位上有一个链表用于保存所有到期的任务,随着时间推移指针指向哪个槽位就执行该槽位上的任务,另外引入round(圈数)和分层时间轮的概念来满足不同的任务时间精度。

2.1 使用Netty的HashedWheelTimer我们可以实现一个时间轮,但是和Delay有一样的问题。

2.2 使用Kafka的时间轮,Kafka有很多延时性的操作,延时生产、延时拉取和延时数据删除等,具体实现是Kafka下的TimingWheel类。Kafka的时间轮性能不错,但是实现方式较复杂。

3、定时任务

基于Timer、ScheduledThreadPoolExecutop或者xxx-job这类调度框架实现,注意可能会有一些问题,首先定时任务是把分散的超时订单集中在任务调度那一刻处理,所以时间订单处理时间可能就不精准,而且订单量越大,那么调度任务执行时间长的话时间偏差也就越大,其次大数据量时,定时集中扫表,需要考虑数据库压力,不能影响正常业务。但是一般来说,订单超时关闭这种业务,对时间精确度并不是要求很高,所以需要考虑的主要是定时扫表性能问题。

大数据量库表读表性能问题,首先可以加索引,在state(状态)字段上加索引,这边会牵扯出一个问题,那就是区分度不高的字段加索引是否有用,实际上如果该字段对应的枚举占的比例相差很大,比如订单状态,成功的可能占90%,需要关闭的占10%,这样的我查询这部分需要关闭的数据,他可以过滤掉大部分数据,走索引还是可以大大提升效率的。其次可以考虑使用多线程执行,这种方案要注意的就是做好数据隔离,别重复处理一条数据,处理方案可以是扫表后处理时注意幂等控制(一次和多次请求某一个资源应该具有同样的作用),也可以采用分段处理。最后可以使用备库,扫描备注然后根据id直接去修改主库。

4、MQ方案实现延迟消息

4.1 RocketMQ延迟消息:消息写入Broker之后不会立即被消费,而是在指定时间后才会被消费处理。存在无法自由设置关单时长的问题,RocketMQ并不支持任意时长设置(商业版和最新的5.0版本可支持任意时长)。

4.2 RebbitMQ死信队列:给消息设置TTL但是并不消费,到期后消息进入死信队列(交换机-exchange),监听死信队列的消息进行消费。存在问题:死信队列的对头消息阻塞;实现方案麻烦(依赖RebbitMQ,要创建许多exchange)。

4.3 RebbitMQ插件:基于rebbitmq_delayed_message_exchange插件,消息不是通过死信队列处理,而是直接存入Erkang开发的一个数据库,定时查询需要投递的消息进入x_delayed_message队列中,所以不存在消息阻塞的问题,但是要注意有延迟时间限制,这个插件最长支持大约49天的时间。

***注意:***不建议使用MQ,一是订单量大就会堆积大量的消息,资源浪费,成本提升,而且需要注意的是这里面还会有大量的无效消息,因为大部分订单可能是提前取消和完成支付的;二是延迟时间的限制,特别是B类采购订单长关单期很难满足,另外很重要的是,MQ还是会有丢消息的风险的。

5、redis

5.1 消息监听::配置文件redis.conf中开启监听:notify-keysppace-events Ex,代码中实现KeyExpirationEventMessageListener,不推荐使用,过期的key不能保证被立即删除,也不能保证能立即发出,另外还可能存在消息丢失问题。

5.2 zset:socre设置时间戳+超时时间,member为订单号,zset会按照score排序,开启redis扫描任务,获取当前时间>score的延时任务,拿到订单号进行关单。高并发场景下可能会有多个消费者拿到同一个订单的现象。

6、Reddisson

Reddisson定义了分布式延迟队列RDelayedQueue,RDelayedQueue.offer()方法将消息放入RDelayedQueue,到期后Reddisson会将元素从RDelayedQueue转移到RBlockingDeque,RBlockingDeque.take()方法获取元素。

大量登录请求,JVM调优

登录接口一般并不会携带太多信息,高并发环境下产生的众多小对象会很快被回收,考虑JVM的调优主要就是内存的配置和垃圾收集器(吞吐量和STW)的选择,同时做好GC日志的监控。

1、堆内存设置

一般设置为操作系统内存的一半,比如一台4C8G的机器,那么就设置为4G,初始内存和最大内存建议都为4G,避免内存的频繁扩容和收缩。

-Xms4G -Xmx4G

2、垃圾收集器

新生代频繁GC,兼顾高吞吐量和较短的STW(停顿时间,JVM在执行垃圾回收过程中,所有Java执行线程被暂停的持续时间),考虑使用G1作为垃圾收集器(JDK 9 默认,需要内存最少要4G)。

-XX:+UseG1GC

-XX:MaxGCPauseMillis=150

MaxGCPauseMillis为设置的停顿时间,JVM执行时会尽量在设置的这个时间内完成回收,可以使用jstat查看实际停顿时间,如果实际停顿时间远大于这个设置的时间,就需要重新进行一些配置。

另外,可以设置GC的并发线程数

-XX:ParallelGCThreads=4

-XX: ConcGCThreads=2

3、各区大小设置

G1的内存划分是动态自适应的,但是也可以手动进行一些配置

-XX:G1HeapReagionSize=2m

-XX:G1NewSizePercent=20 //年轻代的初始大小为堆的20%

-XX:G1MaxNewSizePercent=50 //年轻代的最大大小为堆的50%

-XX:G1OldCSetRegionThresholdPercent=10 //老年代的大小为堆的10%

-XX:G1HeapWastePercent=10 //垃圾回收后留下的未使用区域的最大比例为10%

4、日志输出

以上配置还需要根据具体情况进行调整,所以增加日志来观察调整

-XX:+HeapDumpOnOutOfMemoryError //内存溢出时输出快照文件

-XX:HeapDumpPath=/path/to/dump.hprof //堆内存快照文件的存储路径

-XX:+PrintGC //输出GC信息

-XX:+PrintGCDateStamps //输出GC发生时间

-XX:+PrintGCDetails //输出GC详细信息

-Xlog:gc*=info:file=/path/to/logs/gc.log:time,uptime:filecount=10,filesize=100M //gc日志输出路径,设置文件大小和数量

业务请求量突增怎么处理

面对流量的激增的问题要注意区分情况,首先注意甄别是否是正常场景。非正常流量激增可能是被DDOS了(攻击者利用大量“肉鸡”发起大量的正常或非正常的请求,耗尽主机资源或网络资源,从而使被攻击的主机无法为正常用户提供服务,被DDOS时被攻击主机上会有大量等待状态的TCP连接,网络中充斥着大量的无用数据包,主机无法正常与外界通讯并提供服务甚至直接系统死机,在用户看来就是网站无法访问)。而正常的流量提升需要考虑两个方面:一方面是长期的可预期的业务好转,施行长期方案,即设计一个支持高并发的系统,包括架构、性能优化和容错机制等等。另一方面就是短期的热点事件影响,这时短期的简单处理就是扩容,增加集群的服务器数量,提升机器硬件配置等。

重点说下一个高并发系统相关的设计和优化要点:

1、分布式架构

将系统拆解成不同的功能模块部署在不同的机器上,相互之间通过远程调用协同工作,对外提供服务。

2、集群部署

在不同的机器上部署相同的应用或者功能模块,通过负载均衡设备对外提供服务。

3、利用缓存

Redis、Ehcache缓存、NoSql技术,提高数据访问性能

4、异步处理、消息队列

消息队列:解耦、异步、削峰填谷,减少请求响应时间,提高系统吞吐量。

kafka支持发布-订阅模式,每秒可处理百万级数据,使用更简单,当然一些高级功能就需要比较麻烦的配置;ActiveMQ/RoketMQ/RabitMQ同时支持点对点和发布-订阅模式,吞吐量相对小点,功能更多样灵活,但相应的使用起来更复杂。

5、预加载

浏览器提前下载某些资源,减少用户的等待时间。

6、代码优化

6.1、单例

IO处理、数据库连接、配置文件解析等使用单例模式

6.2、批量

如涉及数据库的操作,批量执行

6.3、Future模式

通过Future对象异步获取获取返回值,同时主流程继续处理其他业务逻辑

6.4、使用线程池
6.5、锁优化

减少锁的持有时间(同步代码块);减小锁粒度(如ConcurrentHashMap的分段锁)

6.6、缓存结果

本地缓存或者分布式缓存储存计算结果或者查询结果,减少重复的数据库查询和磁盘IO

6.7、SQL优化
6.7.1 索引失效

针对慢sql,通过explain查看执行计划,注意type、key和extra字段,分别是索引类型,使用的索引和查询时的附加操作,三者结合来看可以看出是否使用了索引,如果有走索引,判断是否走了覆盖索引或者是否全扫描索引树等等。简单来说,key要有值,不能是NULL,type应该是ref、eq_ref、range、const等这几个,extrausing index、using index condition都是可以的。

失效原因:

(1)条件字段没有索引或者不满足最左前缀匹配

(2)索引区分度不高,可能会不走索引

(3)表数据少,直接全表扫描

(4)查询语句中,索引字段用了函数计算或者数据类型不一致等

上述(4)包含sql语句的问题补充如下:

(a)MySql用了函数计算之后索引不是一定会失效,MySql 8.之后引入函数索引。

(b)sql语句使用OR,并且OR两边使用<或>,如果OR两边使用的=的话还是可以走索引的。

(c)sql语句使用LIKE,%在 字符串的首位则不走索引。

(d)隐式类型转换,varchar类型字段查询时使用int类型,索引失效,但是注意int类型字段查询时加了单引号或者双引号,参数会自动转换为int类型,能走索引。

(e)sql语句使用 != ,并不是绝对不走索引,比如用自增主键ID时就可能走索引,这个要看索引的选择和数据分布情况。

(f)sql语句使用 is nt null。

(g)sql语句使用 order by,数据量很小时,直接在内存中排序,不使用索引。

(h)sql语句使用 in, in的值比较多的时候可能就不走索引 了。

6.7.2 多表join或者查询字段太多

MySql的嵌套查询效率较低,如果不用join可以考虑代码作二次查询再进行数据关联处理,或者设计表的时候允许数据冗余或基于join关系做宽表。

6.7.3 数据库连接数不够

常见于热点数据更新,多个update语句会排队获取锁,占用连接资源 ,解决思路有1、基于缓存做数据更新,如redis,2、异步更新或者批量更新

6.7.4 数据库IO或者CPU比较高
6.7.5 深度分页问题

考虑使用子查询以及记录上一页ID的方案

6.8、 数据库优化

6.8.1 合理的数据库索引

6.8.2 分库分表

分库针对并发量大,数据库连接数不够。

分表针对表数据量大,查询性能受到很大影响。

拆分分横向拆分和纵向拆分,横向拆分就是把表中不同的记录放到不同的表中,纵向拆分就是把某条记录的多个字段拆分到不同的表中。

分库分表工具:sharing-jdbc,TDDL,MyCat

6.8.3 读写分离

读请求到从库,写请求到主库,主从库通过主从复制实现数据同步,具体读写分流实现方法有:

(a) 代码分流,在DAO层定义定义多个数据源,在实际进行读或者写操作时利用AOP在业务层或者DAO层方法调用前动态切换数据源。

(b) 借助中间件,sharing-jdbc,TDDL等均支持读写分离

注意问题:主从延迟,针对这个问题可以做一些优化,对于不能接受延迟的读请求,强制读主库。

6.9、限流、熔断、降级
6.10、容错和监控
6.11、全面的性能测试和评估

压力测试和安全测试

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

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

相关文章

实验设计与分析(第6版,Montgomery)第5章析因设计引导5.7节思考题5.5 R语言解题

本文是实验设计与分析&#xff08;第6版&#xff0c;Montgomery著&#xff0c;傅珏生译) 第5章析因设计引导5.7节思考题5.5 R语言解题。主要涉及方差分析&#xff0c;正态假设检验&#xff0c;残差分析&#xff0c;交互作用图。 dataframe <-data.frame( wrapc(17,20,12,9,…

字节新出的MCP应用DeepSearch,有点意思。

大家好&#xff0c;我是苍何。 悄悄告诉你个事&#xff0c;昨天我去杭州参加字节火山方舟举办的开发者见面会了&#xff0c;你别说&#xff0c;还真有点刘姥姥进大观园的感觉&#x1f436; 现场真实体验完这次新发布的产品和模型&#xff0c;激动的忍不住想给大家做一波分享。…

期货反向跟单运营逻辑推导思路

期货反向跟单运营逻辑推导思路 很多刚接触期货反向跟的朋友第一印象就是&#xff1a;这绝对是一个完美的策略&#xff0c;在认知不到位的情况下就开始运营&#xff0c;结果就是赔的稀里哗啦。然后告诉身边所有的人&#xff0c;期货反向跟单不靠谱。 这就是一个很有意思的事情&…

使用 HTML + JavaScript 实现图片裁剪上传功能

本文将详细介绍一个基于 HTML 和 JavaScript 实现的图片裁剪上传功能。该功能支持文件选择、拖放上传、图片预览、区域选择、裁剪操作以及图片下载等功能&#xff0c;适用于需要进行图片处理的 Web 应用场景。 效果演示 项目概述 本项目主要包含以下核心功能&#xff1a; 文…

【灵动Mini-F5265-OB】vscode+gcc工程创建、下载、调试

【前言】 【灵动Mini-F5265-OB】在官方的例程中提供了mdk、IAR的开发环境&#xff0c;使用起来非常方便。有位大佬也提供了一个gcc的示例&#xff0c;但是我使用vscode的keil插件进行工程创建&#xff0c;但是提示pack是对不上的。所以我决定重新创建我的vscode来创建开发环境。…

现代语言模型中的分词算法全解:从基础到高级

基础分词&#xff08;Naive Tokenization&#xff09; 最简单的分词方式是基于空格将文本拆分为单词。这是许多自然语言处理&#xff08;NLP&#xff09;任务中常用的一种分词方法。 text "Hello, world! This is a test." tokens text.split() print(f"Tok…

第十三章 Java基础-特殊处理

文章目录 1.包和final2.权限修饰符和代码块3.抽象类1.包和final 2.权限修饰符和代码块 3.抽象类

【操作系统原理08】文件管理

文章目录 零.大纲一.文件管理0.大纲1.文件管理1.1 **文件属性**1.2 文件内部数据组织1.3 文件之间的组织1.4操作系统提供功能1.5 文件在外存存放 二.文件的逻辑结构0.大纲1.无结构文件2.有结构文件 三.文件目录0.大纲1.文件控制块2.目录结构3.索引节点(FCB改进) 四.文件共享0.大…

图论学习笔记 5 - 最小树形图

我们不废话&#xff0c;直接进入正题&#xff1a;最小树形图&#xff0c;一个名字看起来很高级的东西。 声明&#xff1a;为了便于理解&#xff0c;可能图片数量会有亿点点多。图片尺寸可能有的较大。 概念 最小树形图的英文是 Directed Minimum Spanning Tree。 相信懂英文…

《自动驾驶轨迹规划实战:Lattice Planner实现避障路径生成(附可运行Python代码)》—— 零基础实现基于离散优化的避障路径规划

《自动驾驶轨迹规划实战&#xff1a;Lattice Planner实现避障路径生成&#xff08;附可运行Python代码&#xff09;》 —— 零基础实现基于离散优化的避障路径规划 一、为什么Lattice Planner成为自动驾驶的核心算法&#xff1f; 在自动驾驶的路径规划领域&#xff0c;Lattice…

PyTorch——卷积操作(2)

二维矩阵 [[ ]] 这里面conv2d(N,C,H,W)里面的四个是 N就是batch size也就是输入图片的数量&#xff0c;C就是通道数这只是一个二维张量所以通道为1&#xff0c;H就是高&#xff0c;W就是宽&#xff0c;所以是1 1 5 5 卷积核 reshape 第一个参数是batch size样本数量 第二个参数…

【JavaWeb】SpringBoot原理

1 配置优先级 在前面&#xff0c;已经学习了SpringBoot项目当中支持的三类配置文件&#xff1a; application.properties application.yml application.yaml 在SpringBoot项目当中&#xff0c;我们要想配置一个属性&#xff0c;通过这三种方式当中的任意一种来配置都可以&a…

ubuntu22.04安装taskfile

sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -dsudo mv ./bin/task /usr/local/bin/测试 task --version

遥感影像建筑物变化检测

文章目录 效果1、环境安装2、项目下载3、数据集下载4、模型训练5、模型推理6、推理结果7、批量推理效果 1、环境安装 参考文章 搭建Pytorch的GPU环境超详细 win10安装3DGS环境(GPU)超详细 测试GPU环境可用 2、项目下载 https://gitcode.com/gh_mirrors/ch/change_detectio…

多模态大语言模型arxiv论文略读(103)

Are Bigger Encoders Always Better in Vision Large Models? ➡️ 论文标题&#xff1a;Are Bigger Encoders Always Better in Vision Large Models? ➡️ 论文作者&#xff1a;Bozhou Li, Hao Liang, Zimo Meng, Wentao Zhang ➡️ 研究机构: 北京大学 ➡️ 问题背景&…

汇编语言基础: 搭建实验环境

环境配置 1.Visual Studio 创建空项目 创建成功 2.平台框架改为为WIN32 右键点击项目 点击属性 点击配置管理器 平台改为Win32(本文使用32位的汇编) 3.生成采用MASM 在项目属性里点击"生成依赖项"的"生成自定义" 勾选 masm 4.创建第一个汇编程序 右…

基于springboot的益智游戏系统的设计与实现

博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业六年&#xff0c;熟悉各种主流语言&#xff0c;精通java、python、php、爬虫、web开发&#xff0c;已经做了六年的毕业设计程序开发&#xff0c;开发过上千套毕业设计程序&#xff0c;没有什么华丽的语言&#xff0…

第十二节:第四部分:集合框架:List系列集合:LinkedList集合的底层原理、特有方法、栈、队列

LinkedList集合的底层原理 LinkedList集合的应用场景之一 代码&#xff1a;掌握LinkedList集合的使用 package com.itheima.day19_Collection_List;import java.util.LinkedList; import java.util.List;//掌握LinkedList集合的使用。 public class ListTest3 {public static …

多模态大语言模型arxiv论文略读(104)

Talk Less, Interact Better: Evaluating In-context Conversational Adaptation in Multimodal LLMs ➡️ 论文标题&#xff1a;Talk Less, Interact Better: Evaluating In-context Conversational Adaptation in Multimodal LLMs ➡️ 论文作者&#xff1a;Yilun Hua, Yoav…

【C++高级主题】多重继承下的类作用域

目录 一、类作用域与名字查找规则&#xff1a;理解二义性的根源 1.1 类作用域的基本概念 1.2 单继承的名字查找流程 1.3 多重继承的名字查找特殊性 1.4 关键规则&#xff1a;“最近” 作用域优先&#xff0c;但多重继承无 “最近” 二、多重继承二义性的典型类型与代码示…