一、 架构设计
大型电商网站(淘宝、亚马逊等)具有两种特定:
- 门户网站性:信息大,千万种产品详情(文字,图片,视频等)
- 社交服务性:交互多,多种请求和响应(购买,退货,查询物流等)
所以一个成熟的可以承载大流量的电商网站需要考虑各方便的优化比如产品详情采用 CDN,静态化等技术,交互多的手工银行业采用分布式缓存、Nosql等技术。
本文介绍Iaas解决方法,对于电商网站场景的构建和设计。
二、 网站初级架构
介绍:电商网站初级架构很简单,主需要三台服务器,一台用来响应请求,一台做数据库,一台存储图片。当服务器受到来自客户端请求后,去数据库和文件系统获取对应资源然后返回,逻辑清楚,实现简单。
- 这种系统的几个显著的问题
- 大型电商网站的访问量和事务处理时单台服务器无法负担的,即使是一个服务集群
- 所有应用部署在同一台服务器,有tomcat,nginx,rabbitmp等,耦合严重需要垂直切分和水平切分
- 频繁从RD读写数据,数据库访问压力巨大
- 业务和异常记录都存在对应应用的log中,查找起来很不方便
三、 架构优化
目前泛互联网团队主要从以下方面对电商场景架构优化:
- 业务拆分
- 应用集群部署(分布式部署,集群部署和负载均衡)
- 多级缓存
- 消息队列
- 服务化
- 数据库集群(读写分离)
泛互联网团队电商架构
四、 泛互联网团队架构介绍
从事务处理来介绍该架构:
- 对外暴露增强ELB的EIP作为网站的IP地址,所有client请求是通过ELB
- ELB对于client的请求根据加权轮询的负载均衡方式分配到Nginx集群中的一台服务器
- Nginx服务器收到后根据请求类型决定请求流向(以下可在Nginx.cof中定义)
- 普通URL,Nginx将使用轮询进行负载均衡转发请求到controller集群中的一台。
- HTML页面请求,则会在自己的/opt/html目录中找到对应的静态文件返回
- css、png等静态资源,则会在/opt/static目录中找到对应的静态文件返回
- 当某台controller接到request,将会根据http请求固定字段的值去Redis缓存中尝试发送get请求,如果有缓存内容则返回,若返回值为null,则请求通过dubbo(分布式服务框架)以RPC的方式发给下层zookeeper集群中leader节点,订阅服务
- zookeeper集群将把该请求转发给对应的服务提供商,再次进行负载均衡
- 某台service主机收到RPC后,将去数据库读取或者写入对应数据,将结果返回
- 由controller集群和service集群产生的日志文件被发送给一台部署了RabbitMq的服务进行统一集中以及发送给存放日志的服务器,引入DMQ,来对日志消息进行统一再转发的原因有二:
- 是对controllers,service和日志服务器进行解耦,避免依赖
- 提高消息发送的可能性,持久化,传输确认以及发布确认
分布式
分布式文件系统目前物理环境已搭好,代码逻辑还没有靠过来,之后的版本将把部分静态文件放入服务器,减轻nginx集群的压力。
五、 系统优化项
根据服务属性进行垂直分割,划分为不同的服务,购物服务,支付服务等不同的服务在不同service上部署,减少单个服务上过多冗余代码,方便之后对于单一业务代码进行重构,减少单台机器上的业务压力
六、 集群部署
- Nginx集群(第二次负载均衡及请求动静态分离)
- Contoller集群(接受客户请求)
- zookeeper集群(第三次负载均衡注册服务和订阅服务)
- service集群(提供对应服务)
七、 多级缓存
redis缓存:存储一些首页内容及热销售产品信息,这些数据被读取的数据很高,降低数据库访问压力
八、 数据库集群
- Redis主备模式(提高可用缓存服务)
- RDS主备模式(提高可用数据库服务)
可切换备份模式(异步,半同步),前者追求性能,后者追求高一致性
可创建只读备份,分担数据库压力
九、 服务化
service的业务逻辑的模式在zookeeper中进行注册,用dubbo框架进行调用,将web层和业务层解耦,实现两个运行在不同tomcat下服务接口调用
十、 消息队列
- RabbitMQ作为消息队列发送方只需要把自己的日志记录传给该节点,而无需确认最终能到达日志服务器(消息队列确保)
- 当有新的数据进行保存时,只需要新增一条bingding指定client和consumer即可,解耦了最终接受方和发送方的依赖
十一、 其他技术
ELB作为网站的入口,提供第一次的负载均衡,还可以轻易扩展其他的业务,比如http转https,URL和域名转发等
十二、 框架展望
- 引入AS(Auto Scaling)弹性伸缩服务来应用电商的潮汐场景
- 完成文件服务器的代码层连接,减轻Nginx集群的压力,并实现由controller主动上传静态文件的功能
引入obs(对象存储)如MongoDB来实现大数据下数据库快速横向扩张满足读写要求