资讯专栏INFORMATION COLUMN

【Java猫说】项目架构的演进史(大型电商系列)

littlelightss / 1433人阅读

摘要:我们本次也要从核心模块演进细节到核心架构设计思想,最后实现高性能高并发高可用的电商实战项目。过程中安全性数据分析监控反作弊继续发展架构服务化消息队列任务调度多机房因此任何一个高大上的项目技术架构和开发技术实现不是一蹴而就的。

阅读本文约 “7分钟”


大家都知道,一个真实的企业级项目开发过程、大型企业项目开发的编码思维、经验、技巧、高质量的线上作品都是需要耗费人力物力和成本,同样我们的项目也需要你挤出时间慢慢消化哦!

让我们来看看我们最熟悉的淘宝架构

当然,没有哪个网站一个就是这么丰富的,都是一步一步进展起来的。

我们本次也要从核心模块-演进细节到核心架构-设计思想,最后实现高性能、高并发、高可用的电商实战项目。

本次我们将讲的有数据库及接口、项目初始化、用户模块、分类模块、商品模块、购物车模块、收货地址模块、支付模块、订单模块······

由于是序章,我们先来了解一下,一个大型Java项目架构演进解析

首先从一个小网站说起,一台服务器就够了,数据库与应用均部署到一个服务器上。

随着用户增加,数据量增大,硬盘支撑不起,这时一台服务器已经支持不起了。我们可以将应用服务器和数据服务分离,给应用服务器配置更好的CPU、内存等,给数据服务器配置更好更快的硬盘,如下图用了三台服务器以提高性能。

即使文件服务器宕机,该架构依然可以支持使用,随着访问的并发增高,为了降低接口访问时间、提高服务性能,我们需要继续优化演进,我们会发现有很多数据其实并不需要每次都从数据库中读取,于是我们增加了缓存,主要是80%的访问都集中在20%的数据上(28原则),只要缓存得当,系统的性能也将得到提升,而缓存又分为两种Local Cache本地缓存、Remote Distributed Cache远程单机缓存(远程分布式缓存)下图为分布式缓存集群(什么样的业务使用远程缓存、什么业务使用本地缓存)

这个时候随着访问的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猫说】实例变量与局部变量

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/47901.html

相关文章

  • Java猫说项目架构进史大型电商系列

    摘要:我们本次也要从核心模块演进细节到核心架构设计思想,最后实现高性能高并发高可用的电商实战项目。过程中安全性数据分析监控反作弊继续发展架构服务化消息队列任务调度多机房因此任何一个高大上的项目技术架构和开发技术实现不是一蹴而就的。 阅读本文约 7分钟 大家都知道,一个真实的企业级项目开发过程、大型企业项目开发的编码思维、经验、技巧、高质量的线上作品都是需要耗费人力物力和成本,同样我们的项目...

    yuanxin 评论0 收藏0
  • Java猫说项目架构进史大型电商系列

    摘要:我们本次也要从核心模块演进细节到核心架构设计思想,最后实现高性能高并发高可用的电商实战项目。过程中安全性数据分析监控反作弊继续发展架构服务化消息队列任务调度多机房因此任何一个高大上的项目技术架构和开发技术实现不是一蹴而就的。 阅读本文约 7分钟 大家都知道,一个真实的企业级项目开发过程、大型企业项目开发的编码思维、经验、技巧、高质量的线上作品都是需要耗费人力物力和成本,同样我们的项目...

    sumory 评论0 收藏0
  • Java猫说项目架构进史大型电商系列

    摘要:我们本次也要从核心模块演进细节到核心架构设计思想,最后实现高性能高并发高可用的电商实战项目。过程中安全性数据分析监控反作弊继续发展架构服务化消息队列任务调度多机房因此任何一个高大上的项目技术架构和开发技术实现不是一蹴而就的。 阅读本文约 7分钟 大家都知道,一个真实的企业级项目开发过程、大型企业项目开发的编码思维、经验、技巧、高质量的线上作品都是需要耗费人力物力和成本,同样我们的项目...

    leejan97 评论0 收藏0
  • Java猫说】SSM整合Netty5.0详细说明

    摘要:而我们项目在实测时也是将项目发布到测试服务器,通过模拟工具进行测试连接,当数据格式正常,且业务数据正常,服务器就会对指令执行对应的操作。 阅读本文约5.5分钟 最近又有粉丝加Q群讨论netty整合SSM项目的方式等,我在这里抽了休息日的时候整理一下,一步一步的记录,注意的是,本案例仅实现了用netty整合SSM后与单片机等类TCP应用通信。 SSM + Netty项目结合思路 对于N...

    dingding199389 评论0 收藏0
  • Java猫说】实例变量与局部变量

    摘要:我们来看看实例变量与局部变量之间的差别实例变量是声明在类内而不是方法中。局部变量在使用前必须初始化。局部变量没有默认值,如果在变量被初始化前就要使用的话,编译器会显示错误。 阅读本文约1.8分钟 实例变量永远都会有默认值,如果你没有明确的赋值给实例变量,或者没有调用setter,实例变量还是会有值! integers 0 floating points 0.0 boolean...

    dreamtecher 评论0 收藏0

发表评论

0条评论

littlelightss

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<