一、一般高并发web系统
这里的一般指的是秒杀之类的电子商务系统,比如说小米抢购、淘宝双十一、秒杀活动等等,12306订票网站与其有本质区别,下面会有说到。
系统架构图
下图是我调查众多资料总结出的系统架构图,当然这也不能作为通用的解决方案,首先像淘宝等企业公布的资料肯定不是最先进或者是性能最好的,其次具体情况还需具体分析。
核心技术点
前端优化 前端优化主要包括动态内容静态化,增加前端缓存。页面静态化是指将指含有大量动态元素的动态网页,如jsp、php等,转换为html静态页面,静态页面由于不用加载动态元素,其访问速度要比动态页面快得多,可以增加访问速度,减小数据库压力;前端页面缓存在系统前端对Web服务器上的页面进行缓存。
CDN技术 CDN即内容分发网络,其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定。通过在网络各处放置节点服务器所构成的在现有的互联网基础之上的一层智能虚拟网络,CDN系统能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上。其目的是使用户可就近取得所需内容,解决 Internet网络拥挤的状况,提高用户访问网站的响应速度。
负载均衡 负载均衡的基本思想是把高并发的访问平均分配到每一个服务器节点上,从而减小分布式数据库中每一个节点的压力。
中间件 数据库的中间件技术是指把应用层与数据库层分离,在中间增加一个部分,避免应用直接访问数据库。因为系统可能采用读写分离的技术,因而会使用不同的数据库,中间件可以屏蔽数据库直接的不同,提供统一的接口。中间件还负责事务的协调处理,起到数据连接管理的作用,多个客户端连接通过中间件可以共用一个数据库连接。
memcached memcached是一个高性能的分布式内存对象缓存系统,通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度,它是基于一个存储键/值对的hashmap。
并发控制 数据库限流,达到数据库的最大并发数,进入行锁状态。如不进行控制,一旦其中一个连接卡住,会引发雪崩效应,从而影响整个系统
排队系统 锁机制导致排队
并行复制 采用并行复制的技术可以解决主备库复制延迟问题
数据库拆分 分为水平拆分和垂直拆分,垂直拆分即按列拆分,把数据按应用分离,降低单个事务的数据处理量;水平拆分即按行拆分,降低节点的并发量
读写分离 有些系统读操作频繁,而有些系统写操作频繁,读写分离能有效提高访问速度
二、web集中式高并发架构,下面是一个项目的总体架构
我们先介绍下架构中的技术选型为什么这么选。
1.使用nginx进行反向代理实现负载均衡而不使用其他的。网上有很多种实现负载均衡的软硬件方案,其中F5,apache的负载均衡,lvs的负载均衡为什么我们都不选?F5,没钱。apache,复杂,在高并发上性能低于nginx。lvs,没怎么了解,直接抛弃了。
2.使用redis作为缓存。redis跟mencache,ehcache选哪个一直都是人们所头疼的。首先ehcache是存在于本地内存的,多个tomcat做负载的时候就特别麻烦了。mencache是支持多线程的缓存,但它只支持一种数据结构---key-value,这使我们在使用它的时候会有很多瓶颈。redis分布式缓存,提供了多种数据结构的存储,虽然它只支持单线程访问,但速度不亚于mencache。
3.mysql我们使用的是5.6的版本,主要是支持事务,颜表情等功能,没啥好说的
4.至于mysql主从处理(代码层),我们是在mybatis层面定义两个mapper,一个读,一个写,人工操作,没啥复用性,就是为了项目赶紧上线。(想实现高可用,随时加从库的话可以使用一些中间件,例如mysql-proxy,当然使用中间件效率相对就会下来一点)
接下来讲一下架构
1.首先我们前端是构造了一个虚拟IP(暴露给用户)进行主热双备,然后连接到一个nginx,在nginx进行请求过滤,比如恶意的压力测试之类的行为(百度有很多解决方案,例如lua脚本,redis黑白名单等)。通过nginx进行反向代理把请求分发给各个tomcat(可以通过配置权重,轮询方式配置分发),此处的tomcat可以根据需求设置多个(一台mysql大概每秒能撑2000个并发,所以自己看着办啦)。
2.到了tomcat层后,我们会先把请求分为两种,一种是查询请求,一种是更新请求。
1)其中查询请求先会访问redis缓存(减少mysql压力,提高并发),若命中则返回数据给用户,若不命中则查询mysql(从库:myisam引擎,只读库,提高读取效率),并把查询结果set到redis中
2)更新请求会发送到mysql(主库:innodb,保证事务,数据安全)
3.由于我们项目对于实时性要求不是很高,所以此时可以不用考虑mysql主从复制时的延时性。(网上有很多种解决延时的方案,例如缓存,中间件等)
4.至于静态文件我们存放在自己构建的cdn上,也是为了提升访问效率
最后讲一下数据库
数据库服务为上层 Web 应用提供关系式或结构化的数据存储与查询支持。取决于具体用例,Web 应用可以使用数据库连接器之类的插件机制来提供对不同数据库服务的访问支持。在这种架构下,用户可以灵活地选择或变更最适合企业现阶段情况的不同数据库产品。例如:用户可以在原型阶段使用 SQLite 之类的嵌入式引擎完成快速部署和功能验证;而在应用的初期阶段切换到廉价的 MySql 数据库解决方案;等到业务需求不断上升,数据库负载不断加重时再向 Clustrix、MongoDB、Cassandra、MySql Cluster、ORACLE 等更昂贵和复杂的解决方案进行迁移。
1.设计表的时候适当的加些冗余字段,这样会少了很多的连表查询(当然冗余字段改变了对项目需求影响不大或冗余字段不会改变的情况下)
2.预估好字段大小,毕竟定义好字段大小后mysql就给该字段定义了相对大小的空间,定义过大会很浪费资源。当然也避免定义一些没用的字段
3.适当索引,当然跟废话差不多啦,加索引的技巧也很多,上网搜搜。
4.不是一条sql搞定全部就是好,有时候把大的sql拆分成小的sql效率会高很多
·如果发现文章有任何问题,欢迎私信或者留言交流,也可以关注笔者的头条号,一起学习交流一起进步。