Server 架构
一、架构的目的
架构设计的主要目的:是为了解决软件系统复杂度带来的问题。
二、基本概念
系统与子系统,模块与组件,框架与架构
划分模块的主要目的是职责分离;
划分组件的主要目的是单元复用。
框架是组件规范。eg:MVC、MVP、MVVM、J2EE等。
架构关注的是结构。
4+1视图——的结构标准。
三、高性能
服务器集群
1、任务分配
任务分配器从 1 台变成了多台(对应图中的任务分配器 1 到任务分配器 M),这个变化带来的复杂度就是需要将不同的用户分配到不同的任务分配器上(即图中的虚线“用户分配”部分)。
常见的方法包括 DNS 轮询、智能 DNS、CDN(Content Delivery Network,内容分发网络)、GSLB 设备(Global Server Load Balance,全局负载均衡)等。
CDN是什么?使用CDN有什么优势? - 阿里巴巴淘系技术的回答 - 知乎 https://www.zhihu.com/question/36514327/answer/1604554133
(1)改图保持图片URL不变,可以避免商品链路的缓存失效。
(2)在访问高峰到来之前,提前预热图片到CDN,可以避免CDN缓存失效对源站的压力。
2、任务分解
为何通过任务分解就能够提升性能?
- 1、简单的系统更加容易做到高性能
- 2、可以针对单个任务进行扩展
四、高可用
有一个本质上的区别:将数据从一台机器搬到到另一台机器,需要经过线路进行传输。线路传输的速度是毫秒级别,同一机房内部能够做到几毫秒;分布在不同地方的机房,传输耗时需要几十甚至上百毫秒。例如,从广州机房到北京机房,稳定情况下 ping 延时大约是 50ms,不稳定情况下可能达到 1s 甚至更多。
存储高可用的难点不在于如何备份数据,而在于如何减少或者规避数据不一致对业务造成的影响。
民主式决策指的是多个独立的个体通过投票的方式来进行状态决策。例如,ZooKeeper 集群在选举 leader 时就是采用这种方式。
Zookeeper的工作角色 ——> https://www.cnblogs.com/raphael5200/p/5285583.htm
五、可扩展性
设计模式的核心就是,封装变化,隔离可变性 。
这是设计模式的核心思想,能理解到这点比背住23个模式更重要。
六、低成本、安全、规模
1、 低成本给架构设计带来的主要复杂度体现在,往往只有“创新”才能达到低成本目标。
类似的新技术例子很多,我来举几个。
NoSQL(Memcache、Redis 等)的出现是为了解决关系型数据库无法应对高并发访问带来的访问压力。
全文搜索引擎(Sphinx、Elasticsearch、Solr)的出现是为了解决关系型数据库 like 搜索的低效的问题。
Hadoop 的出现是为了解决传统文件系统无法应对海量数据存储和计算的问题。
Facebook 为了解决 PHP 的低效问题,刚开始的解决方案是 HipHop PHP,可以将 PHP 语言翻译为 C++ 语言执行,后来改为 HHVM,将 PHP 翻译为字节码然后由虚拟机执行,和 Java 的 JVM 类似。
新浪微博将传统的 Redis/MC + MySQL 方式,扩展为 Redis/MC + SSD Cache + MySQL 方式,SSD Cache 作为 L2 缓存使用,既解决了 MC/Redis 成本过高,容量小的问题,也解决了穿透 DB 带来的数据库访问压力(来源:http://www.infoq.com/cn/articles/weibo-platform-archieture )
Linkedin 为了处理每天 5 千亿的事件,开发了高效的 Kafka 消息系统。
其他类似将 Ruby on Rails 改为 Java、Lua + redis 改为 Go 语言实现的例子还有很多。
2、从技术的角度来讲,安全可以分为两类:一类是功能上的安全,一类是架构上的安全。
七、架构设计三原则
合适原则、简单原则、演化原则
合适原则宣言:“合适优于业界领先”。
简单原则宣言:“简单优于复杂”。—— KISS原则:Keep it Simple,Stupid.
演化原则宣言:“演化优于一步到位”。 ——软件架构需要根据业务发展不断变化。
八、架构设计流程
1、识别复杂度
2、设计备选方案
易犯错误:
第一种常见的错误:设计最优秀的方案——违背合适原则和简单原则
第二种常见的错误:只做一个方案。
单一方案设计会出现过度辩护的情况,即架构评审时,针对方案存在的问题和疑问,架构师会竭尽全力去为自己的设计进行辩护,经验不足的设计人员可能会强词夺理。
备选方案的数量以 3 ~ 5 个为最佳。
备选方案的差异要比较明显。
备选方案的技术不要只局限于已经熟悉的技术。
第三种常见的错误:备选方案过于详细。
3、评估和选择备选方案
“360 度环评”。
具体的操作方式为:列出我们需要关注的质量属性点,然后分别从这些质量属性的维度去评估每个方案,再综合挑选适合当时情况的最优方案。
常见的方案质量属性点有:性能、可用性、硬件成本、项目投入、复杂度、安全性、可扩展性等。
通常情况下,如果某个质量属性评估和业务发展有关系(例如,性能、硬件成本等),需要评估未来业务发展的规模时,一种简单的方式是将当前的业务规模乘以 2 ~4 即可,如果现在的基数较低,可以乘以 4;如果现在基数较高,可以乘以 2。例如,现在的 TPS 是 1000,则按照 TPS 4000 来设计方案;如果现在 TPS 是 10000,则按照 TPS 20000 来设计方案。
正确的做法是按优先级选择,即架构师综合当前的业务发展情况、团队人员规模和技能、业务发展预测等因素,将质量属性按照优先级排序,首先挑选满足第一优先级的,如果方案都满足,那就再看第二优先级……以此类推。
4、详细方案设计
可以完善的细节:
1、发送端和消费端如何寻址
利用zookeeper做注册中心,把broker的地址注册到zk上,发送端和消费端只要配置注册中心的地址即可获取集群所以broker地址,当有broker下线时,发送端和消费端能及时更新broker地址。
2、发送端消息重试
当发送消息发生网络异常时(不包括超时异常),可以重新选择下一台broker来重试发送,重试策略可以自定义。
3、消息消费采用pull还是push?
考虑push模式会更复杂,故放弃,采用pull模式,消费端主动去拉,为了达到与push模式相同的低延迟效果,可以采用长轮询的方式,消费端轮询拉取消息费,当有消费可消费时,返回消息,如果没有可消费的消息,挂起当前线程,直到超时或者有可消费的消息为止。
4、消息重复问题
消息中间件不解决消息重复的问题,有业务系统自己根据业务的唯一id去重。
5、顺序消息
发送端在发生顺序消息时,只发送到相同broker的相同队列,消费端消费时,顺序消息只能由同一个消费端消息。
6、定时消息
发送端指定消息延时多长时间消费,broker端定时扫描定时消息,达到延时时间的消息加入到消费队列。
7、事务消息
发送端分两步,先预发送消息,broker端只记录消息为预发送状态,再执行本地事务,然后再根据本地事务的成功或者失败发送确认消息(回滚还是提交),这步如果发生异常,broker启动定时任务,把未确认的消息发送给发送端回查事务状态(需要发送端提供回查接口)。