电商项目总结
Posted zeussbook
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了电商项目总结相关的知识,希望对你有一定的参考价值。
一、模块的划分
有好多大公司根据业务来划分模块,比如商品系统,订单系统,核心和非核心。本文只要是根据前后台等来划分。
首先说说 失败转移和负债均衡的概念,
失败转移:简单来说就是一个集群中的某个服务器坏掉了,应该让该台服务器上的用户转移到其它的几台服务器上,这个过程对用户来说,无需知道。
负载均衡:简单来说就是多个用户来并发访问时,集群内的服务器共同承担用户并发访问的压力,但不一定是平均分配。
上述二个概念,不光出现在WEB服务器领域,数据库领域也是需要做失败转移和负载均衡的。
1.前后台分离。互联网项目,特别是电商项目,用户数量巨大,而管理员数量相比很小。需要做一个前后台分离,即前台和后台,是两个独立的项目。
原因:放在一起会影响后台管理员的。前台并发量大要做集群的。如果前台宕机,那么后台也不能操作,耦合度太高。
再者,前台是发布到外网,后台是发布到内网,内网安全性更高。
2.其它的模块。曾今有人建议过,前后台两个项目有一些项目是重复操作的,比如修改,查询一些业务,有人提议再建立一个web项目same,提取出这些重复的dao,service,或者说把这些dao层service层全部抽取出来做一个独立的模块,这些重复的东西结合在一起,也做一个集群。
当然这样是省了不少代码。我是反驳的,首先是增加成本,其次是破坏了前后台分离设计的一个初衷,后台同样会被前台拖累,因为他们访问同样一个dao,service。后台与前台无异。后台必须优先,在一些特定的情况下能解决一下特定的问题。比如可以快速增加库存余量。
当然这个技术是可以实现的: 那么这就涉及到了我们maven里面的重要知识点,即依赖。same工程被前台工程依赖,同时也被后台工程依赖。我们的java工程是可以打包成jar,只要我们把打成的jar放到前台项目和后台项目中,就解决了这个依赖问题。但是这种拷贝的方式显然是过于笨重。我们显然可以使用另一种方式 即maven的依赖管理,使用maven的依赖管理功能我们就不用自己把 java工程打成jar拷贝到那两个项目中了。
3.图片模块,pictrue。做一个图片上传的服务器,如果是淘宝那种C2C,前端是有上传图片需求的。但是B2C的话,客户端是没有权限上传这些资源的,头像基本采用系统默认选择有限。如果图片资源小,没必要这个服务器的。比如小公司的门户网站,就没必要。
商城的话,是需要的,具体看图片容量。量较小,FTP是单机独立的。量大,FastDFS是一个分布式文件服务系统。
4.项目整合。算起来有三个模块:前台、后台、图片模块。他们在模块分别没有关联性,但是在业务上有,这三个模块不需要做刻意的整合。
虽然没有用到,但是要说说整合这块的知识。如果我们使用了前面的same,那么我们个模块是没有关联性的,在业务上也很难彼此调用。
所以我们还需要创建一个pom项目(父工程)。pom指的是工程对象模型,即这个pom web工程可以把散的四个工程分别当做对象来进行管理。使用父工程web项目去管理这个四个散的模块使他们有机结合起来,能够相互调用并且进行信息交互。这个pom父工程除了管理这四个模块并没有其他功能。
二、项目的部署(构架)
如图:
A、后台部署的话使用单机模式就行了,即只需要一台主机,因为后台本身用户量就不会有多大,都是管理人员,既然用户量不大的话这个并发量就更小了,充其量达到一百就不错了。
B、前台是互联网用户访问的,所以并发量会很大,所以要考虑你这个服务器对于并发量的支持问题。所以前台做集群部署(上面讲过)。
举个例子,比如三台服务器, 分别放着前台()做集群,那么这三台服务器的ip是不一样的,分别为192.168.1.101,192.168.1.102,192.168.1.103。这里注意了,我们的服务器一般都使用linux或者unix系统的。以上三台服务器的三个ip都是内网ip。那么有些人就奇怪了,内网的东西如果被外网访问到,这里我们在讲一下反向代理的概念。首先解释一下什么叫代理,代理是什么,代理就是有人替你做些事情,比如中介,也是代理啊。
代理分为正向代理和反向代理。
正向代理:我们从内网访问外网所经过的代理服务器,我们使用ipconfig查看到的一般是内网ip,但是我们从内网访问外网的话是需要代理服务器的。但是我们现在的情况是要让外网的互联网用户访问到我们内网的服务器,那么外网直接访问内网是无法访问的。这时候就需要借助代理服务器,得通过代理服务器为我们做一个代理,通过代理服务器去访问内网,这就是反向代理。即反向代理就是让外网访问内网的。如果现在我们的三台服务器是外网ip的话,我们直接就可以访问了,多方便,那为什么要使用内网ip呢?因为对于我们服务器的安全性大大提高了,不会轻易被攻击。那么这台代理服务器的ip肯定是外网ip。
正向代理:从内网访问外网所经过的代理服务器。
反向代理:从外网访问内网所经过的代理服务器。
现在我们在市面上用的反向代理服务器有Apache的HTTP服务器。
但是现在还有一个非常火的,如日中天的一个服务器,即nginx,这个服务器现在也在大量的使用,因为这个服务器的性能非常高,支持的并发量也很大。现在很多互联网项目都是用Nginx,官方发布数据是三台nginx在一瞬间能够支撑5万的并发量但实际只能够支撑2万。
Nginx服务器有三种能力,第一种就是反向代理,刚才已经讲过了。第二种是负载均衡的能力。第三种是静态文件处理能力,这个我们接下来具体讲解。
我们来看一下我们的部署图,我们图中的nginx起到一个反向代理的作用,这是他的一个特点。那么接下来就是nginx负载均衡的能力。
当互联网中的请求来的时候,我们可以配置规则,即我们服务器只接收.do或者.html等以其他后缀结尾的请求。当一个.do请求过来之后,nginx给你拦截下来,拦截下来之后,他自己并不去处理这个请求,而是帮你转发到后台集群的这几台服务器上,那么到底转发到哪台呢,那么可以在nginx上做一些配置,即做一些权重的配置。
什么叫权重呢?就是给我们这里的三台服务器分配不同的压力。
比如,给第一台分配30%的压力,给第二台分配50%的压力,给第三台分配20%的压力,具体得看你这三台服务器的配置所支持的能力,如果他们的配置都是差不多的话,你可以平均分配压力。
这边nginx也很智能,他不会把所有请求都分担在一台机器上,Nginx会为我们按照权重做一个只能的分配。这就是nginx支持集群并且能够做负载均衡的能力。我们在使用nginx做集群和负载均衡之前使用的原始方法是DNS轮询,DNS轮询也能起到一个集群作用,但是无法做到负载均衡。DNS老早之前已经被淘汰了,为什么呢,就是因为因为DNS轮询会导致分配不均,分配不均的话就会导致一台机器压力很大,其他机器闲置,明显没有起到负载均衡的作用。
nginx主要就是在服务器集群的基础之上起到负载均衡的作用,让用户访问压力平均分配到这些服务器上来,这样的话我们后台的处理能力明显得就提升上来了。那么实际上在nginx前端还有一个东西叫F5,他是一个硬件的负载均衡器,这个硬件负载均衡器能够支持非常大的并发量,互联网用户只要访问F5这一个就行了,那么在F5上把请求往nginx上分发,但是F5价钱不菲,几十万到几百万之间。但是我们这边不使用F5直接访问nginx也是可以的。
但是有一个问题叫三点故障问题,即如果我们部署nginx服务器的这台机器宕机了,那么就没法访问我们的后面的三台服务器了。相当于nginx是一扇大门一样,门关了,外面的人也就没法进来了。我们很容想到,可以多部署几台nginx服务器嘛,是的,在大型的互联网项目中,一般nginx都有两台,即双机模式,但是用户进来之后该访问哪台呢?这就要我们使用F5做负载均衡,去管理这两台Nginx服务器,F5的负载均衡指的是对nginx的负载均衡即给nginx分配用户访问压力,这样一来一台nginx服务器出现故障了,F5还可以支配另一台nginx服务器应对用户访问,避免我们这里的三点故障即一台nginx宕机了,整个项目就无法运行了。所以使用F5对nginx做负载均衡,一台nginx服务器宕机了还有另一个台可以使用,这对于来访问互联网用户是没有影响的,就不会出现问题。F5是硬件负载均衡器稳定性是很高的。
那么两台nginx做负载均衡,他有两种策略。
1.其中有一台作为备机,只有当另一台运作的机器出现故障了,那么这台才启用。
2.两台机器都启动,做负载均衡和反向代理。
我们还可以把后台的一整个模块拆分成几个小模块(war包),然后把每个小模块分别部署到单个服务器上(肯定不是单个机器上,这里是要做集群的),这就是分布式部署,然后通过另一台备用的nginx为这几个小模块做负载均衡,不是备用的还是为原来的几个整体的模块做负载均衡。如果在某个时间,对这几个拆分了的特定的小模块业务访问量很大,就可以单独访问备用的nginx服务器及其后面的web服务器。这样的话,我们整个这样的部署,就明显分担了更多的压力了。
那么以上结构有一个问题:
模拟情景:某个用户想要从我们这个网站下载资源,但是他必须先登录。
所以用户输入信息点击登录之后,登录请求就会通过F5硬件负载均衡器过来的,F5把请求交给其中一台nginx,然后nginx再把请求发给我们的前台服务器1。假设用户通过校验,那么这台1服务器会产生一个session存储该用户的登录信息,接下来该用户就可以下载资源了,当点击下载的时候下载资源请求再次通过F5硬件负载均衡器过来,F5把请求再分发给其中一台nginx,但是1服务器已经很忙了,所以这台nginx把我们的下载请求交给了前台服务器2处理,但是我们的前台服务器2他并没有存储了该用户信息的session,
当服务器2收到这个下载请求时首先会判断你有没有登录(找存储了用户信息的session),很明显你是无法从服务器2中顺利地下载资源的。那该怎么办呢?
解决方法
1.最原始的解决方法是session的共享或者叫session的复制,那么什么叫session共享呢?就是当一台服务器中有session了,那么同时也会给其余的服务器复制相同的一份session,让这些服务器有同样的session。但是这种方法有一个问题,在session复制的时候就会产生一个性能的问题,如果用户数量越多session就是复制得越频发,还有就是你服务器集群的数量越多session复制得也越多。本质上就是你的使用量越多,session的复制也就迅速增长,我们把这个叫做session复制风暴,他会对我们的服务器性能产生很大的影响,所以这种策略我们是不采用的。
2.第二种方法是最合适的,但是我们还需要一台服务器, 这台服务器我们需要部署非关系型数据库redis, redis是一个用c语言编写开源的key-value存储系统(nosql),学过java的应该都知道java集合这章中的map吧,map也是key-value(键值对)的形式存储数据的吧,redis和这个是类似的。属于非关系型数据库。现在redis是一个比较火的技术,在redis中他可以把session做一个接管,也就是redis可以和我们的前台这些服务器做一个整合,那么如何整合呢?回到我们上面假设的原始情景中,当互联网用户输入信息点击登录后,我们的请求经过F5和nginx来到前台服务器1,此时服务器1中当前用户session不是服务器1自己创建和管理的而是交给redis服务器来创建和管理。当用户再次点击下载链接时,请求通过F5和nginx被传到了服务器2上,然后服务器2从redis服务器中获取对应的session,判断当前发送请求的用户是否已经登录,这样的话这个问题就很好的解决了。也不会出现session复制风暴的问题。Session服务器也是可以做集群和分布式部署的(包括redis数据库分页,读写分离,主从复制。主负责写,从负责读)。
接下来讲的是nginx的静态文件处理能力:静态文件处理,如果我们的静态页面即给访问者浏览的页面放在前台服务器上,那么前台服务器处理静态页面的能力是不够的。
所以我们不能把静态页面发布到前台服务器中,我们得发布到nginx服务器上。那么发布到nginx的时候我们是从管理员后台服务器进行发布的,那么我们如何在从管理员后台服务器把静态页面和图片发布到nginx服务器上呢?我们之前做发布的时候是使用webservice来做的。现在如果要把静态页面和图片发布到nginx上,就需要在nginx部署webservice,但是nginx是无法部署webservice的。我们要在管理员后台和nginx之间做一个静态化发布。
第一种方案:使用共享服务器rsingle,和nginx两台机器上,都有 一个文件夹相互做同步,只要把静态文件放到自己机器的此文件夹中同时也会同步到对应的nginx机器的文件夹上。
第二种方案:在nginx安装一个tomcat服务,部署webservice服务war包,这个war的功能是专门用来接收静态文件的,部署之后就让这个tomcat来接收静态文件和图片。这个tomcat中得部署我们的webservice服务war包,那么webservice服务我们发布了之后就会调用这里面的服务从而把中静态文件发送到nginx当中,专门放在一个存储静态文件的文件夹中,这样的话当互联网用户来访问的时候,当请求来到nginx的时候,nginx就会判断,当前请求是.html或者.jpg或者.css结尾的,即请求静态资源的,就不会再把该请求发送给前台服务器中去处理而是直接在自己nginx服务器上处理。
总结: 项目中nginx服务器的作用
1.反向代理:从外网访问内网所经过的代理服务器,拦截.do或者其他结尾的请求,做集群(目的:负载均衡),转发给前台服务器。
2.负载均衡
3. 静态文件处理能力。
数据库集群和分布式。
下面的简单讲解一下:
我这里还没有讲数据库的集群和分布式包括主从复制、读写分离。
大型网站需要存储海量的数据,为达到海量数据存储,高可用,高性能一般采用冗余的方式进行系统设计,本质上其实就是通过空间换时间,比如原来一台数据库服务器既负责读也负责写,现在读单独放在一台服务器上,写也单独放在一台服务器上,提高了读写效率。
一般有两种冗余的系统设计方式:读写分离和分库分表。
读写分离:一般解决读比例远大于写比例的场景,可采用一主一备,一主多备或多主多备方式。
读写分离简单的说是把对数据库读和写的操作分开对应不同的数据库服务器,这样能有效地减轻数据库压力,也能减轻io压力。主数据库提供写操作,从数据库提供读操作,其实在很多系统中,主要是读的操作,例如你浏览淘宝一般是看得多,写得少吧。当主数据库进行写操作时,数据要同步到从的数据库,这样才能有效保证每个数据库的完整性。
主备:
这一般是数据库的安全策略,对于一些安全性要求比较高的系统,数据库通常是由主服务器和备份服务器组成,主备同时运行,主服务器有数据改动后,立刻会同步到备份服务器。所以在日常运维工作中,为了防患于未然,经常会进行主备切换,就是把生产对接的服务器从主数据库切换到备份库上,使用备份库运行一段时间,看看备份库运行是否正常,数据是否正确等。
切换的操作只需将连接池中,数据库服务器的ip换成备份库ip就可以了。
数据库分库和表拆分(分库分表):
1. 业务拆分后:每个子系统需要单独的库。
2. 如果单独的库太大,可以根据业务特性,进行再次数据库拆分,跟我们上面讲的拆分是类似的,比如我们可以把数据库分为商品分类库,产品库;
3. 分库后,如果表中有数据量很大的,则进行表拆分,一般可以按照id,时间等进行表拆分
4. 在分库,分表的基础上,进行读写分离
底层拆分的数据库进行分布式部署和集群部署。
.同帐号登录的同步:
A、redis缓存,每个用户登录生成一个key,登录首先读取这个key,存在则断掉。
B、实现session共享,上面说过风暴式增加服务器的压力。
C、在数据库增加登录状态码。这种说法一般都是没有工作经验的人,为什么了,理解A和B就知道了。当然也是可以的,登录必须经过数据库。
以上是关于电商项目总结的主要内容,如果未能解决你的问题,请参考以下文章