架构的演进
没有最好的架构,只有最合适的架构
技术和业务的关系
技术是为业务服务的,互联网公司业务靠技术支撑
三高架构
高可用
高并发
高性能
高可用
高可用
保证服务稳定,重点是解决单点故障问题。因为单点故障,所以要有备机,要有自动故障转移。主备架构或主从架构
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 机制
初创公司架构
无运维团队,购买云服务
4台esc组成高可用架构
此处可以明显看出,nginx的负载均衡策略很重要。并且再以后的架构演进中,nginx一直在架构中,很重要。所以,接下来重点讨论下nginx 的负载均衡配置
nginx负载均衡
将多台服务组成集群,前端使用nginx实现负载均衡,将请求分散打到后端服务中
实现负载均衡的分发,对三高会有一定的提升
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;
}
- 默认轮询
upstream node { server 10.20.0.10:8080; server 10.20.0.11:8080; keepalive 65; }
- weight 加权轮询
upstream node { server 10.20.0.10:8080 weight=5; server 10.20.0.11:8080 weight=10; keepalive 65; }
- ip_hash
upstream node { ip_hash; server 10.20.0.10:8080; server 10.20.0.11:8080; keepalive 65; }
- url_hash
upstream node { hash $request_uri; # 第三方 server 10.20.0.10:8080; server 10.20.0.11:8080; keepalive 65; }
- 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;
}
动态资源负载均衡
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;
}
动静资源分离
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匹配顺序
location = / {} # = 精确匹配
location / {} # 普通匹配
location /images {} # 普通匹配
location ~/documents {} # 普通匹配,区分大小写 ~
location ^~ /images/ {} # 普通匹配,区分大小写 ~ 以/iamges/开头 ^
location ~* \.(git|jpg|png)$ {} # 正则匹配 ~* 以.git .jpg .png 结尾 $