架构的演进

没有最好的架构,只有最合适的架构

技术和业务的关系

技术是为业务服务的,互联网公司业务靠技术支撑

三高架构

高可用 高并发 高性能

高可用

高可用 保证服务稳定,重点是解决单点故障问题。因为单点故障,所以要有备机,要有自动故障转移。主备架构或主从架构

lvs + keepalive 实现主备切换

nginx + keepalive 实现主备切换

mysql 主从 MHA自动故障转移 (主从复制异步,有丢数据风险)

redis 主从 sentinel自动故障转移 (主从复制异步,有丢数据风险)

高并发

高并发 提升qps tps,单点并发一定有上限。主从架构、分片架构

主从架构读写分离可以有效解决读高并发,写仍然有单点限制。因此衍生出分片机制

主节点按照一定规则进行分片,如hash分片,每一个分片在有自己的从节点。

redis cluster hash槽

mysql 根据用户id 或 订单id进行哈希分片(代码实现或使用proxy)

此处可参考akf划分原则,x轴先进行业务划分,y轴再进行数据分片,z轴主从架构

高性能

高性能 开始追求对cpu的性能压榨了,要深入了解计算机底层原理。对cpu、内存、硬盘、网络、io等要有清晰的认识,对linux内核要有基本的了解

进程内 锁的升级机制,cas轻量级锁、重量级锁,atomic 原语

kafka高性能底层逻辑,批量、异步、mmap、顺序写入、sendfile(零拷贝)、内核刷盘机制

msyql高性能底层逻辑,wal(write ahead log)、内核刷盘机制、mvcc、锁

redis高性能底层逻辑,基于内存,计算想数据移动,6以后iothread为多线程,网络IO epoll机制,copy on write 机制

初创公司架构

无运维团队,购买云服务

image-20210927132823715

4台esc组成高可用架构

此处可以明显看出,nginx的负载均衡策略很重要。并且再以后的架构演进中,nginx一直在架构中,很重要。所以,接下来重点讨论下nginx 的负载均衡配置

nginx负载均衡

将多台服务组成集群,前端使用nginx实现负载均衡,将请求分散打到后端服务中

实现负载均衡的分发,对三高会有一定的提升

image-20210927141318907

Nginx要实现负载均衡需要用到proxy_pass代理模块配置

Nginx负载均衡与Nginx代理不同地方在于

Nginx代理仅代理一台服务器,而Nginx负载均衡则是将客户端请求代理转发至一组upstream虚拟服务池

Nginx可以配置代理多台服务器,当一台服务器宕机之后,仍能保持系统可用。

upstream 配置

相关参数

  • server 反响服务地址 + 端口
  • weight 权重
  • max_fails 失败多少次 认为主机已经挂掉,则踢出
  • fail_timeout 踢出后重新探测时间
  • slow_start 当节点恢复,不立即加入,而是等待 slow_start 后加入服务队列
  • backup 备用服务 当配置的集群所有服务挂掉了,启用当前的配置项
  • max_conns 允许最大连接数

负载均衡算法

  • ll + weight 轮询+权重(默认)
  • ip_hash 基于公网ip hash,可保证同一个用户访问永远打到同一个实例上。可能有流量倾斜压力
  • url_hash 基于url hash(第三方),可保证同一个url永远打到一个实例上
  • least_conn 最少连接(第三方)
  • least_time 最小响应时间(第三方)
upstream node {
  server 10.20.0.10:8080;
  server 10.20.0.11:8080;
}
location / {
  proxy_pass http://node;
}

  1. 默认轮询
    upstream node {
     server 10.20.0.10:8080;
     server 10.20.0.11:8080;
     keepalive 65;
    }
    
  2. weight 加权轮询
    upstream node {
     server 10.20.0.10:8080 weight=5;
     server 10.20.0.11:8080 weight=10;
     keepalive 65;
    }
    
  3. ip_hash
    upstream node {
     ip_hash;
     server 10.20.0.10:8080;
     server 10.20.0.11:8080;
     keepalive 65;
    }
    
  4. url_hash
    upstream node {
     hash $request_uri; # 第三方
     server 10.20.0.10:8080;
     server 10.20.0.11:8080;
     keepalive 65;
    }
    
  5. least_conn 最少连接数
    upstream node {
     least_conn; # 第三方
     server 10.20.0.10:8080;
     server 10.20.0.11:8080;
     keepalive 65;
    }
    

proxy_params

proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_connect_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;

proxy_buffering on;
proxy_buffer_size 32k;
proxy_buffers 4 128k;

静态资源代理

http > server >

location ~* .*\.(png|jpg|git)$ {
    root /data;
}

image-20210928162725700

动态资源负载均衡

http >

upstream node {
  server 172.16.213.133:9090;
  server 172.16.213.134:9090;
}

http > server >

location /hello {
  proxy_pass http://node;
  include conf.d/proxy_params;
}

image-20210928163717292

image-20210928163731885

动静资源分离

http >

upstream node {
        server 172.16.213.133:9090;
        server 172.16.213.134:9090;
    }

    upstream static {
        server 172.16.213.133:80; #静态资源服务器
    }

http > server >

location /hello {
  proxy_pass http://node;
  include conf.d/proxy_params;
}

location /images {
  proxy_pass http://static;
  include conf.d/proxy_params;
}

nginx location匹配顺序

image-20210928170502687

location = / {} # = 精确匹配
location / {} # 普通匹配
location /images {} # 普通匹配
location ~/documents {} # 普通匹配,区分大小写 ~
location ^~ /images/ {} # 普通匹配,区分大小写 ~ 以/iamges/开头 ^
location ~* \.(git|jpg|png)$ {} # 正则匹配 ~* 以.git .jpg .png 结尾 $
Scroll to Top