今天电话面试, 提到优秀架构的特点.

着实让我脑袋空了一把, 这个太难说了. 快速思考了一些之后, 我回答说, 简单.

好的架构并不会有特别复杂, 可以让每个人都看的懂, 这是我心中的好的架构. 但不知道面试官会怎么想. 我要详细说一下为什么这么个回答, 如果说的不对, 拍砖拍死我吧.

道家有云: 大道至简, 建筑大师密斯也说过: Less is more. 简单是好的架构的特点, 受欢迎的语言也是如此.

举个几个栗子:


一. 高并发的web

所有高并发的动态web结构简化后都是以下3大块:

  • 存储层
  • 控制层
  • 请求响应层(apache/cgi/nginx)

于是为了达到高的并发能力

  1. 各层做好自己的缓存, 尽量不给底层带来压力.
  2. 各层把本身性能做好.
  3. 各层把任务发给最合适的下层.
  • 存储层
  1. 如果是数据库, 索引/外键/冗余数据设计好
  2. 控制好连接数, 慢查询的日志要跟Monitor配合, 快速处理.
  3. 访问压力大, 解决掉写入瓶颈问题
  4. 增加存储节点(对读写分离完全不建议, 同步延迟不说, 没必要这么做)
  • 控制层
  1. 访问存储层, 添加redis等内存级缓存, 使用连接池减少连接次数与连接数, 尽量减少查询上下流, 尽量远离join查询, 只update需要update的内容.
  2. 多存储节点的选择控制(hash与map规则, 或者可以使用中间件的工具)
  3. 优化处理能力, 可以多线程, 多进程, 协程, 异步, 减少cpu消耗/资源占用/等待时间等.
  4. 模块分工, 公共library开发 ,library以外的模块没有任何耦合, 让各小队可以独立前进.
  5. 瓶颈优化, 可以考虑把library与各其他有瓶颈的地方着重优化, 保证快速响应.
  6. 对于完成业务类型更多的内容, 比如数据层的访问与管理, 可以单独拉出一层.
  • 请求响应层
  1. 加大Request队列容量(针对不同的环境可以考虑Request去重).
  2. 堵塞快速处理
  3. 控制请求分发至其他服务器/控制层/静态文件.
  4. 静态文件CDN存储.

实际上以上的描述是所有高并发网站共有的架构.

以上架构还缺了一个很重要的环节, 就是monitor, 再专门做好monitor, 监控好log,加入报警event, 这个系统就非常完美了.

大部分开发为了让项目更可控, 都会使用MVC把控制层细分, 但我要说的是view可以分拆出去. model层实际上属于私有library. 对求性能的web来说, ORM是累赘, 可以逐步砍掉. 真正需要加大投入的还是在Controller层.

有些框架是MVT, 比如Django, 不管框架怎么细分层, 按产品内容去分任务, 每个人分到不同的任务就可以做不同部分的事情, 同时也可以对特殊产品使用特殊的架构. git版本控制是神器, 合并分支又这么简单, 所以还应该从OOP往流程化收敛一下.

针对web还要提到一些提升性能的问题, 可以在前端靠javascript的访问实现一些动态数据, 比如用户信息, 购物车. 这样跨部门合作, 提升性能都会非常棒的.


 二. 爬虫架构

web是流出型服务, 爬虫是流入型业务. 这里就简单些说.

  1. 下载器(downloader)
  2. 解析器(parser 可以合并到控制器)
  3. 存储器(importer)
  4. 控制器(controller)
  • 下载器的能力决定了下载速度, 有些特殊的业务是需要反”反爬虫”技术的, 可能需要加代理, 填写验证码等等.
  • 控制器的排重决定了爬取的有效率
  • 存储器有必要可以对数据进行简单的清洗
  • 有些业务类型比较特殊, 需要专门写解析器, 还要有出错反馈机制.

最大的瓶颈是在下载器, 下载器用异步会大大提高效率, 再搭上多线程或者多进程, 那这个下载器就无敌了, 这样之后的瓶颈有可能会在网络或存储的I/O.

所有程序想要达到更高的执行效率, 就需要有更脱离可读语言的编写, 比如异步twisted, 这些看似复杂, 其实经过好好思考, 原理也是非常简单.

还是要说, 要加上一个Monitor, 监控log, event, 配合工作, 这也算架构的一部分.有些要做unit test, 实际上, 这就是个保险丝的作用.农村家里没有保险盒,很容易一家短路全村断电. 要不要强制做, 要看团队的素质与代码质量和unit test的优先级.


 

三. 架构中的中间件与控制层

目前有名的框架/软件 都会有个middleware

实际上middleware是一个通用逻辑的处理, 我以上所说的两种架构实现的框架都会加上很多Middleware层.

我还是很喜欢Middleware这种设计的, 但是返回来思考, Middleware 只是被控制的一部分, 属于控制层.

而且在框架中一般都会有个Engine控制middleware, 也同时控制着你写的控制层.

为了架构更有针对性, 控制层就可以细分成为多个不同的控制单元, 下文中将会提到.

大部分人在看到架构图的时候会搞的一头雾水, 实际上就是被这些中间件与引擎搞的, 大家下次再看架构图的时候不妨先把middleware忽略掉, 然后把控制层与引擎合并, 再看看架构是又多简单.

附 Scrapy 架构图 vs 简化架构图:

scrapy_architecture

 

存储器

控制器 — 下载器 — Internet

解析器


 架构进阶:

通过以上的描述, 其实我们已经得到了最精良的骨架.

架构师接下来还是要根据产品的访问量与本身业务特点细化, 尤其是控制层的地方. 比如web控制层可以分为mvc, 然后在各层加上中间件, 可以按project/app/的结构来实现不同产品或项目的管理, 使每个产品与项目有自己都有的settings与middleware.

下一步应该是各个不同的业务类型中的实现, 比如有的需要消息服务, 队列服务, 特殊的存储, 连接池子等等.

最后用简洁的图表达出来, 如上图scrapy的架构图.

至于UML图就让大家一起参与进来吧, 因为这些都是血肉了, 等画图来和写出代码来也离的没多远了.


 

总结:

有本书叫«架构之美», 架构是一门艺术也是哲学, 不仅仅在程序上, 在国家企业管理上一样得以体现, 好的企业或者国家的管理都简单有效.

圣经旧约中曾提到, 以色列在管理人的时候要分很多层级,  而层级的领导人只管理10个人左右. 当下互联网盛行, 也兴起了扁平化的管理.

对于管理学, 设计管理方式的工作就叫做架构. 每个伟大的管理方式, 不管是扁平化管理还是层级管理, 都极其经典并且简单.

我是建筑学出身, 看过一大些好的设计. 国际著名的建筑大师做出的作品, 都可以用一张极其简单的草图画出来, 比如大家熟知的鸟巢, 央视大楼, 东直门的当代MOMA, 三里屯的Soho. 简单背后你能看到的是专注与专业.

软家架构也应当如此, Less is more.