一、MySQL主从复制,完成每秒30万订单
(一)数据库方面优化
1. 添加索引
2. 尽量多使用数值型
3. 尽量多考虑使用定长而非变长
4. exist和in
5. in和not in
6. like模糊查询(不使用 %string%),查询的字段创建覆盖索引
(二)架构方面优化
1. 负载均衡
2. 主从复制(千万级别:MySQL主从+Redis队列)
3. 读写分离
二、ActiveMQ请求分流,亿级高并发削峰利器
(一)思路:
1、将请求缓存至ActiveMQ队列中
2、参考之前编写的微信IM程序中的redis缓存任务管理器
(二)本地模拟并发:CountDownLatch,发令枪
三、脱离单体应用的必经之路
(一)划重点:
1、session与cookie的原理:
因为http是无状态协议,客户端访问服务端时,服务器会产生session,并保存在内存中,返回客户端该session,被保存在客户端的cookie中,下次再访问服务器的时候,会要求携带cookie,会找到服务器中对应的用户会话
2、解决nginx中反复登录问题:
1. session黏滞:可以在nginx中配置ip_hash算法,相同的请求只会打到同一台服务器上
2. session复制:使用tomcat的session同步功能(配置成tomcat集群)
3. session共享:使用redis。springboot中有专门注解,三步配置即可
(二)思路:
1、应用:
虚拟IP(keepalive)==》Nginx主从==》tomcat集群==》数据库
2、数据库:
虚拟IP(keepalive)==》LVS主从==》MySQL主从
四、OTA架构师带你搭建高并发秒杀系统解决方案
(一)OTA:在线旅游社
(二)秒杀技术特点:
1、读多写少
1. 缓存
2、高并发
1. 限流(nginx直接可以配置)
a. 令牌桶:比如每秒10个请求,令牌按照每秒5个存储,最多放20个。那么系统只会允许持续每秒处理5个请求,或等20个令牌满了后,一次性处理20个请求,确保系统稳定可靠
b. 漏桶:所有请求(每秒有10个请求)都经过一个桶,但桶里每秒只处理一个请求,桶里溢出,则表示请求丢失
2. 负载均衡
3. 缓存
4. 异步
5. 队列
3、资源冲突
1. 原子操作
a. 数据库锁:乐观锁(数据增加版本标识,每次修改+1)、悲观锁(给表上锁,独占)========》在高并发下,悲观锁比乐观锁效率高
b. 分布式锁(redis、zk),以redis分布式锁为例:
i. 加锁:setnx(set if not exists)命令,设置锁的持有人和锁的有效期
ii. 使用lua脚本,保证解锁操作的原子性(多条命令汇总为一条,确保了绝对原子性)
c. 其它原子操作,redis decr:因为redis是单进程单线程的,所以是安全的,所以可以使用redis的increment计数功能,保证数据原子性
2.异步
(三)划重点
1、秒杀核心思路:
层层限流
2、接口幂等:
指无论进行多少次相同接口调用,获取的结果是一样的
五、玩转SpringBoot开启微服务之旅
1. 起步依赖机制
2. 自动配置
3. SpringBoot CLI
4. Actuato
六、大厂开发人员必备技能——海量数据存储解决方案
(一)划重点
1. 大厂对MySQL大表军规:单表超过1000万必须优化,否则后果自负
2. 通常对MySQL进行分库分表
(二)Sharding-JDBC的概念与应用
1. 单维度分库分表:使用主键(利用User_ID)保存查询策略
2. 带条件的查询:分成多条SQL执行。例如:* from、id>1、id in (1,2,3)
3. 多维度分库分表
七、通往架构师之路:你必须要掌握的JVM特性
(一)类加载器
编译器————将java编译成字节码————类加载器将java字节码加载到java运行时内存区域中去(方法区)————执行器————本地方法接口————本地方法库
(二)Java堆、Java栈、方法区————运行时数据区
1、Java堆(线程共享)
主要存放java实例化对象,jvm内存分配最大的区域。新生代与老年代:新生代分为edn(使用一次)、s0(多次)、s1(多次),垃圾回收机制根据标记算法,每使用一次会加1,根据实例化对象使用多少次,会先进行edn区、再进入s0、s1区,最后进入老年代区
2、Java栈(线程私有)
先进后出。主要存放局部变量表、操作数栈(操作的步骤)、动态连接/方法返回地址
3、方法区(线程共享)
存放类元数据信息、方法、常量池
(三)GC垃圾回收机制
垃圾回收机制通常回收新年代中的数据
八、实现订单自动取消(延迟任务,倒计时)方案
(一)划重点
1、定时任务
每过一段时间要重复一件事情
2、延迟任务
触发一件事情后,再等待一段时间,做另一件事情
3、工具类
countDownLatch,使一个线程等待其他线程各自执行完毕后再执行,通常用于模拟多线程并发
(二)延迟任务实现方案
1、数据库轮询
1. 原理:小型项目的通用方式,通过一个线程去扫描数据库或数据库定时任务,通过订单时间判断超时的订单,进行更新状态或其它操作
2. 优点:实现简单、无技术难点、异常恢复、支持分布式/集群环境
3. 缺点:影响数据库性能、时效性差、效率低
2、JDK延迟队列——DelayQueue
1. 原理:DelayQueue是一个无界阻塞队列,只有延迟期满时才能从中获取元素,放入delayQueue中的对象需要实现Delay接口
a. poll():获取并移除队列的超时元素,没有则返回空
b. take():获取并移除队列的超时元素,如果没有则wait当前线程,直到有元素满足超时条件,返回结果。使用该方式
2. 优点:实现简单、性能较好
3. 缺点:异常恢复困难、分布式/集群实现困难
3、redis——之前嘉配tigase中离线消息方案
1. 原理:Redis sortedSet集合(sorted set也叫zset)是一个有序集合,每个元素(member)都关联了一个score,可以通过score排序获取集合中的值
实现方式:将订单超时时间戳与订单号分别设置为score与member,系统扫描第一个元素判断是否超时
2. 优点:解耦、异常恢复、扩展性强、支持分布式/集群环境
3. 缺点:增加Redis维护、占用宽带
4、RabbitMQ TTL+DLX——任务交换器,同之前的tigase
1. 原理:RabbitMQ可以设置消息过期时间(TTL),当消息过期后可以将该消息投递到队列上设置的死信交换器(DLX)上,再次投递到死信消息队列中,重新消费
2. 优点:解耦、异常恢复、扩展性强、支持分布式/集群环境
3. 缺点:增加RabbitMQ维护、占用宽带
九、资深架构师带你手撕Spring MVC核心源码
(一)手写注解及DispacherServlet——反射
1、包扫描
2、类实例化
3、依赖注入
4、映射处理
(二)Spring MVC原理
1. 首先是用户发送请求,比如在浏览器中输入http://localhost:8080/SpringTest/login
2. 用户的请求发送到了DispacherServlet,是一个servlet的实现。主要用来接收用户请求,然后响应结果,相当于一个转发器
3. 经过DispatcherServlet过滤后URL后,就进入了HandleMapping也就是映射处理器,主要是根据URL来匹配我们的处理器(或叫控制器)
4. 通过映射处理器就找到了我们需要处理用户请求的控制器也就是Handler
5. 经过适配器调用控制器的方法后,就会想前端控制器返回一个ModelView,包含我们需要信息的pojo对象和视图信息
6. 前端控制器开始解析视图信息,通过视图解析器(View Resolver),进行视图解析,根据逻辑视图名解析成真正的视图(view)
7. 解析完视图信息后,就把modelview中的model信息传递到我们的view界面上,整个流程就处理完毕
十、玩转大型互联网企业DevOps利器-Docker
1、镜像
只读,docker原理是使用多个只读层构成UnionFS(联合文件系统)。maven中使用镜像插件,可以将工程打包成镜像
2、仓库
打包镜像的同时,使用maven命令将镜像上传至私有仓库(生产环境)。也有很多公有仓库
3、容器
启动即可运行镜像,相当于轻量级的虚拟机
十一、三高系统高可用高并发高性能系统的必备技术 ——缓存
(一)思路
使用Spring cache注解。spring可按其内部缓存组件顺序,自动匹配服务器加载的缓存
十二、双11电商网站应对千万级流量技术内幕
(一)单体架构(QPS:50-100)
(二)中小企业架构(QPS:500-800)
(三)阿里、百度、京东等大型企业架构(QPS:1000w)
1、核心:nginx
nginx反向代理
nginx动静分享
nginx静态模板(Lua)
nginx缓存
nginx调用服务(调用java后台微服务)
十三、手写Redis连接池
之前开发的微信消息处理的连接池
十四、一个合格程序员必须懂的开放API接口安全处理
原理:非对称加密,公钥+密钥,时间戳,随机数。参考买卖聊中的支付接口、微信消息处理中的对外开放接口、迎风聚智提供给外包的获取token对外接口等
十五、支付宝520会员日20亿积分红包背后的保障 技术——限流
(一)限流方案
1、手动实现
如页面中同一功能使用多个按钮(普通下载、快速下载)分流用户请求
2、AtomicInteger
3、MQ
原理,通过异步方式,消费者根据自身性能情况,主动获取MQ队列中的请求,进行调用,而不是被动调用
4、容器限流
修改容器(如tomcat)中相关参数,指定请求访问数据的大小
5、spring cloud的hystrix限流
线程隔离 vs 信号量隔离
(二)spring cloud原理
1、Eureka
类似zookeeper
2、Feign
解决写大量httpclient的代码,方便服务间相互调用
3、Ribbon
服务间发起请求的时候,基于Ribbon做负载均衡,从一个服务的多台机器中选择一台
4、Hystrix
有限流、熔断、降级等功能,防止服务雪崩
5、zuul
如果前端、移动端要调用后端系统,统一从Zuul网关进入,由Zuul网关转发请求给对应的服务
(三)spring cloud通俗理解————改造spring boot
1. 第一次进化:加入zuul网关
2. 第二次进化:服务注册和发现,加入eureka
3. 简化我们的配置
(四)千万级并发系统架构
十六、ZooKeeper从案例场景到理论最佳实践
ZooKeeper是一个高可用的分布式数据管理与系统协调框架。可以:
1. 配置中心
2. 命名服务
3. 分布式协调服务/通知
4. Master选举
5. 分布式锁
十七、架构师进阶知识:想弄清楚微服务先搞懂RPC
(一)RPC调用流程
(二)什么是RPC及HTTP协议 VS TCP(企业更倾向于该协议)协议
(三)RPC三大角色及底层原理
(四)RPC(远程过程调用)的解决方案
1. corba
2. RMI
3. WebService
4. RestFul
(五)主流RPC框架
(六)阿里DUBBO(支持tpc、http等多种协议)
十八、高并发场景的订单号、ID生成策略
(一)解决方案
1. UUID
2. 数据库自增
3. Snowflake
4. Redis
(二)解决方案优缺点
十九、BIO、NIO、AIO区别和应用场景
1. BIO:适合连接数并不多,只有最多几百个连接的普通应用,能比较好的进行工作,但如果连接数量剧增,这种实现方式就无法很好的工作了,对于并发量要求较高的企业,这种方案,肯定是不可取的。————同步阻塞IO
2. NIO:会等数据准备好后,再交由应用进行处理,数据的读取/写入过程依然在应用线程中完成,只是将等待的时间剥离到单独的线程中去,节省了数据准备时间,因为多路复用机制,Selector会得到复用,对于那些读写过程时间长的,NIO就不太适合。————同步非阻塞IO
3. AIO:读完(内核内存拷贝到用户内存)了系统再通知应用,使用回调函数,进行业务处理,AIO能够胜任那些重量级,读写过程长的任务
二十、微服务的性能优化
1.使用JMeter进行接口压测
2. 使用JProfiler对压测过程中进行记录,分析接口耗时,内存等
3. 通过jvm命令,分析内存使用
4. 使用阿里巴巴Arthas,对程序进行监控
5. 使用sleuth来分析整条链路
二十一、快速开发利器
1.OnlineMooc
能做什么:后台管理使用TyAdmin(现代化的Xadmin替代品)生成管理后台前后端,并自动对接
github:https://github.com/mtianyan/OnlineMooc
2.APIJSON
能做什么:是一种专为API而生的 JSON网络传输协议 以及 基于这套协议实现的ORM库
github:https://github.com/Tencent/APIJSON