架构设计指南 如何成为架构师
Posted 抓手
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了架构设计指南 如何成为架构师相关的知识,希望对你有一定的参考价值。
一:技术选型
创业初期架构方案怎么选型?
(1)要考虑业务的需求与特点,初期往往“快速实现”更重要,此时系统的特点是请求量小,数据量小,服务器资源也非常有限;
(2)这个阶段最重要的选型依据是:合伙人熟悉什么技术栈,使用什么技术栈;
(3)第一版往往采用ALL in one架构;
(4)这个阶段研发主要在写CURD业务逻辑,引入DAO和ORM能极大提高工程效率;
画外音:什么是ALL in one架构?。
如果硬要问我,会选择什么技术栈,我会二选一:
或者
Java体系(Linux,Tomcat,MySQL,Java)
使用开源框架组件还是自研?
我的观点是:
(1)早期不建议自研;
(2)随着规模的扩大,要控制技术栈;
(3)要浅浅的封装一层;
(4)适当的时候,造一些契合业务的轮子;
画外音:为什么要控制技术栈?为什么要封装一层?
什么情况下要进行容量评估?
至少在三种情况下,要进行容量评估:
(1)新系统上线;
(2)临时运营活动;
(3)系统容量有质变性增长;
系统层面,要评估哪些重要指标?
主要评估网络带宽、CPU、内存容量、磁盘容量、磁盘IO等资源指标,系统层面主要看吞吐量指标。
画外音:容量设计五大步骤是啥?
创业初期,系统层面存在瓶颈的时候,优化原则是什么?
(1)最低成本,初期最大的成本是时间成本;
(2)用“钱”和“资源”快速解决系统问题,而不是过早的系统重构;
(3)将ALL in one架构升级为伪分布式架构,是此阶段的最佳实践;
伪分布式的核心是什么?
伪分布式的本质是单机变多机,但又不是真正的高可用,其核心是垂直拆分:
(1)业务垂直拆分;
(2)代码垂直拆分;
(3)数据库垂直拆分;
(4)研发团队垂直拆分;
画外音:伪分布式的优化细节是啥?
二:接入层架构
如何解决接入层的扩展性问题?
引入反向代理。
最常见的反向代理是什么?
引入反向代理之后,要解决什么新的问题?
(1)集群负载均衡;
(2)反向代理高可用;
画外音:有哪些常见的负载均衡方法?如何保证反向代理高可用?
站点流量从小到大,接入层架构如何演进?
整体可以分为五个阶段:
(1)有反向代理技术之前,单体架构要解决扩展性问题,可使用DNS轮询架构;
(2)有反向代理技术之后,初期可以使用反向代理解决扩展性问题;
(3)然后,需要升级为高可用反向代理架构;
(4)多级反向代理,引入LVS&F5进一步扩充性能;
(5)想要无限性能,必须用DNS轮询架构;
画外音:每个阶段的逻辑与细节到底是怎么样的?
Session,是接入层架构非常关注的问题,如何保证Session一致性?
通常有四种方案:
(1)客户端层解决;
(2)反向代理层解决;
(3)web-server层解决;
(4)后端服务层解决
画外音:每种方案细节又是怎么样的?
CDN,是接入层不得不谈的问题,CDN架构有哪些要了解?
引入CDN架构,至少要考虑这五个问题:
(1)什么样的资源适合静态加速;
(2)CDN的架构是怎么样的;
(3)CDN是怎么实现“就近访问的”;
(4)如何保证源站和镜像站数据的一致性;
(5)资源更新,是推还是拉?
画外音:学CDN,千万不要去百度“斯塔尔报告”。
TCP接入,架构上要考虑哪些问题?
至少要考虑这四个架构设计点:
(1)TCP如何快速实现接入;
(2)TCP如何快速实现扩展,以及高可用;
(3)TCP如何快速实现负载均衡;
(4)TCP如何保证扩展性与耦合性的平衡;
画外音:有没有综合方案,系统性解决负载均衡 + 高可用 + 可扩展 + 解耦合等一系列问题?
三:急速性能优化
在互联网公司发展早期,为了产品快速迭代,最常使用的架构是什么?
ALL in one架构。
如果此时业务发展很快,系统成了瓶颈,架构优化的方向是什么?
用最短时间,以对代码最小的冲击,极速扩充系统性能。
早期如何快速的扩充系统性能?
使用三大分离的性能优化方法。
早期系统容易“白屏”,如何快速的提升用户体验,消除白屏?
动静分离。
什么是动静分离?
动静分离,是“静态页面与动态页面,分开不同的系统访问”的架构设计方法。
画外音:如何来实施?分别对应怎样的技术点?
如果静态页面访问这么快,动态页面访问这么慢,能否将“原本需要动态生成的页面,提前生成静态页面”?
可以,这是“页面静态化”技术,能够100倍提升访问速度。
画外音:这个技术适用怎么样的业务场景?
早期系统的主要瓶颈,最容易出现在哪里?
数据库读性能扛不住。
如何快速提升数据库读性能?
读写分离,使用数据库分组架构,一主多从,主从同步,读写分离。
画外音:读写分离,水平切分都是使用数据库集群,有什么异同?
后台运营系统,复杂的SQL语句对数据库性能影响较大,怎么办?
前台与后台分离。
画外音:前后端分离,前台后台分离,是一回事么?如何快速实施前台与后台分离?
四:微服务架构
系统初期,哪类技术栈最为流行?
(1)PHP语言的LAMP栈;;
(2)Java语言的LiToMyJa栈;
业务快速发展,三层架构可能存在哪些问题?
(1)代码频繁拷贝;
(2)底层复杂性扩散;
(3)公共库耦合;
(4)SQL质量不可控,数据库性能急剧下降;
(5)数据库耦合,无法实现增加实例扩容;
可以通过什么架构方案解决上述1-5问题?
微服务架构。
如果要落地微服务架构,服务粒度可以如何选择?
常见的有以下四种粒度:
(1)统一服务层;
(2)按业务划分服务;
(3)按库划分服务;
(4)按接口划分服务(需要轻量级进程等语言层面支持);
微服务架构,可能带来什么问题?
可能带来的潜在问题有:
(1)系统复杂性上升;
(2)层次间依赖关系变得复杂;
(3)运维,部署更麻烦;
(4)监控变得更复杂;
(5)定位问题更麻烦;
不要以为,引入一个RPC框架就是“微服务架构”了,微服务架构要解决很多问题。
微服务架构要解决哪些问题?
至少要解决高可用,无限性能扩展,负载均衡等众多架构基础问题。
如何解决高可用的问题?
每一层解决高可用问题的方案不一样,涉及虚IP,反向代理,集群,连接池,数据库分组,缓存冗余,故障转移等诸多技术。
画外音:高可用的方法论是什么?
如何解决无限性能扩展的问题?
每一层解决高可用问题的方案不一样,涉及Scale up,Scale out,DNS轮询,反向代理,连接池,水平切分等诸多技术。
画外音:无限性能的方法论是什么?
如何解决负载均衡的问题?
负载均衡分为两类:
(1)同构均匀分摊;
(2)异构按能力分摊;
异构服务器负载均衡,常见的这么几种方案:
(1)静态权重法;
(2)动态权重法,涉及“保险丝”算法;
同时,动态权重法还可以实现服务器的过载保护。
画外音:什么是“保险丝”算法?什么是过载保护?
哪一个组件,和高可用,无限性能扩展,负载均衡相关?
连接池。
连接池的核心是什么?
两个核心数据结构:连接数组,锁数据;
三个核心接口:初始化,拿出连接,放回连接;
画外音:如何快速掌握连接池内核?
五:数据库架构
工程上,数据库要设计一些什么?
(1)根据“业务模式”设计表结构;
(2)根据“访问模式”设计索引结构;
架构上,数据库还必须考虑什么?
(1)读性能提升;
(2)高可用;
(3)一致性保障;
(4)扩展性;
(5)垂直拆分;
画外音:我C,我居然从来没考虑过这些问题。
提升系统读取速度,有哪几种常见方法?
(1)建立索引;
(2)增加从库;
(3)增加缓存;
一个数据库分组集群,主从同步,读写分离,能不能在主库和从库建立不同的索引?
可以,例如:
(1)主库只响应写请求,不建立索引;
(2)线上从库,建立线上访问索引;
(3)后台从库,建立后台访问索引;
如何保证数据库的高可用?
核心思想是:冗余+故障自动转移:
(1)写库高可用,冗余写库;
(2)读库高可用,冗余读库;
数据冗余会带来什么副作用?
会引发一致性问题:
(1)两个写库数据可能不一致;
(2)主库和从库数据可能不一致;
写库高可用,两个写库相互同步数据,自增ID可能冲突导致数据不一致,有什么优化方案?
(1)为每个写库指定不同的初始值,相同的增长步长;
(2)生成不同的ID;
(3)一个写库提供服务,一个写库作为高可用影子主;
主从延时,有什么优化方案?
(1)业务容忍;
(2)强制读主;
(3)在从库有可能读到旧数据时,选择性读主(非常帅气的方案);
底层表结构变更,水平扩展分库个数发生变化,底层存储引擎升级,数据库如何平滑过度?
如果业务能够接受,可以停服扩展。
否则,可以使用以下三种方法:
(1)追日志平滑扩容法,平滑过度;
(2)双写平滑扩容法,平滑过度;
(3)秒级平滑扩容法(非常帅气的方案);
画外音:如何在秒级,实现读写实例加倍?容量加倍?
数据库垂直拆分的最佳实践是什么?
数据库垂直拆分,尽量把:
(1)长度短;
(2)访问频率高;
(3)经常一起访问;
的数据放在主表里。
六:缓存架构
工程上,缓存一般有几种使用方式?
(1)进程内缓存;
(2)进程外缓存,也就是缓存服务;
如果有多个服务使用进程内缓存,如何保证一致性?
常见的有三种方法:
(1)服务节点同步通知;
(2)MQ异步通知;
(3)牺牲少量一致性,定期后端更新;
绝大部分情况,还是应该使用缓存服务,缓存的使用,有什么注意点?
以下几点,应该要注意:
(1)服务与服务之间不要通过缓存传递数据;
(2)如果缓存挂掉,可能导致雪崩,此时要做高可用缓存,或者水平切分;
(3)调用方不宜再单独使用缓存存储服务底层的数据,容易出现数据不一致,以及反向依赖;
(4)不同服务,缓存实例要做垂直拆分,不宜共用缓存;
互联网缓存操作细节,最佳实践是什么?
Cache Aside Pattern。
Cache Aside Pattern的细节是什么?
它分为读缓存最佳实践,以及写缓存最佳实践。
读缓存最佳实践是:先读缓存,命中则返回;未命中则读数据库,然后设置缓存。
写缓存最佳实践是:
(1)淘汰缓存,而不是修改缓存;
(2)先操作数据库,再操作缓存;
画外音:为什么呢?
缓存的本质是“冗余了数据库中的数据”,可能存在什么问题?
缓存与数据库数据不一致。
什么场景下容易出现不一致?
写后立即读业务场景。
画外音:为什么呢?
出现不一致时,优化思路是什么?
及时把缓存中的脏数据淘汰掉。
具体要怎么淘汰,保证缓存与数据库中数据的一致性呢?
(1)服务同步二次淘汰法;
(2)服务异步二次淘汰法;
(3)线下异步二次淘汰法;
画外音:二次淘汰法,是很常见的一种实践。
目前缓存服务最常用的是什么?
Redis和memcache。
什么时候选择使用Redis?
以下场景优先使用Redis:
(1)需要支持复杂数据结构;
(2)需要支持持久化;
(3)需要天然高可用;
(4)value存储内容比较大;
如果只是纯KV,可以使用memcache。
画外音:纯KV场景,为什么memcache会更快呢?
七:架构解耦
配置文件,是互联网架构中不可缺少的一环。依赖(调用)某个下游服务集群,将下游集群信息放在自身配置文件里是一种惯用做法,该做法可能导致什么问题?
可能导致上下游严重耦合:
(1)上游痛:扩容的是下游,改配置重启的是上游;
画外音:架构设计中典型的反向依赖。
(2)下游痛:不知道谁依赖于自己,难以实施服务治理,按调用方限流;
为了解决上述问题,常见的配置架构演进是怎么样的?
(1)“配置私藏”架构;
(2)“全局配置文件”架构;
(3)“配置中心”架构;
除了配置中心,消息总线MQ也是互联网架构中的常见解耦利器。
一般来说,什么时候不使用MQ?
上游实时关注执行结果时,通常不使用MQ,而使用RPC调用。
什么情况下,可以使用MQ来解耦?
以下四种情况,可以使用MQ来解耦:
(1)数据驱动的任务依赖;
(2)上游不关心执行结果;
(3)上游关注结果,但执行时间很长,例如跨公网调用第三方服务;
(4)削峰填谷,流量控制,保护下游;
上下游IP耦合,可以如何解耦?
使用内网域名来代替内网IP。
多个模块,因为公共库而耦合在一起,可以如何解耦?
粗暴方案:代码各自拷贝一份(不太推荐)。
优化方案:
(1)垂直拆分,个性业务代码“上浮”;
(2)服务化,共性业务代码“下沉”;
多个模块,因为数据库而耦合在一起,可以如何解耦?
数据库耦合,需要对架构进行调整:
(1)第一步,公共数据访问服务化,数据私藏;
(2)第二步,个性数据访问,自己家的数据自己管理;
画外音:数据库耦合,当数据库成为瓶颈时,增加数据库实例也难以拆分扩容,非常头疼。
以上是关于架构设计指南 如何成为架构师的主要内容,如果未能解决你的问题,请参考以下文章