阅读本文约 “7分钟”web
你们都知道,一个真实的企业级项目开发过程、大型企业项目开发的编码思惟、经验、技巧、高质量的线上做品都是须要耗费人力物力和成本,一样咱们的项目也须要你挤出时间慢慢消化哦!数据库
让咱们来看看咱们最熟悉的淘宝架构segmentfault
固然,没有哪一个网站一个就是这么丰富的,都是一步一步进展起来的。后端
咱们本次也要从核心模块-演进细节到核心架构-设计思想,最后实现高性能、高并发、高可用的电商实战项目。浏览器
本次咱们将讲的有数据库及接口、项目初始化、用户模块、分类模块、商品模块、购物车模块、收货地址模块、支付模块、订单模块······缓存
因为是序章,咱们先来了解一下,一个大型Java项目架构演进解析安全
首先从一个小网站提及,一台服务器就够了,数据库与应用均部署到一个服务器上。 服务器
随着用户增长,数据量增大,硬盘支撑不起,这时一台服务器已经支持不起了。咱们能够将应用服务器和数据服务分离,给应用服务器配置更好的CPU、内存等,给数据服务器配置更好更快的硬盘,以下图用了三台服务器以提升性能。cookie
即便文件服务器宕机,该架构依然能够支持使用,随着访问的并发增高,为了下降接口访问时间、提升服务性能,咱们须要继续优化演进,咱们会发现有不少数据其实并不须要每次都从数据库中读取,因而咱们增长了缓存,主要是80%的访问都集中在20%的数据上(28原则),只要缓存得当,系统的性能也将获得提高,而缓存又分为两种Local Cache本地缓存、Remote Distributed Cache远程单机缓存(远程分布式缓存)下图为分布式缓存集群(什么样的业务使用远程缓存、什么业务使用本地缓存) session
这个时候随着访问的QPS不断提升,服务器的处理能力有限,例如Tomcat,则其将成为一个瓶颈,即便购买更好的硬件,但老是存在上限且成本也不低,这时咱们就须要作个服务器的集群(负载均衡调度服务器),这样咱们就能够横向扩展咱们的服务器,解决服务器处理能力的瓶颈。
这时咱们还要思考几个问题,所谓负载均衡的调度策略是什么,适合什么场景,当咱们登陆A服务器,Session信息存储在A服务器上,假设咱们的(IPHash)负载均衡将其信息分散到其余服务器,可是其不够分散也不够均匀,可能形成某些服务器压力过大,某些则没有压力,这时机器网卡的带宽就可能成为瓶颈,这时咱们使用轮询或最小链接负载的策略,可能致使访问A服务器后,再访问B服务器时读取不到Session信息,这时咱们就要解决Session管理的问题,咱们使用Session Sticky(粘制会话)来处理这个问题,就好比说每次吃饭都为了保证用的是咱们本身的碗筷,只要在饭店中存了咱们的碗筷,则每次去这家饭店吃就行了,其处理方式:对于同一链接中的数据包,负载均衡将其进行一个NAT转换后转发至后端固定的服务器进行处理,以下图所示,这种方案解决了session共享问题(缺点:服务器一旦重启其session将所有消失、负载均衡服务器成为一个有状态的服务器,比较难实现容灾)
咱们再看看第二个解决方案,两个服务器经过复制都保存Browser1的session信息(缺点:应用服务器间的带宽问题,服务器间要不断的同步session信息、大量用户在线时服务器占用内存过多、不适合作大规模集群)
再看看第三个方案,基于cookie,即每次吃饭都带上本身的碗筷,则去哪家饭店均可以吃饭,用携带session信息的cookie去访问服务器,其也解决了session共享的问题(缺点:cookie长度有限,且保存在浏览器上,安全性没有保障)
接着再看看第四种解决方案,咱们将session作成一个session服务器,browser1经过负载均衡请求服务器,服务器将session信息存储到session服务器中,当想要获取时就反向进行。(缺点:目前session Server是单点的,如何解决单点,保证可用性)
咱们能够将Session Server也作成集群,其适合用于Session数量与web服务数量大的状况下,更改架构后,也要修改应用存储session的业务逻辑。 接下来咱们再看看数据库,读写都要通过数据库,当用户量达到必定量时,数据库又将成为一个瓶颈,则咱们将如何解决?咱们可使用数据库的读写分离,主从库,并经过统一的数据访问模型进行访问,将全部读操做引入到Slave服务器,将写操做引入到主库当中,因为数据库读写分离,因此应用程序也要有相应的变化,使用数据访问模块让应用程序开发人员不用理会读写分离的存在,这样多数据源读写代码对咱们的业务就没有了侵入(代码层的演变,如何支持多数据源、如何封装对业务没有侵入、如何使用现用的ORM框架实现数据读写分离、是否更换ORM、其优缺点?)
当咱们访问过大,I/O过大,咱们数据的读写分离又将遇到这几个问题,主从库复制时是否延迟(分机房部署、跨机房传输),应用对于数据源的路由问题,接着咱们为了提升服务器,增长了CND和反向代理服务器,使用CDN能够解决不一样地方访问速度问题、反向代理能够在机房中缓存用户的资源。
这时文件服务器又出现了瓶颈,咱们将文件服务器改成分布式文件服务器集群,咱们要考虑到:如何不影响线上的业务访问,是否须要业务部门帮忙清理数据,是否须要备份服务器,是否须要从新作域名解析。
这时咱们的数据库又出现了新的瓶颈,咱们选择专库专用的方式,进行数据库的垂直拆分,能够解决写数据、并发、量大的问题,分库后又将带来一些新的问题:跨业务的事务(分布式事务)
当某个数据的访问量、数据量、日志等过大达到瓶颈时,这时咱们就要进行数据库的水平拆分,咱们将User拆分红Users1和Users2,水平拆分即将同一个数据表的数据拆分到两个数据库当中,这时咱们就解决了单数据库的瓶颈。
水平拆分后,SQL路由出现一些问题,假设咱们想知道某个用户是存在Users1仍是Users2中,且因为分库,主键的策略也将有所不一样,同时也将面临一个分页的问题(后台管理系统在进行展现时还要考虑分页的问题),当完成后,咱们又发现应用服务器的搜索量上升,这时咱们将应用服务器的搜索功能提取出来作成搜索引擎,同时部分场景使用NoSQL提升性能,
固然以上架构还存在部分问题,如负载均衡服务器是单点,所以也能够将负载均衡服务器作成集群,进行主从的热备,同时作一个自动切换的解决方案。
过程当中:安全性、数据分析、监控、反做弊… 继续发展:SOA架构、服务化、消息队列、任务调度、多机房…
所以任何一个高大上的项目技术架构和开发技术实现不是一蹴而就的。
本文已转载我的技术公众号:UncleCatMySelf
欢迎留言讨论与点赞
上一篇推荐:【Java猫说】SSM整合Netty5.0详细说明
下一篇推荐:【Java猫说】实例变量与局部变量