高并发解决方案

导读

优秀程序员奋斗目标:实现高并发、高性能、高可用 的“三高”分布式系统

衡量高并发常用的一些指标有:

  • 响应时间:系统对请求做出的响应时间
  • 吞吐量:单位时间内能处理的请求数量
  • QPS:系统每秒能处理多少流量
  • TPS:系统每秒处理多少事务(查询多少数据)
  • 并发用户数:同时能承载用户正常使用系统功能的用户数量

提升硬件性能

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

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

进行缓存

缓存的使用场景

  • 经常需要读取的数据(IO、数据库的数据)
  • 频繁访问的数据(文件数据库的数据)
  • 热点数据缓存(热搜,什么时候出现是不确定的,什么时候变冷也不确定,个数也没上限,显示10个罢了)
  • IO 瓶颈数据(3G左右的电影)
  • 计算昂贵的数据
  • 无需实时更新的数据(css、)

缓存的目的是减少对后端服务的访问,降低后端服务的压力

http缓存

浏览器缓存

概述

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

实现方式

比如新浪:http://www.sina.com.cn/,第一次访问返回 200,第二次刷新访问,返回响应码为 304,表示页面内容没有修改过, 浏览器缓存的内容还是最新的,不需要从服务器获取,直接读取浏览器缓存即可。不过会消耗系统的内存。我们也可以在 Java 代码中通过设置响应头,告诉前端浏览器这个请求进行缓存:

NGINX缓存

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

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

CDN缓存

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

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

应用缓存

内存缓存

在内存中缓存数据,效率高,速度快,应用重启缓存丢失,分为JVM内存和物理内存

磁盘缓存(IO流)

在磁盘缓存数据,读取效率较之内存缓存稍低,比数据库稍快,应用重启缓存不会丢失

代码组件:Guava、Ehcache

服务器:Redis、MemCache

多级缓存

在整个应用系统的不同层级进行数据的缓存,多层次缓存,来提升访问效率;

比如:浏览器 -> CDN -> Nginx -> Redis -> DB (磁盘、文件系统)

进行集群

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

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

但是呢,并不是所有的集群都是为了提高并发能力,例如zk集群并不能,还有redis集群

进行拆分

应用拆分

应用的拆分:分布式 (微服务)

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

应用拆分之后,就将原来在同一进程里的调用变成了远程方法调用,此时就需要使用到 一些远程调用技术:httpClient、hessian、dubbo、webservice 等。随着业务复杂度增加,我们需要采用一些开源方案进行开发,提升开发和维护效率,比 如 Dubbo、SpringCloud。

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

数据库拆分

数据库拆分分为:垂直拆分和水平拆分 (分库分表)

按照(服务)把相同类型的表放在一个数据库,这种方式 的拆分叫,也就是在不同库建不同表,把表分散到各个数据库。比如产品、订单、用户三类数据以前在一个数据库中,现在可以用三个数据库,分别为 产品数据库、订单数据库、用户数据库。这样可以将不同的数据库部署在不同的服务器上,提升单机容量和性能问题,也解决多个表之间的 IO 竞争问题。

根据数据行的特点和规则,将表中的某些列切分到一个数据库,这种方式的拆分叫,单库单表在数据量和流量增大的过程中,大表往往会成为性能瓶颈,所以数据库要进行 水平拆分数据库拆分,采用一些开源方案,降低开发难度,比如:MyCat(解决多数据源问题)、Sharding-Sphere

页面静态化

对于一些访问量大,更新频率较低的数据,可直接定时生成静态 html 页面,供前端访问,而不是访问 jsp,常用静态化的技术有freemaker、velocity等。(和模板引擎不一样)

页面静态化首先可以大大提升访问速度,不需要去访问数据库或者缓存来获取数据,浏览器直接加载 html 页即可,页面静态化可以提升网站稳定性,如果程序或数据库出了问题,静态页面依然可以正常访问。常用的应用场景有:首页+延迟加载插件,有很多循环的页面,评论数据等

静态化页面分为手动生成和自动生成,手动生成就是写死,自动生成就是根据查询的内容动态生成页面。,静态资源要写互联网访问

资源动静分离

采用比如 Nginx 实现动静分离,Nginx 负责代理静态资源,Tomcat 负责处理动态资源 Nginx 的效率极高,利用它处理静态资源,可以为后端服务器分担压力,动静分离架构示意图如下:

高并发解决方案

聚簇索引

聚簇索引(聚合索引、聚类索引)

要求索引在索引结构中的位置顺序必须要与数据在表中的物理顺序位置完全一致,例如某个索引30在索引结构是第6个那么它所对应的数据在表中也一定是第6个,一个表中最多只能有一个聚簇索引,主键就是聚簇索引。

主键不建议使用字符串更不要使用UUD,主键建议使用 int 或bigint,配合单调的自增(可以使用数据库自增或自己计算一个自增规则)可以考虑用Unix时间戳的数字类型

非聚簇索引(即B+Tree索引)

普通索引,即B+Tree索引

Hash索引方式

哈希碰撞少(同一行数量少)的时候查询效率很高,但查找区间数据会很麻烦,会到处乱跳。Hash结构的索引也是有顺序的,他比较适合字符串作为索引,因为它的查找是根据Hash值判断的,Hash时它的效率是非常高的,但是不适合查找区间索引,因此综合效率不如B+Tree索引

高并发解决方案

☆SQL 优化

SQL 优化很多,可以总结出很多经验,可以参考文章:https://blog.csdn.net/jie_liang/article/details/77340905

采用数据搜索引擎

elasticsearch / solr

程序优化

  • 养成良好的编程习惯
  • 不要重复创建太多对象
  • 流/文件/连接 一定要记得在 finally 块中关闭
  • 少用重量级同步锁 synchronized,采用 Lock
  • 不要在循环体中使用 try/catch(类似监控器)
  • 多定义局部变量,少定义成员变量

配置优化

JVM优化

设置 JVM 参数

参数解释:

配置项:https://www.oracle.com/java/technologies/javase/vmoptions-jsp.html

Tomcat优化

在tomcat的bin目录下的catalina.sh中设置jvm参数:

  • 设置 tomcat 的线程池大小
  • 设置IO 模式
  • 配置 APR

可以参考文章:https://www.cnblogs.com/zhuawang/p/5213192.html

NGINX优化

调整配置文件参数,偏运维的职责

其他优化

Linux 优化

优化 Linux 内核参数,修改/etc/sysctl.conf,偏运维的职责

http://blog.51cto.com/yangrong/1567427

网络优化

机房、带宽、路由器等方面优化,使得网络架构更合理,运维的职责

前端优化

js 优化:

  • 使用压缩工具,使得文件压缩变小
  • 多个 js 合并成一个 js 文件

css 优化:

  • 使用压缩工具,使得文件压缩变小
  • 多个css 合并成一个 css 文件

html 页面优化:

  • 不要加载太多 js 和 css
  • js 和 css 加载放在页面的尾部(用户体验)
  • 页面上减少到服务的请求数(浏览器有同域名并发限制)

可以通过将资源放在不同服务器上,但是在打开页面的时候压力可能会很大

文章知识点与官方知识档案匹配,可进一步学习相关知识Java技能树并发并发的定义92895 人正在系统学习中

来源:笼中小夜莺

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2021年8月22日
下一篇 2021年8月22日

相关推荐