## 架构思想

---

关于什么是架构，一种比较通俗的说法是 “最高层次的规划，难以改变的决定”，这些规划和决定奠定了事物未来发展的方向和最终的蓝图。

从这个意义上说，人生规划也是一种架构。选什么学校、学什么专业、进什么公司、找什么对象，过什么样的生活，都是自己人生的架构。

具体到软件架构，维基百科是这样定义的：“有关软件整体结构与组件的抽象描述，用于指导大型软件系统各个方面的设计”。系统的各个重要组成部分及其关系构成了系统的架构，这些组成部分可以是具体的功能模块，也可以是非功能的设计与决策，他们相互关系组成一个整体，共同构成了软件系统的架构。


架构其实就是把复杂的问题抽象化、简单化，可能你会觉得“说起来容易但做起来难”，如何能快速上手。可以多观察，根据物质决定意识，借助生活真实场景（用户故事，要很多故事）来还原这一系列问题，抓住并提取核心特征。


#### 架构思想

CPU运算速度>>>>>内存的读写速度>>>>磁盘读写速度


* 满足业务发展需求是最高准则
* 业务建模，抽象和枚举是两种方式，需要平衡，不能走极端
* 模型要能更真实的反应事物的本质，不是名词概念的堆砌，不能过度设计
* 基础架构最关键的是分离不同业务领域、不同技术领域，让整个系统具有持续优化的能力。
* 分离基础服务、业务规则、业务流程，选择合适的工具外化业务规则和业务流程
* 分离业务组件和技术组件，高类聚，低耦合 - 业务信息的执行可以分散，但业务信息的管理要尽量集中
* 不要让软件的逻辑架构与最后物理部署绑死 - 选择合适的技术而不是高深的技术，随着业务的发展调整使用的技术
*  好的系统架构需要合适的组织架构去保障 - 团队成员思想的转变，漫长而艰难
*  业务架构、系统架构、数据模型


#### 面对一块新业务，如何系统架构？
* 业务分析：输出业务架构图，这个系统里有多少个业务模块，从前台用户到底层一共有多少层。
* 系统划分：根据业务架构图输出系统架构图，需要思考的是这块业务划分成多少个系统，可能一个系统能支持多个业务。基于什么原则将一个系统拆分成多个系统？又基于什么原则将两个系统合并成一个系统？
* 系统分层：系统是几层架构，基于什么原则将一个系统进行分层，分成多少层？
* 模块化：系统里有多少个模块，哪些需要模块化？基于什么原则将一类代码变成一个模块。


#### 如何模块化

* 基于水平切分。把一个系统按照业务类型进行水平切分成多个模块，比如权限管理模块，用户管理模块，各种业务模块等。
* 基于垂直切分。把一个系统按照系统层次进行垂直切分成多个模块，如DAO层，SERVICE层，业务逻辑层。
* 基于单一职责。将代码按照职责抽象出来形成一个一个的模块。将系统中同一职责的代码放在一个模块里。比如我们开发的系统要对接多个渠道的数据，每个渠道的对接方式和数据解析方式不一样，为避免不同渠道代码的相互影响，我们把各个渠道的代码放在各自的模块里。
* 基于易变和不易变。将不易变的代码抽象到一个模块里，比如系统的比较通用的功能。将易变的代码放在另外一个或多个模块里，比如业务逻辑。因为易变的代码经常修改，会很不稳定，分开之后易变代码在修改时候，不会将BUG传染给不变的代码。

#### 提升系统的稳定性

* 流控

双11期间，对于一些重要的接口（比如帐号的查询接口，店铺首页）做流量控制，超过阈值直接返回失败。
另外对于一些不重要的业务也可以考虑采用降级方案，大促—>邮件系统。根据28原则，提前将大卖家约1W左右在缓存中预热，并设置起止时间，活动期间内这部分大卖家不发交易邮件提醒，以减轻SA邮件服务器的压力。

* 容灾

最大程度保证主链路的可用性，比如我负责交易的下单，而下单过程中有优惠的业务逻辑，此时需要考虑UMP系统挂掉，不会影响用户下单（后面可以通过修改价格弥补），采用的方式是，如果优惠挂掉，重新渲染页面，并增加ump屏蔽标记，下单时会自动屏蔽ump的代码逻辑。
另外还会记录ump系统不可用次数，一定时间内超过阈值，系统会自动报警。

* 稳定性

第三方系统可能会不稳定，存在接口超时或宕机，为了增加系统的健壮性，调用接口时设置超时时间以及异常捕获处理。

* 容量规划

做好容量规划、系统间强弱依赖关系梳理。
如：冷热数据不同处理，早期的订单采用oracle存储，随着订单的数量越来越多，查询缓慢，考虑数据迁移，引入历史表，将已归档的记录迁移到历史表中。当然最好的方法是分库分表。


#### 分布式架构

* 分布式系统
* 分布式缓存
* 分布式数据


#### API 和乐高积木有什么相似之处？

相信我们大多数人在儿童时期都喜欢玩乐高积木。乐高积木的真正乐趣和吸引力在于，尽管包装盒外面都带有示意图片，但你最终都可以随心所欲得搭出各种样子或造型。

对 API 的最佳解释就是它们像乐高积木一样。我们可以用创造性的方式来组合它们，而不用在意它们原本的设计和实现意图。

你可以发现很多 API 和乐高积木的相似之处：

- 标准化：通用、标准化的组件，作为基本的构建块（building blocks）；

- 可用性：强调可用性，附有文档或使用说明；

- 可定制：为不同功能使用不同的API；

- 创造性：能够组合不同的 API 来创造混搭的结果；

乐高和 API 都有超简单的界面/接口，并且借助这样简单的界面/接口，它可以非常直观、容易、快速得构建。

虽然乐高和 API 一样可能附带示意图片或使用文档，大概描述了推荐玩法或用途，但真正令人兴奋的结果或收获恰恰是通过创造力产生的。

让我们仔细地思考下上述的提法。在很多情况下，API 的使用者构建出了 API 的构建者超出预期的服务或产品，API 使用者想要的，和 API 构建者认为使用者想要的，这二者之间通常有个断层。事实也确实如此，在 IoT 领域，我们使用 API 创造出了一些非常有创造性的使用场景。



