返回首页

正经一点的云端 Web 架构

GCP vs AWS 的负载均衡器选型,加一个典型 Web 应用的部署示例。

发布 2019年3月12日 标签 #cloud #architecture #aws #gcp

~/posts/aws-web-architecture $ cat post.md

/ 语言 EN / 中文
/ 主题 / /

架构的目标

只给五个人用的软件其实谈不上架构——AWS 可,ThinkPad 可,树莓派也可。但既然要谈云端 Web 应用,目标就指向负载能力和可用性。

地理

一台机器跑的服务谈不上架构。多台机器后,机器所在的地理位置就要考虑了。用户和服务之间需要负载均衡器把请求散到不同实例上。

任何一家云厂商都有”可用区”的概念。简单场景下,挑你软件主要服务的那个区就行。AWS 没有提供真正全局的负载均衡器——Route 53 也是要选可用区的。这不是说 AWS 没法服务全球,但 ELB 在跨可用区的 IP 来源是动态、不可控的。

GCP 有全局负载均衡器,能让一个 IP 服务全球(Global forwarding rules)。要做全球性的软件,GCP 这块更省事。

选型对比

GCP

直接说结论:GCP 在负载均衡这块功能比较全。当前提供三种 LB:

  • HTTP/HTTPS
  • Proxy:支持 TCP 和 SSL
  • Network:支持 TCP 和 UDP;不支持全球可用区

对外暴露用 HTTPProxy,内部服务之间用 Network

除全局可用区外,GCP 的几个加分项:

  • HTTP/HTTPS 负载均衡器支持 WebSocket。
  • 分配算法更细——AWS 的 Auto Scaling Group 和 ELB 之间通信较弱,基本是平均分配;GCP 可以基于 CPU 占用之类的信号动态分配。
  • HTTP 负载均衡器可以按 URL 把流量路由到不同实例(甚至不同可用区)。

Proxy 和 HTTP/HTTPS 都能转 HTTP?

是的。两个都能作为 HTTP 入口。区别是 Proxy 转发的是请求的克隆,HTTP/HTTPS 转发的是请求本身——前者会丢失用户的连接信息。

AWS ELB

首先,所有 ELB 都不支持跨可用区——这是前提。面向全球的服务不应该(不是不能)用 ELB。其它短板还包括分配算法、跨域配置等。

这不是个对已有项目容易换的决策,且 GCP 这些服务也上线得比 ELB 晚很多——这里只是指出确实存在的差距,不是说 ELB 不好用。

物理布局

负载均衡的前提是无状态服务——每个请求落到哪台机器我们都不在乎。即便如此,ELB 对开启 Keep-Alive 的 HTTP 请求会尽量复用同一条 TCP 连接,复用时每次新请求只走两次握手而非三次。

下面看一个具体例子。

示例:典型 Web 应用

假设有这样一个应用:

  • 前端用 React + webpack 打成 bundle.jsindex.htmlstyle.css,配合 Express 做服务端渲染分发(暂不考虑同构)。
  • 后端用 Spring Boot 写 RESTful API。所有 API 无状态,数据来自一台 Redis 和一台 MongoDB。
  • 一个 Scala 写的 ETL 服务每天跑几次,把数据装进 MongoDB,把未同步的数据带出。

部署上:

  • 前端和后端都对外暴露接口,挂在同一个域名下的不同子域名上。各自指向自己的负载均衡器。
  • 每个负载均衡器后面挂一个 Auto Scaling Group:压力大时自动扩容;实例崩了就重启。
  • 同子网内,后端用内网 IP 直连 Redis / MongoDB。
  • ETL 服务也跑在这个子网里,不对外暴露任何接口或 IP。
返回首页