以尽可能少的代价解决实际问题
2019-12-23 10:10:14 2 举报
AI智能生成
后台开发知识框图--腾讯高级工程师--呕心之作
作者其他创作
大纲/内容
以尽可能少的代价,创造出尽可能好的工具,长久地解决实际问题
高可用:在用户预期的时间内返回系统设计下合理的结果
预防问题1:在预期时间内没有拿到结果
请数量突高,超过系统的处理能力
负载均衡
均衡策略
轮循均衡
权重轮循均衡
随机均衡
权重随机均衡
响应速度均衡
最少连接数均衡
处理能力均衡
此种均衡算法将把服务请求分配给内部中处理负荷(根据服务器CPU型号、CPU数量、内存大小及当前连接数、测速数据等换算而成)最轻的服务器
均衡架构
DNS负载均衡
举例,我们公司的 L5系统
反向代理负载均衡,如nginx
过载保护
轻重分离
按照高内聚低耦合的方式部署服务,使得局部的过载不扩散到整个系统
及早拒绝
容量预警,提前处理
建议容量管理按照70%预警,过载保护按照90%启动
柔性可用,服务降级
有损服务
CAP理论中,P(分区容错性)是基本,此外优先保证A(可用性),再追求C(一致性)
一致性的抉择
强一致性
实时的、同步的、读写互斥的数据一致性、完整性
弱一致性
异步,允许有不一致性窗口,特例为【最终一致性】
【有损】
腾讯特色,通过精心细分场景,选择牺牲一部分一致性、完整性;
需要注意的
程序的正确性、健壮性的要求还是刚性的,不能用【有损】来掩盖错误
小规模分布或不分布的业务确保可用、数据可靠、一致,即A & C兼顾;中等规模的分布系统优先考虑【BASE】;大规模分布式系统充分考虑【有损服务】;
运营监控和错误日志都很重要,积分和钱都很重要,要做必要的防盗、防刷安全机制
具体表现:优先保证核心数据、降低同步频次等
系统本身出现故障,使处理能力下降
架构设计上
大系统小做
一个子系统出了问题不会影响到其他功能的使用
将核心功能和非核心功能区分开来,优先保证核心功能的高可用
比如核心是读,且高频,而写低频,则可以读写分离
逻辑层:开发新需求导致系统本身故障
开发前准确理解需求
开发中完全实现需求
测试中充分验证需求完成度,
发布中合理的灰度策略+严守线上运营规范
将正确的发布提升到重中之重
灰度策略
按照特性(内容维度)
按照对象
白名单
Alpha用户
公司用户
。。。
科学的排期是保证
逻辑层:容灾
根本方法:冗余设计
无状态服务
集群模式
有状态服务
set模式,每个set管理一部分带状态的数据
异地部署
光纤断/机房停电
热备、冷备
服务器硬件故障死机
异地部署就近服务
网络环境恶劣(不同ISP互联)
DNS建设
黑客攻击
服务雪崩
负载均衡、流量拥塞控制、频率控制
程序core
自动拉起
SET化部署
集装箱模型
存储层:日志+备份
提升存储层的可用性,如高可用的分布式redis
如果服务很重要,比如app入口,则可以在逻辑层增加对用户结果的内存拷贝,这样哪怕redis全挂了也能服务
流水日志
方便撤销、回滚等
数据热备:增量同步+全量同步
数据冷备
存储机器故障、机房网络故障等导致数据丢失
在第三方服务时出现故障,导致系统处理能力下降
预防问题2:在预期时间内拿到了不合理的结果
- 请求内容有问题却没有处理;
内容长度限制、特殊字符等
敏感词过滤/检测,UGC 安平打击,限频策略(如验证码、次数限制)
- 系统数据一致性的问题;
分布式一致性
- 系统调用第三方服务出现问题导致返回数据不合理;
如果真的出了问题,希望能尽快恢复
立体监控
用户层
拨测
业务特性监控
应用层监控
服务特性监控
请求量、失败量、时延等
进程监控
系统层监控
cpu、内存、网卡、磁盘
网络丢包率、网络时延
全链路监控
能看到这个链路上每个节点的运行状况
fulllink
精准告警
出了问题马上就知道
告警内容一定要能准确反映出了什么问题,以及怎样解决该问题
告警方式有讲究,电话、微信、企业微信、短信、公众号。。。
日志
主要流程都要有完整的日志信息
管控好日志级别
高性能:以尽量低的成本满足达到尽可能高的性能
无锁化
零拷贝
内存映射
Linux内核2.4以后,支持带有DMA收集拷贝功能的传输,将内核页缓存中的数据直接打包发到网络上
池子化
内存池
线程池
连接池
对象池
并发化
请求并发
冗余请求
同时向后端服务发送多个同样的请求,谁响应快就是使用谁,其他的则丢弃
并发编程!!!
异步化
缓存
读操作
先从缓存读数据,如果没有命中,则去db读
异常:高访问量的key过期了
本地锁
每个进程内有锁,适用于进程数不太多的情况
分布式锁
软过期
快要到达过期时间了,先延长下该数据的过期时间,同时去后端请求更新数据
异常:缓存穿透,大量并发请求都是无效数据
缓存空对象
注意:多个不同的key同时过期了
对不同的缓存数据使用不同的失效时间
先从缓存读数据,如果没有命中,直接返回
写操作
双写模式
读数据时:读缓存未读到数据,从db读到了,再回写缓存
写数据时:更新缓存和db
先缓存再db
先更新缓存再更新数据库
注意:需要保证先更新缓存的请求一定先更新db
还有可能出现:并发的两个请求,一个请求更新缓存时,另一个请求在缓存没拿到数据然后用db数据更新了缓存,导致数据不一致
先删除缓存再更新数据库
先db再缓存
先更新数据库再更新缓存
注意:可能db更新成功但缓存更新失败,所以缓存需要设置过期时间
先更新数据库再删除缓存
在更新了db后异步更新缓存
按时间定时增量
按时间定时全量
按内容差异实时增量
推荐文章
http://km.oa.com/group/27110/articles/show/381299?kmref=related_post
分布
多进程
多线程
异步回调
协程
函数式编程
以数据流为模型的并行处理任务
易扩展:设计出能快速响应客户需求,易维护、低耦合、高复用的业务架构
总则
核心能力是:抽象能力
类是对对象的抽象
抽象类是对类的抽象
接口是对行为的抽象
开放-关闭原则
对修改关闭,对扩展开放
面对需求,对程序的改动是通过增加新的代码进行的,而不是更改已有的代码
什么时候应该应用抽象去重构?
在变化刚刚发生的时候,在可以预料到变化的时候
依赖倒转原则
子类不依赖父类,子类父类都依赖接口
里氏代换原则
任何基类可以出现的地方,一定可以用子类代替
单一职责原则
每个类,应该只负责一件事情
golang中的设计模式实现
描述:https://www.runoob.com/design-pattern/template-pattern.html
实现: https://github.com/senghoo/golang-design-pattern
创建型模式
核心:创建性模式抽象了实例化的过程,他们帮助一个系统独立与如何创建、组合和表示他的那些对象,因此在这些方面提供了很大的灵活性
工厂方法模式
定义一个用于创建对象的接口,让子类决定实例化哪个类;通常设计从工厂方法开始,当需要更大灵活性时,再考虑其他模式
抽象工厂模式
提供一个创建一系列或相互依赖对象的接口,而无需指定他们具体的类
建造者模式
构建对象的流程固定,每个子流程的细节频繁变化时使用,使得同样的构建过程可以创建不同的表示
原型模式
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象
单例模式
保证一个类仅有一个实例,并提供一个访问他的全局访问点
简单工厂模式
结构型模式
适配器模式
当旧接口不兼容时使用
桥接模式
将抽象部分和它的实现部分分离,是他们都可以独立变化
组合模式
将对象组合成树形结构以表示“部分-整体”的层次结构,使用户对单个对象和组合对象的使用具有一致性
装饰模式
被装饰的对象不变,用于装饰的对象频繁变化
外观模式
为子系统中的一组接口提供了一个一致的界面,比如MVC三层模型就是很好的应用
享元模式
比如依赖注入到统一的对象管理器,以保证每个对象都全局可复用
代理模式
为其他对象提供一种代理以控制对这个对象的访问
行为型模式1
观察者模式
发布-订阅模式
模版方法模式
解决代码重复问题:定义一个操作的算法骨架,而将一些步骤延迟到子类中,模版方法是的子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤
命令模式
将一个请求封装成一个对象
状态模式
封装状态和对应的行为,当状态改变时会发生对应行为
context上下文:保存当前状态、状态间转移的触发变量
state:多个状态的父类,定义状态的通用方法Handle()
ConcreteState:定义特定状态的Handle()方法,在该方法中实现逻辑:什么条件下转变,下一个状态是什么
职责链模式
行为型模式2
解释器模式
中介者模式
访问者模式
策略模式
当业务规则/算法经常变化时,可以用该模式对规则/算法做封装
用一个context包裹待实现的interface
对于每种算法,分别实现该interface
使用时,要用哪种策略就把哪种策略传入context
备忘录模式
捕获一个对象的内部状态,并在该对象之外保存对象,这样以后就可以将对象恢复到原先保存的状态
迭代器模式
将聚合对象的内部表示和对它的访问分离
迪米特法则
腾讯的海量服务之道
2个价值技术观
动态运营
敏捷迭代,所谓小步快跑,对用户的需求快速反应
产品需求中的“思想”比“做法”更重要
一个好想法,推迟2个月实现,可能已经不再适应当前用户的需求,也就一文不值了
好的架构不是没有BUG,而是BUG影响范围小、易发现、易修补
4个意识
干干净净
先扛住再优化
边重构边生活
7个技术手段
容灾
此种均衡算法将把服务请求分配给内部中处理负荷(根据服务器CPU型号、CPU数量、内存大小及当前连接数等换算而成)最轻的服务器
柔性可用
要尽可能正常接收请求,不能堵死
要尽可能成功返回关键数据
灰度
高可用:尽量保证系统在绝大部分情况下都是可用的
高可用性的定义
两大指标
MTBF
就是一个东西有多不可靠,多长时间坏一次
MTTR
一旦坏了,恢复服务的时间需要多长
可用性7级图表
http://km.oa.com/articles/show/265476?kmref=search&from_page=1&no=1
高可用性基本方案
提高冗余度,多实例运行,用资源换可用性
第一个细节:N + 2 应该是标配
第二个细节: 实例之间必须对等、独立
第三个细节:流量控制能力非常重要
变更管理,服务正常运行时出问题较少,往往是发布越频繁,坏的可能性就越大
第一点: 线下测试(Offline Test)
第二点:灰度发布
第三点:服务必须对回滚提供支持
请求输入
请求的内容异常
内容是否符合政策规定,是否涉黄、涉恐等
请求量超过预期
流量控制
优先保证核心数据、降低同步频次等
冗余设计
数据存储
监控告警
硬件、操作系统层面的监控
进程级别监控
业务级别监控
运营维护
性能瓶颈预警时,及时扩容
进程级别的检活和故障隔离
进程内模块级别的故障隔离
比如给模块设置开关,当出现问题时,可以关闭该模块
单个用户级别的故障隔离
收藏
0 条评论
下一页