【场景】高并发解决方案

文章目录

  • 1. 硬件
  • 2. 缓存
    • 2.1 HTTP缓存
      • 2.1.1 浏览器缓存
      • 2.1.2 Nginx缓存
      • 2.1.3 CDN缓存
    • 2.2 应用缓存
  • 3 集群
  • 4. 拆分
    • 4.1 应用拆分(分布式、微服务)
    • 4.2 数据库拆分
  • 5. 静态化
  • 6. 动静分离
  • 7. 消息队列
  • 8. 池化
    • 8.1 对象池
    • 8.2 数据库连接池
    • 8.3 线程池
  • 9. 数据库优化
    • 9.1 配置优化
    • 9.2 索引优化
    • 9.3 执行计划

1. 硬件

  • CPU从32位提升为64位
  • 内存从64GB提升为256GB(比如缓存服务器);
  • 磁盘扩容,1TB扩展到2TB,比如文件系统
  • 磁盘从 HDD(Hard Disk Drive)提升为 SSD(固态硬盘(Solid State Drives)),有大量读写的应用
  • 千兆网卡提升为万兆网卡

但是不管怎么提升硬件性能,硬件性能的提升不可能永无止尽,所以最终还是要靠分布式解决

2. 缓存

2.1 HTTP缓存

2.1.1 浏览器缓存

浏览器缓存是指当我们使用浏览器访问一些网站页面时,根据服务器端返回的缓存设置响应头,将响应内容缓存到浏览器,下次可以直接使用缓存内容或者仅需要去服务器端验证内容是否过期即可(js、css、html、png),这样可以减少浏览器和服务器之间来回传输的数据量,节省带宽,提升性能

比如淘宝:http://www.taobao.com/

第一次访问返回200,第二次刷新访问,返回响应码为304,表示页面内容没有修改过,浏览器缓存的内容还是最新的,不需要从服务器获取,直接读取浏览器缓存即可

在这里插入图片描述

我们也可以在Java 代码中通过设置响应头,告诉浏览器进行缓存

# web static
spring.web.resources.add-mappings=true
spring.web.resources.chain.cache=true
spring.web.resources.chain.enabled=true
# 静态资源在浏览器缓存3600s
spring.web.resources.cache.period=3600
spring.web.resources.static-locations=classpath:/static/

2.1.2 Nginx缓存

Nginx提供了expires 指令来实现缓存控制,比如:

location static {root /opt/static/;expires 1d;//全天
}

当用户访问时,Nginx拦截到请求后先从Nginx本地缓存查询数据,如果有并且没有过期,则直接返回缓存内容

2.1.3 CDN缓存

CDN的全称是Content Delivery Network,即内容分发网络。CDN 是构建在网络之上的内容分发网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。CDN的关键技术主要有内容存储和分发技术

CDN 它本身也是一个缓存,它把后端应用的数据缓存起来,用户要访问的时候,直接从CDN上获取,不需要走后端的 Nginx,以及具体应用服务器Tomcat,它的作用主要是加速数据的传输,也提高稳定性,如果从CDN上没有获取到数据,再走后端的Nginx 缓存,Nginx上也没有,则走后端的应用服务器,CDN主要缓存静态资源(js、css、html、png)

2.2 应用缓存

浏览器 -> CDN -> Nginx -> Redis -> DB

需要缓存的数据:经常需要读取的数据、热点数据(销量高的商品、热搜榜单、网红直播间)、IO瓶颈数据(文件、电影)、计算昂贵的数据、无需实时更新的数据(js/css/html/img),缓存的目的是减少对后端服务的访问,降低后端服务的压力

3 集群

一个单体应用,当访问流量很大无法支撑,那么可以集群部署,也叫单体应用水平扩容,原来通过部署一台服务器提供服务,现在就多部署几台,那么服务的能力就会提升

部署了多台服务器,但是用户访问入口只能是一个,比如www.web.com,所以就需要负载均衡,负载均衡是应用集群扩容后的必须步集群部署后,用户的会话 session 状态要保持的话,就需要实现 session共享。

应用服务器集群、redis集群、MySQL集群(主从复制、读写分离)

4. 拆分

4.1 应用拆分(分布式、微服务)

单体应用,随着业务的发展,应用功能的增加,单体应用就逐步变得非常庞大,很多人维护这么一个系统,开发、测试、上线都会造成很大问题,比如代码冲突,代码重复,逻辑错综混乱,代码逻辑复杂度增加,响应新需求的速度降低,隐藏的风险增大,所以需要按照业务维度进行应用拆分,采用分布式开发

应用拆分之后,就将原来在同一进程里的调用变成了远程方法调用,此时就需要使用到一些远程调用技术: httpClient、hessian、dubbo、webservice等

随着业务复杂度增加,我们需要采用一些开源方案进行开发,提升开发和维护效率,比如 Dubbo、SpringCloud

通过应用拆分之后,扩容就变得容易,如果此时系统处理能力跟不上,只需要增加服务器即可(把拆分后的每一个服务再多做几个集群)

4.2 数据库拆分

读写分离、分库分表(水平/垂直)

5. 静态化

对于一些访问量大,更新频率较低的数据,可直接定时生成静态html页供前端访问,而不是访问jsp面

常用静态化的技术: freemaker、velocity

浏览器只需要请求静态页面,暂时不需要去访问数据库或者缓存来获取数据,浏览器直接加载html页即可,局部使用ajax发起请求更新。先给用户返回静态页面,后续再利用ajax请求数据(比如用户请求电商首页时,先返回纯html,其他的图片、视频资源使用ajax更新,请求地址都写为互联网绝对路径

在这里插入图片描述

页面静态化可以提升网站稳定性,如果程序或数据库出了问题,静态页面依然可以正常访问

还可以延迟加载,根据滚动条的位置加载数据

6. 动静分离

采用比如Nginx实现动静分离,Nginx负责代理静态资源,Tomcat 负责处理动态资源

Nginx的效率极高,利用它处理静态资源,可以减轻后端服务器的压力,动静分离架构示意图:

在这里插入图片描述

Redis的并发量在7w,nginx的并发量在4w,tomcat的并发量在700左右,MySQL在600左右

7. 消息队列

队列的作用就是:异步处理、流量削峰、系统解耦

  • 异步下单:收到用户下单请求,校验后即可给用户返回下单成功,将数据放入消息队列,访问数据库的操作可以后续再做
  • 削峰填谷:请求过多时,将请求数据放到MQ中,业务线程可以以稳定的速度消费,这就防止了高并发请求直接访问业务服务器
  • 定时发送邮件:将数据带上TTL放到MQ中,时间到后转移到死信队列,业务线程从死信队列获取数据,取消订单

异步处理是使用队列的一个主要原因,比如注册成功了,发优惠券/送积分/送红包/发短信/发邮件等操作都可以异步处理

使用队列实现系统解耦,比如最主要的支付操作成功了,发消息通知物流,发票等操作都不用保证实时,无需同步调用这些接口,可以让这些消息入队,使用线程池慢慢处理

使用队列流量削峰,比如并发下单、秒杀等,可以考虑使用队列将请求暂时入队,通过队列的方式将流量削平,变成平缓请求进行处理,避免应用系统因瞬间的巨大压力而压垮。但需要保证入队的请求一定能完成

常见的消息队列产品:ActiveMQ/RabbitMQ/RocketMQ/kafka

  • RabbitMQ、RokectMQ、Kafka的并发量分别在1w、10w、100w
  • ActiveMQ是jms规范下的一个老牌的成熟的消息中间件/消息服务器
  • RabbitMQ/RocketMQ 数据可靠性极好,性能也非常优秀,在一些全融领域、电商领域使用很广泛,RocketMQ是阿里巴巴的
  • kafka主要运用在大数据领域,用于对数据的分析,日志的分析等处理它有可能产生消息的丢失问题,它追求性能,性能极好,不追求数据的可靠性

8. 池化

8.1 对象池

通过复用对象,减少对象创建和垃圾收集器回收对象的资源开销,可以采用commons-pool2实现

实际项目采用对象池并不常见,主要在开发框架或组件的时候会采用

8.2 数据库连接池

Druid、DBCP、C3P0、BoneCP

8.3 线程池

  • Executors.newFixedThreadPool:创建一个固定大小的线程池,可控制并发的线程数,超出的线程会在队列中等待;
  • Executors.newCachedThreadPool:创建一个可缓存的线程池,若线程数超过处理所需,缓存一段时间后会回收,若线程数不够,则新建线程;
  • Executors.newSingleThreadExecutor:创建单个线程数的线程池,它可以保证先进先出的执行顺序;
  • Executors.newScheduledThreadPool:创建一个可以执行延迟任务的线程池;
  • Executors.newSingleThreadScheduledExecutor:创建一个单线程的可以执行延迟任务的线程池;
  • Executors.newWorkStealingPool:创建一个抢占式执行的线程池(任务执行顺序不确定)【JDK 1.8 添加】。
  • ThreadPoolExecutor:最原始的创建线程池的方式,它包含了 7 个参数可供设置,会更加可控。

9. 数据库优化

9.1 配置优化

MySQL Server配置优化: mysqld启动时会加载my.cnf,配置其中的相关配置可以优化server

如果某个二级索引不断被使用,二级索引成为热数据,那么InnoDB会根据在二级索引树上的索引值在构建一个哈希索引来加速搜索(只适用于等值比较)。业务完成后,可以用show engine innodb status查看哈希索引使用频率,若不高可以关闭

  • 根据物理机的条件,合理设置InnoDB log buffer大小(redo log缓存的大小),Innodb_buffer_pool_size(缓存的大小),来减少磁盘I/O次数,因为缓存区大了,在缓冲区工作的时间就长了,redo log的效率就高了
  • 增大并发连接数量和保持连接超时时间
  • MySQL使用select + 线程池的模型,适当增加MySQL线程池中的线程thread_cache_size

9.2 索引优化

  • 选择合适的索引数据结构: 一般使用B+树,若等值查询较多,也可使用自适应哈希索引
  • 选择合适的索引列:选择对查询频率高且区分度高的列作为索引列。区分度越高,索引的效果越好。避免在索引中包含过多重复值或过长的列;
  • 尽量使用聚簇索引:聚簇索引的叶子节点存储了具体的数据,不用在像非聚簇索引一样进行回表查询,所以在查询时,尽量选择聚簇索引。此外对于聚簇索引,数据在索引结构中的位置和物理位置是一致的,访问效率更高
  • 避免过多的索引:索引会占用存储空间,并且在数据更新时需要维护索引,过多的索引会增加维护的开销。只创建必要的索引,避免创建过多的索引;
  • 联合索引符合要符合最左匹配原则、join的连接字段最好用到索引、where过滤字段的区分度是否大、过滤字段避免涉及聚合函数以及类型转换

索引失效的情况

  • 没用到索引导致全表扫描,加了表锁
  • 由于where的过滤字段做了类型转换、聚合函数,没用到索引
  • 索引不合适,导致外部排序
  • select的字段过多,导致回表
  • 联合索引没用到最左侧的字段

表数据量太大,导致查找慢:可以分库分表,或者将一些时间很久远的数据导出到专门的文件服务器中

log buffer和buffer pool太小,刷脏页频率过高

当只需要指定数量数据的时候,可以使用limit提前结束查找,无需扫描全表。limit m,n时最好先用主键id过滤掉前m个数据

9.3 执行计划

参考:【MySQL】分析SQL的几种方式

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

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

相关文章

系列九、对象的生命周期和GC

一、堆细分 Java堆从GC的角度还可以细分为:新生代(eden【伊甸园区】、from【幸存者0区】、to【幸存者1区】)和老年代。 二、MinorGC的过程 复制>清空》交换 1、eden、from区中的对象复制到to区,年龄1 首先,当eden区…

【自动化测试】Appium环境搭建与配置-详细步骤,一篇带你打通...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 1、Node.js环境搭…

异步编程工具Promise与Async/Await:解决前端开发中的嵌套回调地狱

文章目录 Promise:处理异步操作的基本工具Promise.all async/await:更简洁的异步编程方式Promise与async/await的比较结论 当谈及JavaScript中的异步编程时,两个非常常见且强大的工具是Promise和async/await。在本文中,我们将以实…

XD6500S— LoRa SIP模块

XD6500S是一系列LoRa SIP模块,集成了射频前端和LoRa射频收发器SX1262系列,支持LoRa和FSK调制。收发器SX1262系列,支持LoRa和FSK调制。LoRa技术是一种扩频协议,针对LPWAN 应用的低数据速率、超远距离和超低功耗通信进行了优化。通信…

vscode+python开发之虚拟环境和解释器切换

需求情景: 现在我们要开发多个项目比如:项目A,项目B、项目C,他们每个项目需要依赖不同的库。每个项目依赖的解释器也不一样怎么办? 项目A:需要在python3.7环境运行 依赖aadd3.2库 项目B、需要在python3.11…

云原生微服务架构及实现技术

云原生是一种技术理念和架构方法,它充分利用云计算的优势,将应用程序和基础设施进行优化,以适应云环境的特性。云原生的设计原则主要包括弹性、韧性、安全性、可观测性、灰度等,旨在让企业在云环境中实现轻量、敏捷、高度自动化的…

springboot项目的可执行jar以后台本地服务的方式运行在Windows机器上

文章目录 用到的工具先上一个效果图准备可执行文件注册及启动服务 前段时间遇到一个项目,需要我们提供一个驱动控件,可以以后台服务的方式运行在Windows机器上。开始寻找各种解决办法。 最后发现一个不错的解决方式。分享给大家一下。 用到的工具 链接&…

15分钟,不,用模板做数据可视化只需5分钟

测试显示,一个对奥威BI软件不太熟悉的人来开发数据可视化报表,要15分钟,而当这个人去套用数据可视化模板做报表,只需5分钟! 数据可视化模板是奥威BI上的一个特色功能板块。用户下载后更新数据源,立即就能获…

Spring Cloud Netflix微服务组件-Eureka

目录 CAP理论 注册中心对比 为什么注册中心更适合用AP? 分布式系统AP和CP如何取舍? Eureka核心功能点 Euraka server启动的主线流程 总体流程图 EnableEurekaServer 流程图 EurekaServerAutoConfiguration EurekaServerInitializerConfigurat…

《白帽子讲web安全》笔记

第八章 文件上传漏洞 文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力 文件上传后导致的常见安全问题一般有: ❍ 上传文件是Web脚本语言,服务器的Web容器解释并执行了用户上传的脚本&#xf…

准「AI 时代」下,如何衡量程序员的工作效率和生产力?

近 20 家科技、金融和制药公司实施了新的研发效能管理方法,并取得了令人鼓舞的初步结果。 客户报告的产品缺陷减少 20%-30%;员工体验分数提高 20%;客户满意度评分提高 60 个百分点。 大模型和 AIGC 技术催生了软件研发的新范式,也…

推介会如何做好媒体宣传

传媒如春雨,润物细无声,大家好,我是51媒体网胡老师。 推介会是一种专为企业、社会组织和团体、政府等提供的展示自身特点、产品和政策的活动形式,旨在促进交流活动,形成合作,从而带来共同利益。推介会的本…

高压放大器设计要求有哪些内容

设计高压放大器时,需要考虑一系列要求以确保其性能和可靠性。以下是设计高压放大器时的一些重要要求。 输入输出电压范围:高压放大器应具备足够的输入和输出电压范围,以适应特定应用的需求。这包括设计合适的电源供应和电路配置,以…

spark性能调优 | 内存优化

目录 我们先了解一下有哪些内存温馨提示RDD示范(spark版本2.1.1)RDD进行优化Df和Ds进行示范 我们先了解一下有哪些内存 1.storage内存 存储数据,缓存 可预估2.shuffle内存 计算join groupby 不可预估spark1.6之前 静态管理的,spark1.6之…

使用Rust编写爬虫代码来抓取精美的图片

目录 一、引言 二、Rust爬虫框架介绍 三、爬虫代码实现 1、创建Scrapy项目 2、创建Spider 3、定义Item对象 4、修改settings.py文件 5、运行爬虫程序 四、图片抓取与存储 五、优化爬虫性能 六、注意事项 总结 一、引言 网络爬虫是一种自动化的网页访问工具&#x…

python采集小破站视频弹幕

嗨喽~大家好呀,这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 环境使用]: Python 3.8 Pycharm模块使用]: import requests 数据请求 import jieba 分词 import wordcloud 词云 import re 正则通过爬虫程序采集数据 分析数…

口袋参谋:如何找竞争小,优势大的蓝海词?

​ 作为淘宝天猫的中小卖家,99.99%的人都知道流量对于店铺的重要性,如果没有流量的话,店铺是肯定没有销量的。 提高流量的方式有很多种,比如优化宝贝图片、标题、关键词等,由于在淘宝天猫上同一宝贝的竞争力太大了…

2022CCPC绵阳 ACGHM

Dashboard - 2022 China Collegiate Programming Contest (CCPC) Mianyang Onsite - Codeforces C.Catch You Catch Me 题意 思路 首先注意到贡献可以按深度统计,对于每个深度dep,贡献是在dep深度中属于的子树种类数,如果在该深度中子树存在…

PLC电力载波通讯,一种新的IoT通讯技术

前言: PLC-IoT 是 PLC 技术应用在物联场景的创新实践,有效解决电力线路信号干扰、衰减问题,支持 IP 化通信能力,使能终端设备智能化,构建智慧边缘联接。PLC让传统IoT有了更多的连接可能: 电力线通信技术适用的场景包括电力配用电网络、城市智慧路灯、交通路口信号灯、园…

HackTheBox-Starting Point--Tier 2---Archetype

文章目录 一 Archetype测试过程1.1 打点1.2 权限获取1.3 权限提升 二 题目 一 Archetype测试过程 1.1 打点 1.端口扫描 nmap -sV -sC 10.129.192.2522.枚举SMB共享 smbclient -N -L \\\\10.129.192.252\\查看backups,并发现 prod.dtsConfig 文件,在 p…