【网站百科】浅谈Web网站架构演变过程
专栏:网站百科
发布日期:2018-11-19
阅读量:5720
前言 我们以Java Web为例,来搭建一个简单的电商系统网站,看看这个网站可以如何一步步演变。 该系统具备的功能:
阶段一:单机构建网站 阶段二:应用服务器与数据库分离 阶段三:应用服务器集群 系统演变到这里,将会出现下面四个问题:
1、第一个问题即是负载均衡的问题,一般有5种解决方案: 1、http重定向。HTTP重定向就是应用层的请求转发。用户的请求其实已经到了HTTP重定向负载均衡服务器,服务器根据算法要求用户重定向,用户收到重定向请求后,再次请求真正的集群 优点:简单。 缺点:性能较差。 2、DNS域名解析负载均衡。DNS域名解析负载均衡就是在用户请求DNS服务器,获取域名对应的IP地址时,DNS服务器直接给出负载均衡后的服务器IP。 优点:交给DNS,不用我们去维护负载均衡服务器。 缺点:当一个应用服务器挂了,不能及时通知DNS,而且DNS负载均衡的控制权在域名服务商那里,网站无法做更多的改善和更强大的管理。 3、反向代理服务器。在用户的请求到达反向代理服务器时(已经到达网站机房),由反向代理服务器根据算法转发到具体的服务器。常用的apache,nginx都可以充当反向代理服务器。 优点:部署简单。 缺点:代理服务器可能成为性能的瓶颈,特别是一次上传大文件。 4、IP层负载均衡。在请求到达负载均衡器后,负载均衡器通过修改请求的目的IP地址,从而实现请求的转发,做到负载均衡。 优点:性能更好。 缺点:负载均衡器的宽带成为瓶颈。 5、数据链路层负载均衡。在请求到达负载均衡器后,负载均衡器通过修改请求的mac地址,从而做到负载均衡,与IP负载均衡不一样的是,当请求访问完服务器之后,直接返回客户。而无需再经过负载均衡器。
1、rr 轮询调度算法。顾名思义,轮询分发请求。 优点:实现简单 缺点:不考虑每台服务器的处理能力 2、wrr 加权调度算法。我们给每个服务器设置权值weight,负载均衡调度器根据权值调度服务器,服务器被调用的次数跟权值成正比。 优点:考虑了服务器处理能力的不同 3、sh 原地址散列:提取用户IP,根据散列函数得出一个key,再根据静态映射表,查处对应的value,即目标服务器IP。过目标机器超负荷,则返回空。 4、dh 目标地址散列:同上,只是现在提取的是目标地址的IP来做哈希。 优点:以上两种算法的都能实现同一个用户访问同一个服务器。 5、lc 最少连接。优先把请求转发给连接数少的服务器。 优点:使得集群中各个服务器的负载更加均匀。 6、wlc 加权最少连接。在lc的基础上,为每台服务器加上权值。算法为:(活动连接数*256+非活动连接数)÷权重 ,计算出来的值小的服务器优先被选择。 优点:可以根据服务器的能力分配请求。 7、sed 最短期望延迟。其实sed跟wlc类似,区别是不考虑非活动连接数。算法为:(活动连接数+1)*256÷权重,同样计算出来的值小的服务器优先被选择。 8、nq 永不排队。改进的sed算法。我们想一下什么情况下才能“永不排队”,那就是服务器的连接数为0的时候,那么假如有服务器连接数为0,均衡器直接把请求转发给它,无需经过sed的计算。 9、LBLC 基于局部性的最少连接。均衡器根据请求的目的IP地址,找出该IP地址最近被使用的服务器,把请求转发之,若该服务器超载,最采用最少连接数算法。 10、LBLCR 带复制的基于局部性的最少连接。均衡器根据请求的目的IP地址,找出该IP地址最近使用的“服务器组”,注意,并不是具体某个服务器,然后采用最少连接数从该组中挑出具体的某台服务器出来,把请求转发之。若该服务器超载,那么根据最少连接数算法,在集群的非本服务器组的服务器中,找出一台服务器出来,加入本服务器组,然后把请求转发之。
1、NAT:负载均衡器接收用户的请求,转发给具体服务器,服务器处理完请求返回给均衡器,均衡器再重新返回给用户。 2、DR:负载均衡器接收用户的请求,转发给具体服务器,服务器出来玩请求后直接返回给用户。需要系统支持IP Tunneling协议,难以跨平台。 3、TUN:同上,但无需IP Tunneling协议,跨平台性好,大部分系统都可以支持。 4、第四个问题是session问题,一般有4种解决方案: 1、Session Sticky。session sticky就是把同一个用户在某一个会话中的请求,都分配到固定的某一台服务器中,这样我们就不需要解决跨服务器的session问题了,常见的算法有ip_hash法,即上面提到的两种散列算法。 优点:实现简单。 缺点:应用服务器重启则session消失。 2、Session Replication。session replication就是在集群中复制session,使得每个服务器都保存有全部用户的session数据。 优点:减轻负载均衡服务器的压力,不需要要实现ip_hasp算法来转发请求。 缺点:复制时宽带开销大,访问量大的话session占用内存大且浪费。 3、Session数据集中存储:session数据集中存储就是利用数据库来存储session数据,实现了session和应用服务器的解耦。 优点:相比session replication的方案,集群间对于宽带和内存的压力减少了很多。 缺点:需要维护存储session的数据库。 4、Cookie Base:cookie base就是把session存在cookie中,有浏览器来告诉应用服务器我的session是什么,同样实现了session和应用服务器的解耦。 优点:实现简单,基本免维护。 缺点:cookie长度限制,安全性低,宽带消耗。 值得一提的是: nginx目前支持的负载均衡算法有wrr、sh(支持一致性哈希)、fair(本人觉得可以归结为lc)。但nginx作为均衡器的话,还可以一同作为静态资源服务器。 keepalived+ipvsadm比较强大,目前支持的算法有:rr、wrr、lc、wlc、lblc、sh、dh keepalived支持集群模式有:NAT、DR、TUN nginx本身并没有提供session同步的解决方案,而apache则提供了session共享的支持。 好了,解决了以上的问题之后,系统的结构如下: 阶段四:数据库读写分离化 这个结构变化后也会带来两个问题:
解决问题方案:
它能够大大提高查询速度。 引入搜索引擎后也会带来以下的开销:
搜索引擎并不能替代数据库,他解决了某些场景下的“读”的问题,是否引入搜索引擎,需要综合考虑整个系统的需求。引入搜索引擎后的系统结构如下: 阶段六:用缓存缓解读库的压力 1、后台应用层和数据库层的缓存 随着访问量的增加,逐渐出现了许多用户访问同一部分内容的情况,对于这些比较热门的内容,没必要每次都从数据库读取。我们可以使用缓存技术,例如可以使用google的开源缓存技术guava或者使用memcacahe作为应用层的缓存,也可以使用redis作为数据库层的缓存。 另外,在某些场景下,关系型数据库并不是很适合,例如我想做一个“每日输入密码错误次数限制”的功能,思路大概是在用户登录时,如果登录错误,则记录下该用户的IP和错误次数,那么这个数据要放在哪里呢?假如放在内存中,那么显然会占用太大的内容;假如放在关系型数据库中,那么既要建立数据库表,还要简历对应的java bean,还要写SQL等等。而分析一下我们要存储的数据,无非就是类似{ip:errorNumber}这样的key:value数据。对于这种数据,我们可以用NOSQL数据库来代替传统的关系型数据库。 2、页面缓存 除了数据缓存,还有页面缓存。比如使用HTML5的localstroage或者cookie。 优点:
缺点:
值得一提的是: 缓存集群的调度算法不同与上面提到的应用服务器和数据库。最好采用“一致性哈希算法”,这样才能提高命中率。这个就不展开讲了,有兴趣的可以查阅相关资料。 加入缓存后的结构:
我们的网站演进到现在,交易、商品、用户的数据都还在同一个数据库中。尽管采取了增加缓存,读写分离的方式,但随着数据库的压力继续增加,数据库的瓶颈越来越突出,此时,我们可以有数据垂直拆分和水平拆分两种选择。 7.1、数据垂直拆分 垂直拆分的意思是把数据库中不同的业务数据拆分道不同的数据库中,结合现在的例子,就是把交易、商品、用户的数据分开。 优点:
缺点:
问题:
解决问题方案:
垂直拆分后的结构如下: 7.2、数据水平拆分 数据水平拆分就是把同一个表中的数据拆分到两个甚至多个数据库中。产生数据水平拆分的原因是某个业务的数据量或者更新量到达了单个数据库的瓶颈,这时就可以把这个表拆分到两个或更多个数据库中。 优点:
问题:
解决问题方案:
数据水平拆分后的结构: 阶段八:应用的拆分 问题:
解决问题:
8.2、走服务化的道路 为了解决上面拆分应用后所出现的问题,我们把公共的服务拆分出来,形成一种服务化的模式,简称SOA。 采用服务化之后的系统结构: 优点:
问题:
解决方法:
阶段九:引入消息中间件 随着网站的继续发展,我们的系统中可能出现不同语言开发的子模块和部署在不同平台的子系统。此时我们需要一个平台来传递可靠的,与平台和语言无关的数据,并且能够把负载均衡透明化,能在调用过程中收集调用数据并分析之,推测出网站的访问增长率等等一系列需求,对于网站应该如何成长做出预测。开源消息中间件有阿里的dubbo,可以搭配Google开源的分布式程序协调服务zookeeper实现服务器的注册与发现。 说点什么
发表
最新评论
|
点击开启品牌新篇章