架构学习
系统分解多个系统业务模块好处?(微服务)
- 简单的系统更容易做到高性能,因为在单体应用中,提高了A业务效率有可能会降低其他的业务效率。
- 分解之后更容易看到系统的瓶颈所在,可以对单个业务进行扩展,有针对性的优化比如代码或者增加服务解决,其他服务可以保持不变。
- 分解的业务模块越多,网络的开销也就越大,调用的业务链路也长,排查问题越不方便。
1 | 今日心得 |
高性能 基本都是通过水平增加服务 冗余
高可用 必须要提到cap理论 ,zk的pasox zab协议是其中的了解的。另外还有脑裂的情况产生。zk是通过投票的算法在少数服从多数。
可扩展性
将变化封装到变化层
将不变封装到不稳定层
1.系统需要拆分出变化层和稳定层
2.需要设计变化层和稳定层之间的接口
以上基本就是复杂度的来源,另外成本,安全,规模 也同样是复杂度的来源之一。
架构设计原则
合适优于先进>演化优于一步到位>简单优于复杂
1 | 合适也就是适应当前需要是首位的,连当前需求都满足不了谈不到其他。 |
1 | 架构设计三原则; |
nginx 负载均衡 大约5w ,http 请求大约2w ,kafaka 号称百万,zk读写速度大约2w多
1 | 架构设计由需求所驱动,本质目的是为了解决软件系统的复杂性;为此,我们在进行架构设计时,需要以理解需求为前提,首要进行系统复杂性的分析。具体做法是: |
1 | 经过架构设计流程第 1 步——识别复杂度,确定了系统面临的主要复杂度问题,进而明确了设计方案的目标,就可以开展架构设计流程第 2 步——设计备选方案。架构设计备选方案的工作更多 的是从需求、团队、技术、资源等综合情况出发,对主流、成熟的架构模式进行选择、组合、调整、创新。 |
Kafka VS rocketMQ
1 | 1、数据可靠性 |
高性能数据库集群
1.读写分离
本质是将访问压力分散到集群中的多个节点,但是没有分散存储压力
一般是主从的概念,主负责写入,从负责读取数据。主复制数据到从 。
主从复制延迟
一些业务如果是写之后马上进行读取的操作,建议读写操作都保证分配主上进行避免。
关键业务的读写都在主进行操作,非关键性业务去从库进行读取
进行二次读取,从库读取失败后向主进行读取。
分配机制
程序代码封装
简单易用,灵活性高,但是如果主宕机发生故障,这个时候需要切换配置。
目前开源的实现方案中,淘宝的TDDL,它是一个通用数据访问层,所有功能封装在jar包中提供给业务代码调
用。其基本原理是一个基于集中式配置的 jdbc datasource实现,具有主备、读写分离、动态数据库配置等功能。
- 中间件封装
360开源自己的数据库中间件Atlas,基于mysql proxy 。
2.“分库分表”
既可以分散访问压力,又可以分散存储压力
高性能缓存
缓存穿透
一般指去缓存中查询数据,发现没有直接去存储系统去查询数据。
存储数据不存在
如果查询存储系统的数据没有找到,则直接设置一个默认值(可以是空值,也可以是具体的值)存到缓存中,这样第二次读取缓存时就会获取到默认。
缓存数据生成耗费大量时间或资源
例如电商的商品分页,我们只能缓存单页数据,一般设置的有效期为1天。
缓存雪崩
指的是当缓存失效后引起系统性能急剧下降的情况。
解决办法 更新锁机制和后台更新机制
更新锁
对缓存更新操作保证只有一个线程能够进行缓存更新,可以采用分布式锁进行处理,未获取到锁的线程要么等待重新读取缓存或者直接返回默认值。
缓存雪崩问题,我们采取了双key策略:要缓存的key过期时间是t,key1没有过期时间。每次缓存读取不到key时就返回key1的内容,然后触发一个事件。这个事件会同时更新key和key1。
后台更新
业务线程发现缓存失效后发送一条消息到消息队列,之后后台线程进行更新缓存,更新前判断缓存是否存在。后台更新还有一个好处就是缓存预热,在系统上线前可以更新一些数据到缓存中。
缓存热点
缓存热点的解决方案就是复制多份副本,将请求分散到多个缓存服务器上,缓存数据一样,通过缓存的key加编号进行区分,每次读取缓存随机读取副本。但是注意副本的过期时间千万不能一样,那样会导致缓存同时失效。
应用总结
1 | 一 数据库自身不是有缓存吗,标准答案是怎么回击他? |
单Reactor单进程的是Redis.
以Java的NIO为例,Selector是线程安全的,但是通过Selector.selectKeys() 返回的键的集合是非线程安全的,对selected keys的处理必须单线程处理或者采取同步措施进行保护.
Nginx采用的是多Reactor多进程,采用多Reactor多线程的实现有Memcache和Netty
Reactor与Proactor能不能这样打个比方:
1、假如我们去饭店点餐,饭店人很多,如果我们付了钱后站在收银台等着饭端上来我们才离开,这就成了同步阻塞了。
2、如果我们付了钱后给你一个号就可以离开,饭好了老板会叫号,你过来取。这就是Reactor模型。
3、如果我们付了钱后给我一个号就可以坐到坐位上该干啥干啥,饭好了老板会把饭端上来送给你。这就是Proactor模型了。
高性能负载均衡
负载均衡分类:
DNS负载,软负载(LVS,nginx + keeplive)和硬负载(F5,A10)
负载均衡的算法
轮询,不关注服务本身的状态,例如机器配置,负载高等。
加权轮询 一般针对机器性能,还是无法根据服务器的状态差异进行负载
负载最低优先
LVS4层的网络负载设备,可以“连接数”来判断服务器状态,连接数越大表明系统压力越大。
nginx 7层网络负载系统
性能最优类 优先分配给处理速度最快的服务器
Hash类
源地址hash 适用于存在事务和会话的业务。
当我们通过浏览器登录网上银行时,会生成一个会话信息,这个会话是临时
的,关闭浏览器后就失效。网上银行后台无须持久化会话信息,只需要在某台服务器上临时保存这个会话就可以了,但需要保证用户在会话存在期间,每次都能访问到同一个服务
器,这种业务场景就可以用源地址Hash来实现。
ID hash
将某个ID标识的业务分配到同一个服务器中进行梳理,这里的ID一般是临时性数据的id 例如session id
网络搜素 “微信红包高并发” 学习下怎么设计的?
CAP理论
ACID是数据库事务完整性的理论,CAP是分布式系统设计理论,BASE是CAP理论中AP方案的伸。
1 | 一个电商网站心模块有会员,订单,商品,支付,销管理等。 |
FMEA 故障模式与影响分析
failure mode and effects analysis)
架构设计领域,FMEA的具体分析方法是:
- 给出初始的架构设计图
- 假设架构中某个部件发生故障
- 分析此故障对系统功能造成的影响
- 根据分析结果,判断架构是否需要进行优化
FMEA分析表格
功能点
注册登录是功能点,redis缓存功能不能作为功能点。
故障模式
包括故障点和故障模式模式并不需要给出真正的原因
模式的描述要精确,多使用化描述,避免使用化的描述。例如,推荐使用“MySQL响应时间达到3”,而不是“MySQL响应慢”
故障影响
当发生故障模式中的故障时,功能点偶尔不可用,完全不可用,部分用户功能点不可用,功能点响应缓慢,功能点出错等。
4.严重程度
一分为“致命/高/中/低/无”五个档次
严重程度按照这个公式进行评:严重程度 = 功能点重要程度 × 影响范围 × 功能点受损程度
致命:超过70%用户无法。
高:超过30%的用户无法。
- 中:所有用户时间超过5。
- 低:10%的用户时间超过5。
- 中:所有用户都无法改资料。
- 低:20%的用户无法改头像
故障原因
比如导致mysql查询响应慢,可能是mysql bug 或者是没有索引。不同的故障原因检查手段不一样,如果是磁盘坏道导致的运维部门去查询,慢查询导致mysql慢,那么就在mysql添加慢查询日志即可。如果mysqlbug 那么升级mysql。
故障概率
硬件,开源系统,自研系统
风险程度
已有措施
系统现在是否提供了某些来应对,包括:测、容错、自恢复等。
规避措施
技术手段+ 管理手段
解决措施
解决措施位了能够解决问题而做的一些技术手段。
例如 为了解决拖库导致数据泄露,将数据库中敏感数据进行加密。
解决非法访问,增加白名单控制
后续规划
高可用存储架构 双机架构
对任何一个高可用存储方案,需要从以下几个方面去分析:
- 数据如何复制?
- 各个节点的职责是什么?
- 如何应对复制延迟?
如何应对复制中断?
常见的双机高可用架构:主备,主从、主备/主从切换和主主
主备:一般后台系统资源稍微有浪费。
主从:主负责写,从负责读操作,帮主人干活。缺点主从复制延迟大,容易产生数据不一致。
一般用于读和写比例1:10或者更多
主备切换:
主备间状态判断
状态传递的渠道:是相互间互相连接,还是第三方仲裁?
状态检测的内容:例如机器是否掉电、进程是否存在、响应是否缓慢
2.切换决策
切换时机
什么情况备机升级主?掉电?主进程不存在?还是主超时响应?还是一段时间内重复次数?
切换策略
原来主故障恢复后,继续主还是当备?
自动程度
完全自动还是半自动?
数据冲突解决
切换时候数据不一致怎么解决?
常见的架构
主备切换架构三种形式:互连式、中介式、模拟式
高可用存储架构:集群和分区
1 | 计算高可用架构,主要解决当单点发生后,原本发到节点的任务,任务如何分发给非节点,根据业务特点选择分发和重试机制即可,不存在数据一致性问题,只需要保证任务计 |
接口级故障的四种应对方法,分别是降级、容断、限流和排队
1 | 1.购面最大程度静态化,一用户开始前会尝试新面,查压力要比下单压力大很多 |
## 可扩展架构的基本思想和模式
基本思想:拆
拆分思路
- 面向流程拆分:将整个业务流程拆分几个阶段,每一个阶段为一部分。分层架构
- 面向服务拆分:将系统提供的服务拆分,每个服务做为一部分。soa,微服务
- 面向功能拆分:将系统提供的功能拆分,每个功能作为一部分。微内核
1 | 面向流程、面向服务、面向功能,这三个的名,面向服务和面向功能还可以,面向流程这个容易让人误解。 |
Mvp 逻辑分层架构 ,是自顶向下依赖的。
SOA的全称是Service Oriented Architecture,中文翻为“面向服务的架构”,一个特点的就是异构系统整合使用esb总线的思想。
微服务
soa和微服务的区别:
服务粒度
soa的服务粒度要粗一些,可能是一个系统做为一个服务。2⃣微服务会把一个系统拆分成多个服务。
服务通信
RESTFul 协议,rpc协议,无需esb那么重量级的实现,2⃣而微服务仅仅是消息传递
服务交付
微服务的架构理念要求“快速交付”,相应地要求取自动化测试、持续成、自动化部署等敏捷开发相关的最实践。如果没有这些基础能力支撑,微服务规模一变大(例如,超过20个微服务),整体就难以达到快速交付的要求。
应用场景
soa更加适合庞大、复杂的异构的企业级系统
微服务有哪些坑?
服务划分过细,服务间关系复杂,单个服务的复杂度下降,但是系统整个复杂度上升,n个服务的复杂度是n*(n-1)/2
服务数量太多,团队效率急剧下降,团队规模要具备,不然适得其反。
调用链太长,性能下降,调用链太长,问题定位困难
没有自动化支撑,无法快速交付,
没有自动化测试,每次测试需要测试大量接口,没有自动化监控,定位故障排查太难,没有 服务治理,微服务数量多后台管理混乱。
微服务最佳实践-方法篇
服务粒度
建议按照团队规模来划分,三个火枪手原则,3个能形成一个稳定的备份,三人能形成讨论,系统复杂度刚好达到每人都能全面了解系统。
基于业务逻辑拆分
比如电商系统,第一种是“商品” “交易” “用户” ,第二种是 商品、订单、支付、买家、卖家。
这个时候要看团队规模了,二种拆分方式都没任何问题。
基于可扩展拆分
将已经成熟和改动不大的服务拆分为稳定服务,变动的服务细化。这样也不会导致后续快速迭代影响到稳定服务。
基于可靠性拆分
系统中业务模块按照优先级排序,将可靠性要求高的核心服务和非核心隔离开,保证核心服务的高可用。
基于性能拆分
将性能要求高或者性能压力大的模块进行拆分,避免压力过大影响其他服务。例如 数据库,缓存。
基础设施
服务发现、服务路由、服务容错 : 这是最基本的微服务基础设施。
接口框架、API网关:接口框架提升内部服务的开放效率,api网关提供与外部服务对接
自动化部署、自动化测试、配置中心,提升测试和运维效率
服务监控、服务跟踪、服务安全,提升运维效率
微服务-基础设施篇
Drools规则引擎了解下?
对于会员模块,包括,个人设,个人订单,购物车,收等,这些模块保证AP,数据短时间不一致不影响使用。
订单模块的下单付库存操作是整个系统的心,我觉得CA都需要保证,在极情况下P是可以的。
商品模块的商品上下架和库存管理保证CP, 索功能因为本身就不是实时性非常高的模块,所以保证AP就可以了。
销是短时间的数据不一致,结果就是优信看不到,但是已有的优要保证可用,而且优可以提前计算,所以可以保证AP
现在大部分的电商网站对于支付这一块是立的系统,或者使用第三方的支付宝,微信。其实CAP是由第三方来保证的,支付系统是一个对CAP要求极高的系统,C是必须要保证的,AP中A相对