Skip to content

Latest commit

 

History

History
110 lines (64 loc) · 5.44 KB

部署高性能应用.md

File metadata and controls

110 lines (64 loc) · 5.44 KB

部署高性能的服务架构

关于如何部署一个Node应用,Google有很多很棒的文章,现在最流行的两种方案

  • PM2直接部署
  • Docker部署

本文想站高一点点,聊聊如何部署一个高性能、高可用的Node服务(Java/Python/Go服务也一样),主要围绕部署服务的发展历史以及Node应用的负载均衡,不单单是部署成功这件事,也不会涉及Node语言本身的特性,比如异步IO、事件回调、单线程等

本文不讨论Node在高并发、I/O 密集场景的性能问题

一、部署服务的发展历史

从就部署一个没什么流量的博客应用开始吧,假设这个博客的流量会慢慢暴涨,对高并发高可用带来了挑战

1.1 单机部署

只有一台机器,有很强的单点隐患

1.2 多机部署

单机有风险,那就部署多几台机器

但是,前端怎么知道该访问哪台服务呢?

架构设计经典共识:没有什么事加一层解决不了的,如果有,那就再加一层

在这N台服务面前加一层LB (Load Balance 负载均衡),一般由Nginx担任这个角色,LB统一接受请求,再分发到某一台机器

而且Nginx这一层可以拿到用户的信息,能做一些动态分发、简单的逻辑处理等

博客流量开始慢慢增加,开始有爬虫、恶意大流量打进来,三台服务器也快撑不住了

1.3 增加网关

在流量到达真正的服务器之前,加一层网关,用来鉴权、防爬、限流等,保证打到服务器的流量是安全可控的

1.4 动静分离

在现代Web架构中会有很多静态文件请求,比如html、js、css等,这些流量其实可以不用每次都打进服务器或者读取服务器,可以利用 Nginx 对静态资源的缓存能力,或者直接把静态资源部署到CDN上去(最后再补上CDN的图)

1.5 Nginx主备容灾

上门的架构中,单点风险从服务器转移到了Nginx上,所以Nginx也需要以主备的形式部署两台机器,备Nginx通过 keepalived 心跳机制感知主机状态,如果主机宕机,则备Nginx自动切换为主机的角色

Nginx是七层负载均衡器,面向应用层的HTTP,转发流量需要client和上游server各自建立TCP连接,并放入内存缓冲区

建立TCP连接与机器I/O、CPU内存等相关,所以Nginx的抗负载能力在更大的流量面前(百万)也会扛不住

能否不建立TCP连接,直接转发流量包呢?

1.6 LVS (Linux virtual server,linux虚拟服务器)

LVS建立在传输层(TCP/UDP),只转发包(修改地址),不需要和上下游建立连接,相对于Nginx的抗负载、性能更好

同样的道理,单个LVS也存在单点风险,再加几台?那么如何访问多加的几台呢?

1.7 DNS负载均衡

利用DNS来做域名解析的负载均衡

1.8 大型架构

补上CDN,这已经是非常大型的现代Web架构了,主要分层

  • CDN处理静态文件
  • 通过DNS负载均衡解析域名,随机打到其中一台机器
  • LVS集群做负载均衡,转发流量
  • Nginx作为接入层,做流量区分
  • 网关层做统一鉴权、限流等,还可以做服务的发现和注册

二、负载均衡

从上面的大型架构发展历史,可以看到基本每一层都有负载均衡的存在,再回到Node应用本身,也有负载均衡的存在,主要有两个

  • 进程服务负载均衡
    • Node通过集群(cluster)模式实现了多进程
  • RPC调用负载均衡
    • 主要是解决不同服务之间的调用问题,包含传输协议、序列号协议等

关于Node的多进程可参考我这篇 blog/多进程与多线程 — GitHub

具体的负载均衡算法主要有三种

  • Round Robin :依次轮询,调用非常均衡,缺点是无法考虑服务器的真实情况
  • Weighted round robin:基于轮询加权重判断,但可能会导致某个节点的负载突然上涨
  • source IP hash
    • 服务存储状态session,通过一致性hash+虚拟节点算法实现
    • 可以保证用户session,缓存命中率高,但是负载均衡性能比较差

关于负载均衡的算法这里不展开,可参考

Node.js V0.12新特性之Cluster轮转法负载均衡-InfoQ

nodejs负载均衡(一):服务负载均衡 - 知乎

nodejs负载均衡(二):RPC负载均衡 - 知乎