烂大街的NginxRedisMqDb架构.md
一、烂大街的NginxRedisMqDb架构
1. Nginx+接口+Redis+Mq+Db下秒杀原理
- 并发问题,不是大公司的解决方案nginx+redis+mq(kafka_+db对语言没有要求,烂大街,秒杀,限购
1-1. 一直不明白的一点是,各个地方一直在做负载,那总有一个地方是最前端的一个单体入口,这个入口那里如何支撑那么大的流量的?
握手后会消耗server资源建立receiveQ队列和sendQ队列。
1-2. 首先,说说四层和七层的区别;
- 四层负载均衡,指的是IP+端口的负载均衡;
- 七层负载均衡,指的是基于WEB请求,URL等应用层信息的负载均衡。
- 当然,同理,还有基于MAC地址的二层负载均衡和基于IP地址的三层负载均衡(路由和交换机)。
四层负载均衡,主要分析IP层和TCP/UDP层。
七层负载均衡,要分析应用层协议,比如HTTP协议,URL,cookie等信息。
1-3. 计算机集群架构按照功能和结构一般分成以下几类:LBC,HAC,HPC
1)负载均衡集群(Loadbalancingclusters)简称LBC
2)高可用性集群(High-availabilityclusters)简称HAC
3)高性能计算集群(High-perfomanceclusters)简称HPC
4)网格计算(Gridcomputing)
1-4. LVS三种模式
- NAT:Network Address Translation. 网络地址转换模式
- DR:Director Route.直接路由模式
- TUN:隧道模式
1-5. LVS中的相关角色
1)DS(Direct Server):前端负载均衡节点
2)RS(Real Server):后端真实工作服务器
3)VIP(Virtual IP):LVS对外暴露的IP
4)DIP(Direct IP):相当于后门,用于给维护人员直接访问内部节点的IP
5)RIP(Real IP):后端服务器的IP地址
6)CIP(Client IP):客户端的IP
1-6. 什么是持久连接
- 在LVS中,持久连接是为了用来保证当来自同一个用户的请求时能够定位到同一台服务器,目的是为了会话保持,而通常使用的会话保持技术手段就是cookie与session。
- cookie与session简述
在Web服务通信中,HTTP本身是无状态协议,不能标识用户来源,当用户在访问A网页,再从A网页访问其他资源跳转到了B网页,这对于服务器来说又是一个新的请求,之前的登陆信息都没有了,怎么办?为了记录用户的身份信息,开发者在浏览器和服务器之间提供了cookie和session技术,简单说来在你浏览网页时候,服务器建立session用于保存你的身份信息,并将与之对应的cookie信息发送给浏览器,浏览器保存cookie,当你再次浏览该网页时候,服务器检查你的浏览器中的cookie并获取与之对应的session数据,这样一来你上次浏览网页的数据依然存在。 - 4层均衡负载导致的问题
由于cookie和session技术是基于应用层(七层),而LVS工作在4层,只能根据IP地址和端口进行转发,不能根据应用层信息进行转发,所以就存在了问题。
1-7. 网络7层对应的协议
1-7-1. LVS是VRRP协议:是一种报文格式是UDP协议下层的一种
因此不支持tcp协议的3次握手
1-8. 路由表
1-9. TCP四层协议不是有三次握手吗?为啥LVS没有啊老师?传输控制层:握手包,分手包
三次握手LVS请求要走LVS;建立握手后开辟了资源client可以和server直接通信
断开连接时遵循四次分手, 双方两个都需确认断开才能断开
1-9-1. 四层不一定拿到数据,但是一定能看到数据:比如内裤案例
看一下:LVS看到数据触发规则直接根据port把数据扔给服务器
摸一下:像tomcat等容器,会把数据请求摸一下?不理解。
2. Nginx+Redis+MQ+Db限购实现原理
多服务器最简单的方式server可以直接是tomcat;一般是nginx
client-LVS(+keepalive)+tomcat
2-1. 动静分离
nginx静态资源,tomcat动态资源=》nginx+tomcat属于组合成动静分离;静态资源请求数有可能远大于动态资源。
2-2. 反向代理
- 根据uri到指定tomcat是反向代理
- nginx是web server,tomcat是web容器
2-3. 负载均衡
- 同一个URI可以负载到多个tomcat容器中是负载均衡
2-4. KeepAlive HA(守护进程)
2-5. 单体应用的弊端(只有一个tomcat里同时又搜索和购物业务)
2-5-1. 后端服务的发展:多线程=》多进程=》多tomcat容器=》多tomcat容器微服务
单体应用优化=》线程=》线程池
3. Ng+Redis+MQ+DB下亿级流量实现
3-1. 隔离:线程隔离(线程池概念)-进程隔离(cpu资源隔离)-队列隔离(缓存隔离)-容器隔离
隔离的容器只有一个服务资源利用率会高。
3-2. 导致的问题:session共享 引出Redis
redis存状态而服务是无状态的。登录状态存在redis里
3-3. 服务无状态就可以伸缩扩容容器数量
如果服务自己维护状态如果某个容器出现问题就会导致容器间状态数据不一致对外表现不一致。
单例模式不能有属性(final不算)就是不能有状态,因为多线程环境下不能保证状态唯一。
4. Redis在架构中的意义
4-1. 秒杀:抢,便宜,不能多卖(吸引流量&促销&带动其他商品)
4-2. 不要因为技术而技术~~!因为解决所有问题强一致性是实现不了的=》追求最终一致性即可。
对于itemX 99件扣减库存时候是行级锁是串行的
加lvs 加更多ng和tomcat只是让大家建立更多链接握手增加流量能力;大家等待排队去购买;对于单个商品没有意义。
而对于多个商品imtey 99件:上面加流量链接是有效果的因为对于数据库imtey的购买扣减和imtemX的扣减可以并行处理。
4-3. 数据分段(对商品itemX分段)
导致问题:无效请求2个,一个等待请求。
4-4. 过滤无效请求
4-5. 异步处理(mq只要可以一致性+mysql id一致性)可以最终保证数据一致性
秒杀可以少卖不可以多卖,用户体验响应速度最重要,所以扣减可以最后的几件不卖也没问题。
4-6. 限购和秒杀一起聊
也可以实际库存准备80按照100的库存卖
5. 分布式微服务是快了还是慢了
5-1. 怎么做限购?逻辑业务模型
梳理业务模型后要进行技术选型的实战过程:如下
5-1-1. 通过消息中间件实现DB的批量操作提升DB性能
KAFKA是批拉的消费
5-1-1-1. redis decr扣减和user+1操作要不要做事务?不需要,redis单线程,指令是原子的。
5-1-1-2. KAFKA:重复消费,丢数据,性能=》本质是offset在哪里维护,以什么粒度维护
1.分区的消费是批消费;每一条数据都有自己的offset;分区内key乱序的;同一key是有序的。
最可靠方式是取出一条处理一条提交一条性能最低,可靠性最高;另外一种方式批次处理完提交最后一条的offset
2.为了提高数据库批处理能力=》同样的key从kafka过来的数据归集起来(一个线程一个key处理业务逻辑效率提升)批量入库=>但是这样按key入库因为key无序如果key1,key2,key3在分区内存储key2事务失败了,offset维护哪个key的最后一条数据的offset到不清楚了=》所以要汇总数据把分区汇总到1个只发起一个事务提交到mysql(这一个事务同时处理3个key的数据入库)
总结:业务按key归集通过线程级调度处理;入库要归集到一个分区提交,最终选择所有key的第一个key的第一条或者最后key的最后一条offset提交从而实现强一致性的消费存储
只有明白上面offset的本质,才能驱动代码开发实现功能
AP可用CP一致
5-1-1-3. 双写一致性
读写分离数据库一致性;
5-1-1-4. ZK CP是不是能保证一致性?
设计:LRU,LFU,RDB,AOF导致出现访问延迟超时要做到AKF专业程度划分尽量隔离拆解service=>保证service不超限额的情况下性能发挥到极致
5-1-2. 在设计微服务的时候,我们一般会遵循以下4个原则:
- AKF拆分原则 参考 AKF介绍
- 前后端分离原则
- 无状态服务
- restful的通信风格
6. 高可用和可用性对架构的重要性
最终通过网络串联集群,通信,socket io 1.磁盘2 网络nio epoll netty, rpc v.s 微服务的通信无状态http协议restfull风格=》讲明白。
继续学redis zookeeper=>最终明白都能干什么=》CAP理论等方法论
7. CP VS AP,在CAP中到底有没有CP
P 分区容错能力?一定会发生网络不通的现象=》是取A还是取C
Doubble使用zk作为注册发现是CP
eurka:是AP;微服务下用AP让服务可用
大学生 发展路线:高起点 大厂 好学生 提升速度是最快的。
从边缘岗位向核心岗位突进~~!!进公司一定要进核心岗位。
边缘岗位,打工人,替代掉。
马士兵教育=》专业知识=》核心概念沟通
面试层级:算法,数据模式多线程JVM调优=》微服务,服务治理=》分布式锁,分布式事务,分布式ID,雪花算法;分库分表;mysql 主主;主从
主主:主1和主2互相同步数据会不会死循环?应该前面答的不够准确,才会问这个下套=>就是双写一致性(取决于哪种主主机制,如果机制不合适会死循环)