目录
单点登录
1.流程运行:
(1) 用户第一次登录时,将会话信息(用户Id和用户信息),比如以用户Id为Key,写入分布式Session;
(2) 用户再次登录时,获取分布式Session,是否有会话信息,如果没有则调到登录页;
(3) 一般采用Cache中间件实现,建议使用Redis,因此它有持久化功能,方便分布式Session宕机后,可以从持久化存储中加载会话信息;
(4) 存入会话时,可以设置会话保持的时间,比如15分钟,超过后自动超时;
结合Cache中间件,实现的分布式Session,可以很好的模拟Session会话。
我们在浏览器(Browser)中访问一个应用,这个应用需要登录,我们填写完用户名和密码后,完成登录认证。这时,我们在这个用户的session中标记登录状态为yes(已登录),同时在浏览器(Browser)中写入Cookie,这个Cookie是这个用户的唯一标识。下次我们再访问这个应用的时候,请求中会带上这个Cookie,服务端会根据这个Cookie找到对应的session,通过session来判断这个用户是否登录。如果不做特殊配置,这个Cookie的名字叫做jsessionid,值在服务端(server)是唯一的。
2.分布式session方式实现单点登录
单点登录SSO(Single Sign On)说得简单点就是在一个多系统共存的环境下,用户在一处登录后,就不用在其他系统中登录,也就是用户的一次登录能得到其他所有系统的信任。
所以,单点登录要解决的就是,用户只需要登录一次就可以访问所有相互信任的应用系统。
秒杀设计原则
1.尽量将请求拦截在系统上游 传统秒杀系统之所以挂,请求都压倒了后端数据层,数据读写锁冲突严重,并发高响应慢,几乎所有请求都超时,流量虽大,下单成功的有效流量甚小
2.读多写少的常用多使用缓存 这是一个典型的读多写少的应用场景【一趟火车其实只有2000张票,200w个人来买,最多2000个人下单成功,其他人都是查询库存,写比例只有0.1%,读比例占99.9%】,非常适合使用缓存。
秒杀流程
- 登录进入商品列表页面,静态资源缓存
- 点击进入商品详情页面,静态资源缓存,Ajax获取验证码等动态信息
- 点击秒杀, 将验证码结果和商品ID传给后端,如果结果正确。动态生成随机串UUID,结合用户ID和商品ID存入redis,并将path传给前端。前端获取path后,再根据path地址调用秒杀服务
- 服务端获取请求的path参数,去查缓存是否在
- 如果存在,并且Redis还有库存,预减redis库存,看是否已经生成订单,没有的话就将请求入消息队列
- 从消息队列中取消息:获取商品ID和用户ID,判断数据库库存,然后下单
- 下单:减库存,生成订单
- 前端轮询订单生成结果。50ms继续轮询或者秒杀是否成功和失败
- 把商品存到Redis中(定时把数据库中的数据查询到Redis中)
- 进入秒杀列表页, 通过negix把商品展示到商品列表页,用户访问商品,通过negix把商品展示到页面(商品列表页和商品详细页面的数据都是从Redis中获取的),用户进行下单,下单之前先检查是否有库存(用negix读取redis中商品的库存)
- 有库存的话先验证客户是否登录,用授权认证登录,进行抢单,使用Redis队列存储用户抢单信息和ID信息存入队列,避免服务器处理多请求(削峰)
- 提示用户正在排队,用多线程进行下单,读取队列中的信息进行下单
- 下单库存递减(redis中的库存,检查相关信息,检查通过了才下单),
- 添加下单信息,下单成功更新用户排队信息,查询排队信息,已下单
- 进行支付流程.<每次下单会发送延时队列,包含订单ID,用户ID,商品ID发送给RubbitMQ延时30分钟,30分钟后监听器读取,检查redis中
- 用户的订单信息,有信息,没支付;;没有信息,已支付关闭支付记录,清理订单信息,回滚数据>
RabbitMQ
1.MQ是什么
MQ全称为Message Queue,消息队列是应用程序和应用程序之间的通信方法。
2.为什么使用MQ--(面试!)
在项目中,可将一些无需即时返回且耗时的操作提取出来,进行异步处理,而这种异步处理的方式大大的节省了服务器的请求响应时间,从而提高了系统的吞吐量。
3.MQ优势
- 削峰填谷:提升系统的可维护性
- 异步处理 提升用户体验和系统吞吐量(单位时间内处理请求的数目)
- 应用解耦 提升容错性和可维护性
MQ劣势
- 系统的可用性降低
- 系统的复杂度提高
- 一致性问题
4.MQ结构:
rabbit,active,rocketmq,kafka
MQ工作模式
简单模式,
work模式,
Publish/Subscribe发布与订阅模式,
Routing路由模式,
Topics主题模式,
RPC远程调用模式
5.RabbitMQ特点:
- 使得简单,功能强大。
- 基于AMQP协议。 跨语言 c node.js->mq->java python
- 社区活跃,文档完善。
- 高并发性能好,这主要得益于Erlang语言。 c 底层语言,性能强。java 好开发。构建一个web .
- Spring Boot默认已集成RabbitMQ
6.RabbitMq重复消费
RabbitMQ解决消息幂等性问题--重复消费问题
1:如果消费端 程序业务逻辑出现异常消息会消费成功吗?
不会成功,默认一直重试。
rabbitmq 默认情况下 如果消费者程序出现异常的情况下,会自动实现补偿机制(重试机制)是 队列服务器 发送补偿请求,不是生产者
2:充实实现原理:
@RabbitListener 底层 使用Aop进行拦截,如果程序没有抛出异常,自动提交事务
如果Aop使用异常通知拦截 获取异常信息的话,自动实现补偿机制 ,该消息会缓存到rabbitmq服务器端进行存放,一直重试到不抛异常为为止。
修改重试机制策略 ,默认是一直重试
消费者如果保证消息幂等性,不被重复消费(解决方案)
产生原因:网络延迟传输中,会造成进行MQ重试中,在重试过程中,可能会造成重复消费。
解决办法:
使用全局MessageID判断消费方使用同一个,解决幂等性。
生产端设置消息ID
消费端判断消息ID