8点前的请求保证什么时候处理完?
1、不优雅:每层打不打日志 如果打印日志这一层还在处理 2、优雅:前端请求 有超时时间 若超时时间5秒 则8点05秒的时候 超时 关机从上层往下层停止服务
不具备热开关
机器防火墙配置在某一个时间点只出不进
请求流程
高并发设计
缩短延迟 提高吞吐量 让系统处于合理状态
空间换时间
缓存数据库数据 因数据库比内存昂贵
时间换空间
网络传输 http通讯 gz压缩 解压会消耗cpu时间
变更次数少的数据
1、app页面上购物分类 一级 手机 二级电脑 变更少 不能每次登陆就拉取一次 通过版本号判断 哪些更新了 只有更新了才会下载 2、好友数 每次登陆的时候拉一次 变化不频繁 列表数据有一个版本号 server端和客户端都放一个 判断版本号有没有更新 若有则拉一次
哪些请求的耗时很大
1、一个服务集群若有4万QPS 对于占90%流量的前5接口进行优化 剩下的qps也不能忽略 若是慢查询 也不行 2、查看一个服务调用了多少rpc请求 若数据、算法等核心的同步化 非核心流程异步执行 拆分到单独模块去执行 比如消息队列 3、一个逻辑调用多个RPC接口 接口之间没有数据依赖 可以考虑并行调用
优化层次
代码层面
1、不要循环遍历rpc请求 而应该调用批量接口组装数据 2、避免生成过多无用对象 比如使用isDebugEnabled() 应直接log.debug() 3、ArrayList HashMap初始化容量设置是否合理 扩容代价很大 比如根据业务量实际情况直接初始化大小100万 虽然耗费点内存 但性能可以保证 4、rpc接口查询出来的数据复用 5、复制一份数据 直接修改 读多写少的情况 用CopyOnWriteArrayList 6、StringBuilder的容量在预分配的情况下 性能比String提升15倍左右 7、是否正确初始化数据 全局共享数据 饿汉式模式 即在用户访问前先初始化好
数据库
1、状态值 若长度在255以内 用unsigned tinyint ; ip使用int而非varchar 2、使用enum的场景 使用tinyint替换 因enum扩展需要改表 3、禁止select * 会耗费 io、内存、cpu、网络 4、分析查询场景建立合适的索引 分析字段的可选择性、索引长度、对长的varchar使用前缀索引 5、字段 Not Null 允许Null字段需要额外的存储空间去处理Null 并且很难优化 目的是降低服务器CPU使用率、IO流量、内存占用、网络消耗、降低响应时间
局部性原理
这是个二维数组 在内存中是一维数组
第一段 耗时 140ms
第二段 耗时 2700ms
越靠近CUP越快
1、速度越来越高 内存->L3->L2->L1多级缓存 2、在内存是一个大的一维数组 二维数组在内存中按行排列 先存放a[0]行 再放a[1]行 3、按行遍历:局部性原理 Cache Hit(缓存命中率高) 4、按列遍历:下一列和上一列的数组元素在内存中并不是连续的 很可能导致Cache Miss(缓存未命中) 5、CPU需要去内存载入数据 速度较CPU L1 Cache的速度降低了很多 (主存 100ns L1 Cache 0.5ns) 6、能用缓存就用缓存 无论是本地缓存还是分布式缓存 7、高频访问 时效性不高 适合缓存 比如 广告位 时效性很高 需要考虑缓存一致性问题 不适合用缓存 比较交易数据
代码逻辑要适应数据变化的场景
1、explain:SQL的执行计划 2、prossible_keys idx_addtime key null 表示没有索引 查询数据量一旦超过30% 不会走索引 全表扫描
报表查询
只计算增量数据和之前计算结果合并
并发和锁优化
基于CAS LockFee(读不需要加锁 写加锁)比mentex(读写都要加锁)性能要好
案例1-电商秒杀系统
数据分层次校验 上层尽量过滤无效请求 可以是不精确过滤 层层限流 最后一层做数据一致性校验 扣减库存
漏斗模式
1、静态数据 Html js css静态文件 放CDN 缓存到用户端(APP/浏览器) 2、非实时动态数据 缓存在靠近用户访问链路的位置(商品标题、商品描述、用户是否有秒杀资格、秒杀是否已结束) 3、实时数据:营销数据(红包、折扣)商品库存数 过滤掉用户
如何保证不超卖
DB事务保证一致性
热点数据缓存到调用链路更靠近用户的地方
1、内存存储最活跃的数据 2、L1缓存容量小负责抗最热点的数据 L2缓存考虑目标是容量 缓存更大范围数据 一般一般用户的timeline 高热点数据单独缓存 比如设置白名单 大V的用户数据单独缓存 3、feed 前3页 97% 前面几页数据作为热点数据缓存到L1 cache 4、业务逻辑层往往也会开一些缓存来存热点数据 比如大V的id
push模式
若push 那只推活跃用户 比如1万个用户 在业务逻辑层 每批100个用户需要推送 100个线程并行推 从策略上优化 先推活跃用户
如何区分活跃用户?
活跃用户列表 长度100万 用户已上线就在列表中写一下 下线删除
微博数据存储解决方案
1、Pika Key-Value 固化存储(持久化存储) 2、对象存储 Ceph\FastDFS
微信朋友圈是推拉结合
1、发现 有消息提醒 是推 2、点开朋友圈是拉
微博最新数据展示逻辑
比如你有500个好友 拿每个人的100个数据 共5万条数据 在业务逻辑层按照timeline倒序排列
websocket和长轮询本质上没区别
websocket底层也是长轮询 web上用不了tcp协议 websocket在http基础上封装了长轮询
后记
接下来会继续分享 服务网格ServiceMesh相关的实践 觉着有用的话 点个再看哈😄