购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.4 大型系统架构设计

在设计大型系统的架构时,要特别注意对流量的控制,可以采取降级、限流和缓存等策略。本节先介绍一种常见的流量负载架构,然后给出一种流行的软件技术选型,供读者在开发时参考。

2.4.1 服务预处理——限流与多层负载

为了保证亿级流量下的高性能及高可用,除了精湛的编码功底和巧妙的算法外,还需要对海量请求进行多级限流和多层负载。本小节提供几种处理客户端海量请求的思路,供读者参考。

(1)拦截非法请求,从而进行一定程度的限流,举例如下。

① 加入验证码,防止机器人恶意攻击。

② 隐藏秒杀入口地址,确保用户在进行了合理的操作后才能进入。

③ 限制IP操作:对于秒杀等限量业务,限制某一IP能够发起请求的次数。

④ 延长用户操作时间:为避免用户刷单,可以对具体业务在操作时间上进行限制,如同一用户5s内只能进行一次操作。

(2)通过LVS对客户请求进行分流(负载均衡),并通过Keepalived实现多机部署、防止单点故障。

(3)通过Nginx将请求进行动静分离:将静态请求部署到CDN上进行加速(或直接在Nginx中缓存),将动态请求发送给MQ进行流量削峰(当有大量请求时,为减轻服务端压力,可以先在MQ中设置可接收的最大请求量;超过最大值的请求将被直接丢弃)。

关于Nginx还需要注意以下两点。

① Nginx处于OSI网络模型的第七层(应用层),除了实现动静分离外,还可以用于各种策略的负载均衡(如轮询、指定访问的URL规则);而LVS处于OSI的第四层(传输层),是利用Linux内核直接对流量进行转发,可靠性高并且对CPU及内存的消耗低。

② Nginx还可以实现定时器、封禁特定IP/UA等功能,并且可以通过缓存、Lua插件等实现一些简单的功能,直接处理一部分用户请求,从而减轻服务端的压力。

(4)可以将同一个服务多次部署到多个节点上,形成集群服务(如图2—13中有两个“服务A”),并用Nginx进行整合,用来实现并发请求的负载均衡和失败迁移。

(5)项目中的所有服务都可以通过Maven或Gradle进行依赖管理,并使用Git/GitHub进行版本控制和团队协作开发。

以上步骤如图2—13所示。

图2—13 请求处理流程

(6)进一步扩容。以上架构已经能够扛得住千万级的流量了,但如果遇到“双十一购物”“12306抢票”“大型电商秒杀”等亿级流量,还需要做进一步改进。

如图2—14所示,可以进行以下两点扩充,搭建最终的LVS+Nginx+DNS负载架构。

① 通过DNS绑定多个LVS组成的集群,进一步实现负载均衡。

② 通过Nginx将动态请求的路径转发到特定的服务地址上。例如,当用户访问lanqiao.org/payment/时,Nginx将该请求分发到服务A上,当用户访问lanqiao.org/goods/时,Nginx将该请求分发到服务B上。

图2—14 多级负载架构

值得注意的是,如果系统本身不是很大,就没有必要使用以上所有组件。例如,软负载均衡LVS的确可以减轻后面单个组件的压力,但LVS自身也存在着不足,它会使原本直接到达Nginx的请求在LVS自身中转了一次,因此会增加系统中的网络流量,并且带来一定的延迟。简言之,任何一个中间件都可能增加系统的稳定性及性能,但同时也可能存在一定的弊端,在实际使用时一定要结合项目的实际情况慎重权衡。

2.4.2 各组件的技术选型建议

海量请求在经过多级限流和多层负载后,就会抵达应用服务进行实际的处理。复杂的大型系统可以采用分布式或微服务架构搭建具体的应用服务。以微服务架构为例,可以使用以下技术处理用户的具体请求。

(1)通过Zuul再次屏蔽某些不合理请求,或生成各个微服务的虚拟地址。

(2)发来的请求经过SpringMVC等控制器进行跳转,并通过Ribbon或Feign进行客户端负载均衡,发送给一个压力较轻的服务端处理。

(3)控制器根据具体情况,可以请求Eureka中已注册的微服务,也可以通过gRPC、Thrift、Netty+Protobuf等RPC方式整合其他语言提供的服务。

(4)微服务可以使用Spring Boot进行快速构建,并用Spring Cloud组装各个微服务。例如,将各个微服务注册到Eureka中,并通过Hystrix进行熔断处理或服务降级、通过Dashboard进行服务监控等;此外,每个微服务可以使用经典的MVC模式或三层架构。

当然,除了用Spring Cloud搭建微服务架构外,还可以使用Dubbo+Zookeeper的方式。

(5)对于不同的服务,适当选取相应的技术。例如,使用ElasticSearch实现搜索功能、使用Shiro或Security实现安全处理、使用FastDFS或HDFS实现分布式文件系统、使用MapReduce进行分布式离线计算、使用Storm进行流式计算、使用Spark进行实时计算。

(6)各模块、各服务之间使用Restful风格相互调用,并通过JSON格式返回处理结果。

以上步骤如图2—15所示。

图2—15 技术选型参考

在实际开发时,除了以上架构中的技术外,还需要通过JVM、JUC、Netty等高性能底层技术来提高项目的效率和健壮性,并且使用Future模式等提高对用户的响应速度。 kMiIZRmdXk62wptq2WRIse+m46G2+/dhPCkI/o4MvibeodguEpsybG8gxoEqEFXz

点击中间区域
呼出菜单
上一章
目录
下一章
×