前面写过一些电商网站相关的文章,这几天有时间,就把之前写得网站架构相关的文章,总结整理一下。把以前的一些内容就连贯起来,这样也能系统的知道,一个最小的电商平台是怎么一步步搭建起来的。
本文大纲:
- 小型电商网站的架构
- 日志与监控系统的解决方案
- 构建数据库的主从架构
- 基于共享存储的图片服务器架构
- 移动M站建设
- 系统容量预估
- 缓存系统
一、小型电商网站的架构
刚从传统软件行业进入到电商企业时,觉得电商网站没有什么技术含量,也没有什么门槛,都是一些现有的东西堆积木似的堆出来罢了。然而,真正进入到这个行业之后,才发现并非如此。有人说过,好的架构,是演化出来的,电商网站的架构也是如此。现在好的电商网站,看似很复杂,很牛逼,其实也是从很小的架构,也是从没什么技术含量开始的。所以,架构的演化过程,就是在技术团队不断追求极致的过程。
今天就来总结小型电商网站的架构演进。一套电商系统最初期的架构,往往会采用一个比较典型的LAMP架构,前端加上Apache/PHP,后端是MySQL。这个算是比较流行的。不过,目前还有一套.net的技术架构,可能大家很少提到。很不幸,我就是在一个.net平台为基础的电商公司。所以,今天也是要总结.net 平台的电商架构。
1.技术架构
上图为基础架构层面。这是一个很简单的基础架构。
前端网站和M站,考虑到访问量和系统的可用性,基本会采用分布式部署。通过代理服务器进行请求分发。
其它的业务子系统,像商家前台和管理系统,基本上都是单机或是主从部署。
各个DB ,Redis 服务和文件和图片服务,搜索引擎Solr服务等,采用主从部署。
3.详细架构
如上图所示,监控平台监控的范围很广,从服务器性能及资源,到应用系统的监控。每个公司都有特定的平台统一监控的需求及解决方案,但监控平台的任务和作用基本是一致的。
1.日志
日志是监视程序运行的一种重要的方式,主要有两个目的:1.bug的及时发现和定位;2.显示程序运行状态。
正确详细的日志记录能够快速的定位问题。同样,通过查看日志,可以看出程序正在做什么,是不是按预期的设计在执行,所以记录下程序的运行状态是必要的。这里将日志分为两种:1.异常日志;2.运行日志。
我们主要是使用log4net,将各个系统的日志,持久化记录到数据库或者文件中,以方便后续的系统异常监控和性能分析。如何集成log4net,这里不多说。
日志记录的几个原则:
- 日志级别一定要区分清楚,哪些属于error、warning、info等。
- 记录错误的位置。如果是分层系统,一定要在某个层统一处理,例如我们的MVC架构,都是在各个Action中Catch异常并处理,而业务层和数据库层这些地方的异常,都是Catch到异常后,往上一层抛。
- 日志信息清晰准确有意义,日志尽量详细点,以方便处理。应该记录相关系统、模块、时间、操作人、堆栈信息等。方便后续处理。
2.监控
监控系统是一个复杂的系统平台,目前有很多的开源产品和平台。不过我们平台小,监控任务和需求少,所以基本都是自己开发。主要有这五个方面:1.系统资源;2.服务器;3.服务;4.应用异常;5.应用性能。
具体的架构图如下:
读写分离的基本原理就是让主数据库处理事务性增、改、删操作(Insert、Update、Delete)操作,而从数据库处理Select查询操作。数据库复制被用来把事务性操作导致的变更同步到其它从数据库。
以SQL为例,主库负责写数据、读数据。读库仅负责读数据。每次有写库操作,同步更新到读库。写库就一个,读库可以有多个,采用日志同步的方式实现主库和多个读库的数据同步。
1SQL Server 读写分离的配置
SQL Server提供了三种技术,可以用于主从架构之间的数据同步的实现:日志传送、事务复制和SQL 2012 中新增的功能Always On 技术。各自优劣,具体的大家自己去百度吧,这里提供网上的朋友的配置方式,仅供参考。
日志传送:SQL Server 2008 R2 主从数据库同步
(链接:http://www.it165.net/database/html/201306/4088.html)
事务复制:SQL Server 复制:事务发布
(链接:http://www.cnblogs.com/gaizai/p/3305879.html)
第二种解决方案就是判断SQL语句是写语句(Insert 、Update、Create、 Alter)还是读语句(Select)。
四、基于共享存储的图片服务器架构
在当前这个互联网的时代,不管何种网站,对图片的需求量越来越大。尤其是电商网站,几乎都会面临到海量图片资源的存储、访问等相关技术问题。在对图片服务器的架构、扩展、升级的过程中,肯定也会碰到各种各样的问题与需求。当然这并不代表,你就必须得弄一个特别NB的图片服务架构,只要简单、高效、稳定就行。这部分我们来总结一个特别简单、高效的图片服务架构:通过共享存储的方式来实现图片服务架构。
然而,也有一些人问我,现在大型网站的图片服务器的架构已经完全不是这样了,别人家的图片系统比你这个牛逼多了,为啥不直接写那个呢?
事实是:第一,大型牛逼的系统我也不会;第二, 再牛逼的系统也是从小的架构演化过去的,没有一步到位的。这里介绍图片服务器架构虽然比较简单,但也是经过了单机时代的演化了,基本上可以满足中小型分布式网站的需求。这种架构的搭建和学习成本都极低,符合目前“短平快”的开发模式。
通过共享目录的方式实现共享存储 ,在共享目录文件服务器上配置独立域名,这样可以将图片服务器和应用服务器进行分离,来实现独立图片服务器。
优点:
- 将图片服务和应用服务分离,缓解应用服务器的I/O负载。
- 通过共享目录的方式来进行读写操作,可以避免多服务器之间同步相关的问题。
- 相对来讲很灵活,也支持扩容/扩展。支持配置成独立图片服务器和域名访问,方便日后的扩展和优化。
- 相对于更加复杂的分布式的NFS系统,这种方式是性价比高,符合目前互联网的“短平快”的开发模式。
缺点 :
- 共享目录配置有些繁琐。
- 会造成一定的(读写和安全)性能损失。
- 如果图片服务器出现问题,那所有的应用都会受到影响。同时也对存储服务器的性能要求特别高。
- 图片上传操作,还是得经过Web服务器,这对Web服务器还是有巨大的压力。
架构非常简单,基本架构如下图所示:
3.Bootstrap
Bootstrap就不多说了,网上有很多Bootstrap的资料。它最大的优势应该就是非常流行,非常容易上手。如果缺少专业的设计或美工,那么Bootstrap是一个比较好的选择。他的用法极其简单,几乎没什么学习成本,绝对是快速开发的利器。
官网:http://getbootstrap.com/
Github:https://github.com/twbs/bootstrap/
4.几点建议
移动M站的URL要尽量和PC相同,这是可以避免同一URL在PC站可以显示,但是在手机上打开却是404;
M站写单独的TDK。
六、系统容量预估
电商公司的朋友,这样的场景是否似曾相识:
运营和产品神秘兮兮的跑过来问:我们晚上要做搞个促销,服务器能抗得住么?如果扛不住,需要加多少台机器?
于是,技术一脸懵逼。
其实这些都是系统容量预估的问题,容量预估是架构师必备的技能之一。所谓,容量预估其实说白了就是系统在Down掉之前,所能承受的最大流量。这个是技术人员对于系统性能了解的重要指标。常见的容量评估包括流量、并发量、带宽、CPU、内存 、磁盘等一系列内容。这部分来聊一聊容量预估的问题。
1.几个重要参数
- QPS:每秒钟处理的请求数。
- 并发量: 系统同时处理的请求数。
- 响应时间: 一般取平均响应时间。
很多人经常会把并发数和QPS给混淆了。其实只要理解了上面三个要素的意义之后,就能推算出它们之间的关系:QPS = 并发量 / 平均响应时间。
2.容量评估的步骤与方法
1)预估总访问量
如何知道总访问量?对于一个运营活动的访问量评估,或者一个系统上线后PV的评估,有什么好方法?
最简单的办法就是:询问业务方,询问运营同学,询问产品同学,看产品和运营对此次活动的流量预估。
不过,业务方对于流量的预估,应该就PV和用户访问数这两个指标。技术人员需要根据这两个数据,计算其他相关指标,比如QPS等。
2)预估平均QPS
总请求数=总PV*页面衍生连接数
平均QPS = 总请求数/总时间
比如:活动落地页1小时内的总访问量是30w PV,该落地页的衍生连接数为30,那么落地页的平均QPS=/=2500。
3)预估峰值QPS
系统容量规划时,不能只考虑平均QPS,还要考虑高峰的QPS,那么如何评估峰值QPS呢?
这个要根据实际的业务评估,通过以往的一些营销活动的PV等数据进行预估。一般情况下,峰值QPS大概是均值QPS的3-5倍,如果日均QPS为1000,于是评估出峰值QPS为5000。
不过,有一些业务会比较难评估业务访问量,例如“秒杀业务”,这类业务的容量评估暂时不在此讨论。
4)预估系统、单机极限QPS
如何预估一个业务,一个服务器单机的极限QPS呢?
这个性能指标是服务器最基本的指标之一,所以除了压力测试没有其他的办法。通过压力测试,算出服务器的单机极限QPS 。
在一个业务上线前,一般都需要进行压力测试(很多创业型公司,业务迭代很快的系统可能没有这一步,那就悲剧了),以APP推送某营销活动为例(预计日均QPS为1000,峰值QPS为5000),业务场景可能是这样的:
- 通过APP推送一个活动消息;
- 运营活动H5落地页是一个Web站点;
- H5落地页由缓存Cache和数据库DB中的数据拼装而成。
通过压力测试发现,Web服务器单机只能抗住1200的QPS,Cache和数据库DB能抗住并发压力(一般来说,1%的流量到数据库,数据库120 QPS还是能轻松抗住的,Cache的话QPS能抗住,需要评估Cache的带宽,这里假设Cache不是瓶颈),这样,我们就得到了Web单机极限的QPS是1200。一般来说,生产系统不会跑满到极限的,这样容易影响服务器的寿命和性能,单机线上允许跑到QPS1200*0.8=960。
扩展说一句,通过压力测试,已经知道Web层是瓶颈,则可针对Web相关的方面做一些调整优化,以提高Web服务器的单机QPS 。
还有压力测试工作中,一般是以具体业务的角度进行压力测试,关心的是某个具体业务的并发量和QPS。
5)回答最开始那两个问题
需要的机器=峰值QPS/单机极限QPS
好了,上述已经得到了峰值QPS是5000,单机极限QPS是1000,线上部署了3台服务器:
服务器能抗住么? -> 峰值5000,单机1000,线上3台,扛不住
如果扛不住,需要加多少台机器? -> 需要额外2台,提前预留1台更好,给3台保险
3.总结
需要注意的是,以上都是计算单个服务器或是单个集群的容量。实际生产环境是由Web、消息队列、缓存、数据库等等一系列组成的复杂集群。在分布式系统中,任何节点出现瓶颈,都有可能导致雪崩效应,最后导致整个集群垮掉 (“雪崩效应”指的是系统中一个小问题会逐渐扩大,最后造成整个集群宕机)。
所以,要了解规划整个平台的容量,就必须计算出每一个节点的容量。找出任何可能出现的瓶颈所在。
七、缓存系统
对于一个电商系统,缓存是重要组成部分,而提升系统性能的主要方式之一也是缓存。它可以挡掉大部分的数据库访问的冲击,如果没有它,系统很可能会因为数据库不可用导致整个系统崩溃。
但缓存带来了另外一些棘手的问题: 数据的一致性和实时性。例如,数据库中的数据状态已经改变,但在页面上看到的仍然是缓存的旧值,直到缓冲时间失效之后,才能重新更新缓存。这个问题怎么解决?
还有就是缓存数据如果没有失效的话,是会一直保持在内存中的,对服务器的内存也是负担,那么,什么数据可以放缓存,什么数据不可以,这是系统设计之初必须考虑的问题。
什么数据可以放缓存?
不需要实时更新但是又极其消耗数据库的数据。比如网站首页的商品销售的排行榜,热搜商品等等,这些数据基本上都是一天统计一次,用户不会关注其是否是实时的。
需要实时更新,但是数据更新的频率不高的数据。
每次获取这些数据都经过复杂的处理逻辑,比如生成报表。
什么数据不应该使用缓存?
实际上,在电商系统中,大部分数据都是可以缓存的,不能使用缓存的数据很少。这类数据包括涉及到钱、密钥、业务关键性核心数据等。总之,如果你发现,系统里面的大部分数据都不能使用缓存,这说明架构本身出了问题。
如何解决一致性和实时性的问题?
保证一致性和实时性的办法就是:一旦数据库更新了,就必须把原来的缓存更新。
说一说我们的缓存方案:我们目前的缓存系统:Redis(主从)+ RabbitMQ + 缓存清理服务组成,具体如下图:
缓存清理作业订阅RabbitMQ消息队列,一有数据更新进入队列,就将数据重新更新到Redis缓存服务器。
当然,有些朋友的方案,是数据库更新完成之后,立马去更新相关缓存数据。这样就不需要MQ和缓存清理作业。不过,这同时也增加了系统的耦合性。具体得看自己的业务场景和平台大小。
以上均为个人经验分享,不足之处请大伙轻点拍砖,有更好的建议欢迎留言。
作者: 章为忠
链接:http://www.imooc.com/article/details/id/20952
来源:慕课网