Java高并发解决方案

高并发是互联网应用的一大特点,也是互联网应用不可避免的一个问题;比如淘宝双11购物狂欢节,京东618购物促销节,12306春节火车票,促销,秒杀等。

解决高并发问题是一个系统工程,需要站在全局高度统筹谋划,从多个角度进行架构设计;

解决高并发问题,不是一个或两个方案就能解决的,需要从各个维度综合施策才能完成;

在实践中,我们总结和提炼出来了很多应对高并发的方案或者说手段,分别如下:

系统访问用户增多,流量增大,导致服务器压力增大,出现性能瓶颈,我们可以采用一个简单粗暴的策略:提升服务器硬件配置,提升服务器硬件配置的策略,也称为:单体应用垂直扩容。

比如:产品或者网站初期,通常功能较少,用户量也不多,一般就采用一个项目工程来完成,这就是单体应用,也叫集中式应用。

按照经典的MVC三层架构设计,部署单台服务器,使用单台数据库,应用系统和数据库部署在同一台服务器上,随着应用系统功能的增加,访问用户的增多,单台服务器已无法承受那么多的访问流量。

此时,我们可以直接采用简单粗暴的办法:提升硬件配置来解决。

?CPU从32位提升为64位

?内存从64GB提升为256GB(比如缓存服务器);

?磁盘从HDD(HardDiskDrive)提升为SSD(固态硬盘(SolidStateDrives)),有大量读写的应用

?磁盘扩容,1TB扩展到2TB,比如文件系统

?千兆网卡提升为万兆网卡

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

缓存可以说是解决大流量高并发,优化系统性能非常重要的一个策略;

它是解决性能问题的利器,就像一把瑞士军刀,锋利强大;

缓存在高并发系统中无处不在(到处都是)。

①浏览器缓存

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

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

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

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

location/static{ root/opt/static/; expires1d;//全天}当用户访问时,Nginx拦截到请求后先从Nginx本地缓存查询数据,如果有并且没有过期,则直接返回缓存内容。

③CDN缓存

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

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

①内存缓存

在内存中缓存数据,效率高,速度快,应用重启缓存丢失。

②磁盘缓存

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

代码组件:Guava、Ehcache

服务器:Redis、MemCache

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

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

?经常需要读取的数据

?频繁访问的数据

?热点数据缓存

?IO瓶颈数据

?计算昂贵的数据

?无需实时更新的数据

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

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

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

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

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

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

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

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

按照业务维度把相同类型的表放在一个数据库,另一些表放在另一个数据库,这种方式的拆分叫垂直拆分,也就是在不同库建不同表,把表分散到各个数据库;

比如产品、订单、用户三类数据以前在一个数据库中,现在可以用三个数据库,分别为产品数据库、订单数据库、用户数据库;

这样可以将不同的数据库部署在不同的服务器上,提升单机容量和性能问题,也解决多个表之间的IO竞争问题;

根据数据行的特点和规则,将表中的某些行切分到一个数据库,而另外的某些行又切分到另一个数据库,这种方式的拆分叫水平拆分;

单库单表在数据量和流量增大的过程中,大表往往会成为性能瓶颈,所以数据库要进行水平拆分;

数据库拆分,采用一些开源方案,降低开发难度,比如:MyCat、Sharding-Sphere。

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

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

定时任务,每隔2分钟生成一次首页的静态化页面;

页面静态化首先可以大大提升访问速度,不需要去访问数据库或者缓存来获取数据,浏览器直接加载html页即可;

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

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

Nginx的效率极高,利用它处理静态资源,可以为后端服务器分担压力;

动静分离架构示意图

redis和nginx并发量5w左右,tomcat和mysql700左右,当然可以通过一些方式调整。

?采用队列是解决高并发大流量的利器

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

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

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

?使用队列实现系统解耦,比如支付成功了,发消息通知物流系统,发票系统,库存系统等,而无需直接调用这些系统;

?队列应用场景

不是所有的处理都必须要实时处理;

不是所有的请求都必须要实时告诉用户结果;

不是所有的请求都必须100%一次性处理成功;

不知道哪个系统需要我的协助来实现它的业务处理,保证最终一致性,不需要强一致性。

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

?ActiveMQ是jms规范下的一个老牌的成熟的消息中间件/消息服务器

?RabbitMQ/RocketMQ数据可靠性极好,性能也非常优秀,在一些金融领域、电商领域使用很广泛;RocketMQ是阿里巴巴的;

?kafka主要运用在大数据领域,用于对数据的分析,日志的分析等处理,它有可能产生消息的丢失问题,它追求性能,性能极好,不追求数据的可靠性

在实际开发中,我们经常会采用一些池化技术,减少资源消耗,提升系统性能。

通过复用对象,减少对象创建和垃圾收集器回收对象的资源开销;

可以采用commons-pool2实现;

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

Druid/DBCP/C3P0/BoneCP

JedisPool(内部基于commons-pool2实现)

核心实现类:PoolingClientConnectionManager

Java提供java.util.concurrent包可以实现线程池

Executors.newFixedThreadPool(8);线程数量固定

Executors.newSingleThreadExecutor();只有一个线程,避免关闭情况

Executors.newCachedThreadPool();可以自动扩容

Executors.newScheduledThreadPool(10);每隔多久执行

设置JVM参数

-server-Xmx4g-Xms4g-Xmn256m

-XX:PermSize=128m

-Xss256k

-XX:+DisableExplicitGC

-XX:+UseConcMarkSweepGC

-XX:+CMSParallelRemarkEnabled

-XX:+UseCMSCompactAtFullCollection

-XX:LargePageSizeInBytes=128m

?设置JVM参数,可以参考JVM优化参数

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

JAVA_OPTS="-server-XX:+PrintGCDetails-Xmx4g-Xms4g-Xmn256m

-XX:+UseFastAccessorMethods

-XX:+UseCMSInitiatingOccupancyOnly

-XX:CMSInitiatingOccupancyFraction=70"

?设置tomcat的线程池大小

?设置IO模式

?配置APR

?养成良好的编程习惯

?不要重复创建太多对象

?流/文件/连接一定要记得在finally块中关闭

?少用重量级同步锁synchronized,采用Lock

?不要在循环体中使用try/catch

?多定义局部变量,少定义成员变量

修改数据库服务器的配置文件的参数,偏DBA(数据库管理员)

?将数据库服务器和应用服务器分离

?读写分离:通过数据库主从架构解决,写数据时操作主库,读数据时操作从库,分摊读写压力

?分库分表:扩容数据库,解决数据量容量问题

?建立合适的索引

?建立索引的字段尽量的小,最好是数值

?尽量在唯一性高的字段上创建索引,主键、序号等

?不要在性别这种唯一性很低的字段上创建索引

SQL优化很多,可以总结出很多经验;

solr/elasticsearch

调整配置文件参数

worker_processes16;gzipon;#开启gzip压缩输出events{worker_connections65535;#极限值65535 multi_accepton;#开启多路连接 useepoll;#使用epoll模型}13.Linux优化

优化Linux内核参数

修改/etc/sysctl.conf

机房、带宽、路由器等方面优化

网络架构更合理

运维的职责

?压缩变小

?压缩工具

?多个js合并成一个js文件,直接手动拷贝到一个文件中去,页面只加载这一个文件或者利用程序,比如controller,/aa/jspath=xxx.js,xxx.js

?多个css文件合并成一个css文件

?不要加载太多js和css

?js和css加载放在页面的尾部,从用户体验角度考虑的

?页面上减少到服务的请求数

?压测就是压力测试

?在系统上线前,需要对系统各个环节进行压力测试,发现系统的瓶颈点,然后对系统的瓶颈点,进行调优。调优完成后,还需要考虑另外一些风险因素,比如网络不稳定,机房故障等。所以我们需要提前有故障预备方案,比如多机房部署容灾、路由切换等。故障预备方案做好后,还需要提前进行演练,以确保预案的有效性

?压力测试工具:ApacheJMeter/LoadRunner等,偏测试的工作

?CTO、架构师,技术团队、测试团队、运维团队、DBA等共同完成

总结

完成以上的工作,我们才能实现一个高并发、高性能、高可用的“三高”分布式系统。

THE END
1.避免信息爆炸构建完美的消息提醒系统首先要明确的是,什么是消息提醒系统?简单来说,它是一套程序或者功能,用来通知用户有新的事件发生,比如新邮件到达、新朋友请求、即时聊天中的未读信息等。这些提醒可以通过声音、振动、屏幕亮度变化等形式展现给用户。好的消息提醒系统能够帮助我们及时了解重要的事情,而不至于错过关键机会;坏的则可能导致连续不断的声音https://www.ly6b8v3c.cn/shu-ma/551311.html
2.智慧生活需要智慧硬件了解和配置你的Raglon65设备随着5G技术不断完善,以及更多应用场景逐渐被开辟,比如增强现实(AR)、虚拟现实(VR)等领域,骁龙865作为一个支持这些创新需求的核心硬件,将会进一步推动移动互联网向前发展,为我们的未来带来无限可能。 芯片巨变,软件优化之路——应用程序对Raglon 65设备适配挑战与机遇 https://www.d9xmz5u1j.cn/ke-ji/530608.html
3.测试/测试开发八股——找大厂测试实习基础篇测试八股线程数:根据实际需求设定总共有多少个线程参与压测。 Ramp-Up Period:多少秒启动完所有线程。 循环次数:定义要执行的循环次数。 调度器:如果选中了这个选项,需要在配置中进行相关设置。 ②判断压测机可运行的线程数 通过逐步增加线程数,观察压测机CPU的使用情况,以及JMeter的响应时间。当发现CPU稳定且响应时间随线程数https://blog.csdn.net/weixin_45928096/article/details/136400578
4.项目实战10压测机带宽打满,堆机器才是王道然后根据波形图特征进行合理的推测。(一开始可能很懵逼,阅图无数后会有一些感觉) 1. 因为经常会被业务方挑战是压测机的问题,所以就想先加一个集群来压测,以确认是压测机的问题,还是压测链路的问题,亦或是业务方的问题。 压测结果:两个集群,各1500并发,QPS值总共6k https://cloud.tencent.com/developer/article/1791991
5.python编写短信测压网站python压测websocketpython 编写短信测压网站 python压测websocket Websocket协议压测记录 背景: 公司的行情系统是采用的websocket协议,有请求和订阅两种方式向服务器申请最新行情信息。请求方式是一次的,订阅方式是建立连接后,服务器定时向客户端推送行情信息。 初步测试方案: 因考虑到websocket是双工通讯,是长连接,并且本次压测的性能指标是https://blog.51cto.com/u_16099276/10857411
6.新一代垃圾回收器ZGC的探索与实践线上运行 & 全量部署:要求线上机器已安装JDK 11,有3种方式: 新申请默认安装JDK 11的虚拟机:试用JDK 11时可用这种方式;全量部署时,如果新申请机器数量过多,可能没有足够机器资源。 通过手写脚本给存量虚拟机安装JDK 11:不推荐,业务同学过多参与到运维当中。 https://www.528045.com/article/d10c0b06b3.html
7.性能测试PTS销售指南学习笔记可以模拟各种客户端,各种浏览器,各种移动端,从全世界各地发起流量,压测对象可以是公有云,专有云,自建idc以及vpc网络就是阿里云上面的内部网络。 1、非阿里云客户能用吗? 可以,无论客户是公有云/专有云/混合云/自建IDC,无论什么云厂商 只要在公网可访问就能通过PTS来压测。阿里云上的客户有另外的好处就是可以做https://developer.aliyun.com/article/1085961
8.mts是什么短信应用的作用是什么?即开即用,不限账号数 无限邮箱容量4GB超大附件 ¥0.00 免费试用 会打字就会建站 3300+模板,30000+企业选择 立即购买 并发用户数是什么? 并发用户数是什么? 压测是需要模拟用户实际业务操作的真实使用场景,并发用户数是模拟一定数量用户操作的一个配置。 例如,游戏网站某个时间点进行竞技活动,那么这个时候对设备的https://support.huaweicloud.com/topic/831437-4-M
9.短信轰炸机网页版在线短信轰炸机免费短信云呼轰炸机欢迎使用我们的短信轰炸服务,这是一个先进的在线平台,使用户能够同时向多个收件人发送大量短信,为企业、组织和个人提供了一个强大的工具,可以接触他们的目标受众,推广他们的产品或服务,并提高他们的客户参与度,具有用户友好的界面、高送达率和实时报告功能,使其成为促销活动、事件通知、约会提醒等各种用例的理想解决方案https://www.brightbikerebel.com/
10.易打单双11商家打单发货指南3. 提前准备备用打印机 大促单量暴增,建议您多配备几台打印机和备用电脑,保证正常打单。 4. 提前做好人员培训 打单人员提前培训,熟悉易打单的打单流程和常用功能。 5. 提前设置好快递单模版、宝贝简称等 提前设置好快递单、发货单、备货单的打印样式和模版。 https://card.weibo.com/article/m/show/id/2309404828880723902909
11.虚拟机可以建网站游戏测试是什么意思_CSS学习 新闻来源:网络整理 2023-3-4共有:3580浏览 游戏测试是什么意思?这些其实都是一个意思:让玩家进游戏帮忙测试 前面的修饰词都是游戏公司自己加的 不过也说一下大致的一个概念 也不能算是概念 压测:目的是测试下服务器以及一些地图的承载能力 玩家会在哪里因为人多卡的要死要活的 不收https://www.gzit.cn/theme/2676502.html
12.统一身份认证有什么用认证文件有什么用途?便宜云服务器帮助中心为你分享云计算行业信息,包含产品介绍、用户指南、开发指南、最佳实践和常见问题等文档,方便快速查找定位问题与能力成长,并提供相关资料和解决方案。本页面关键词:统一身份认证有什么用。http://support.ceden.cn/?topic/97616-1-T
13.教你提高接口性能的18种方案,用了直接提升100倍。耗时操作,考虑用异步处理,这样可以降低接口耗时。 假设一个转账接口,匹配联行号,是同步执行的,但是它的操作耗时有点长,优化前的流程: 为了降低接口耗时,更快返回,你可以把匹配联行号移到异步处理,优化后: 除了转账这个例子,日常工作中还有很多这种例子。比如:用户注册成功后,短信邮件通知,也是可以异步处理的~ https://maimai.cn/article/detail?fid=1781282995&efid=Ydq-Gt2478kKUM5-4UOLjA
14.告别传统压测:全链路压测在中通的实践分享链路大图首先需要梳理出链路调用大图,刚开始不需要太细,但需要对入口/出口/应用名/数据库/缓存/中间件/资金影响/邮件/短信等,类似这样的一些关键信息能梳理到,因为保密手册的原因,具体的链路图,这里就不放出了,可以用本文最上面的《压测流量链路示意图》进行脑补。 https://xie.infoq.cn/article/cc37b94311d35b68aa8db9ab1
15.速云短信测压4.0.6破解版/短信电话测压程序员阿鑫速云短信测压4.0.6破解版_短信电话测压 此版说明 去除收费,去除软件暗桩 使用必看 这个软件暗桩较多(有锁机暗桩,写入文件暗桩,无限弹Dos窗口暗桩等),尽管补丁已经处理了但可能仍有遗漏,为了保护电脑的安全,尽量在虚拟机下使用(需要使用去虚拟化的虚拟机,没有去虚拟化的虚拟机可以站内搜索) https://www.cxyax.com/?post=743
16.大话性能测试:JMeter实战所以,在这里作者建议学习测试的同学优先掌握JMeter工具,本书意在分享作者系统梳理在工作中积累的JMeter常见的实战经验和一些技巧,让大家能够拿来即用,快速应用于自己的实际工作任务中。 3.测试数据构造 在压测之前,需要在数据库中准备好一定量的铺垫存量数据,有些比较复杂的数据会涉及多张表的关联关系,需要利用代码去https://www.epubit.com/bookDetails?id=UB78128d0789cad
17.GitHuberyajf/awesome堡垒机 安全扫描 工单 应用进程管理 微服务框架 性能分析 抓包工具 接口管理 数据管道 文件管理系统 文档 时序数据库 机器镜像 流量回放 测试压测 消息队列 混沌测试 物联网 终端命令行工具 虚拟化 运维管理平台 运维自动化 配置中心 防火墙 项目管理 Backup 此类目收录项目 5 个。 RepositoryLicenseStarCreatedAhttps://github.com/eryajf/awesome-ops/
18.短信网关平台短信软件接入短信验证码短信群发网关压测数据 按TPS 2000条/秒 测试短信数量 1亿 配置如下 CPU+内存 16核32G 占用存储 300G 带宽 根据流量计费 最低成本(阿里云包年,计算型,动态计算带宽) 按TPS 4000条/秒 测试短信数量 1亿 配置如下 CPU+内存 32核64G 占用存储 500G 带宽 根据流量计费 https://www.smswg.com/
19.消息队列在测试开发中的应用思路在压测服务系统的设计中,为了增加吞吐和并发能力,需要架设压测集群,这时数据处理和性能统计会出现单点问题(如jmeter的设计,当分布式集群过大时,master压力过大而死机),可在压测执行机和性能统计机器之间架设消息队列,作为消息传输媒介的同时,让消息队列缓存数据,缓解性能统计机器的压力。 https://www.jianshu.com/p/c5ca087d8113