之前的《谈谈架构》讲述了架构的概念、原则等等,这里择出其中的设计原则部分供大家随手参考。

架构原则

  • 避免过度设计:最简单的方案最容易实现和维护,也可以避免浪费资源。但方案中需要包括扩展。
  • 冗余设计:对服务、数据库的做结点冗余,保证服务的高可用。通过数据库主从模式、应用集群来实现。
  • 多活数据中心:为了容灾,从根本上保障应用的高可用性。需要构建多活的数据中心,以防止一个数据中心由于不可控因素出现故障后,引起整个系统的不可用。
  • 无状态设计:API、接口等的设计不能有前后依赖关系,一个资源不受其他资源改动的影响。无状态的系统才能更好地进行扩展。如果非得有状态,则要么客户端管理状态,要么服务端用分布式缓存管理状态。
  • 可回滚:对于任何业务尤其是关键业务,都具有恢复机制。可以使用基于日志的WAL、基于事件的Event sourcing等来实现可回滚。
  • 可禁用/自我保护:具有限流机制,当上游的流量超过自身的负载能力时,能够拒绝溢出的请求。可以通过手动开关或者自动开关(监测异常流量行为),在应用前端挡住流量。
  • 问题可追踪:当系统出现问题时,能够定位请求的轨迹、每一步的请求信息等。分布式链路追踪系统即解决的此方面的问题。
  • 可监控:可监控是保障系统能够稳定运行的关键。包括对业务逻辑的监控、应用进程的监控以及应用依赖的CPU、硬盘等系统资源的监控。每一个系统都需要做好这几个层面的监控。
  • 故障隔离:将系统依赖的资源(线程、CPU)和服务隔离开来能够使得某个服务的故障不会影响其他服务的调用。通过线程池或者分散部署结点可以对故障进行隔离。
  • 成熟可控的技术选型:使用市面上主流、成熟、文档、支持资源多的技术,选择合适的而非最火的技术实现系统。
  • 梯级存储:内存->SSD硬盘->传统硬盘->磁带,可以根据数据的重要性和生命周期对数据进行分级存储。
  • 缓存设计:隔离请求与后端逻辑、存储,是就近原则的一种机制。包括客户端缓存(预先下发资源)、Nginx缓存、本地缓存以及分布式缓存。
  • 异步设计:对于调用方不关注结果或者允许结果延时返回的接口,采用队列进行异步响应能够很大程度提高系统性能;调用其他服务的时候不去等待服务方返回结果直接返回,同样能够提升系统响应性能。异步队列也是解决分布式事务的常用手段。
  • 前瞻性设计:根据行业经验和预判,提前把可扩展性、后向兼容性设计好。
  • 水平扩展:相比起垂直扩展,能够通过堆机器解决问题是最优先考虑的问题,系统的负载能力也才能接近无限扩展。此外,基于云计算技术根据系统的负载自动调整容量能够在节省成本的同时保证服务的可用性。
  • 小步构建和发布:快速迭代项目,快速试错。不能有跨度时间过长的项目规划。
  • 自动化:打包、测试的自动化称为持续集成,部署的自动化称为持续部署。自动化机制是快速迭代和试错的基础保证。

架构六步思考法

笔者对美团总架构师夏华夏一次分享提出的架构六步思考法的理解。

数据设计原则

  • 注意存储效率
    • 减少事务
    • 减少联表查询
    • 适当使用索引
    • 考虑使用缓存
  • 避免依赖于数据库的运算功能(函数、存储器、触发器等),将负载放在更容易扩展的业务应用端
  • 数据统计场景中,实时性要求较高的数据统计可以用Redis;非实时数据则可以使用单独表,通过队列异步运算或者定时计算更新数据。此外,对于一致性要求较高的统计数据,需要依靠事务或者定时校对机制保证准确性。

系统响应性能提升五板斧

  • 异步:队列缓冲、异步请求。
  • 并发:利用多CPU多线程执行业务逻辑。
  • 就近原则:缓存、梯度存储。
  • 减少IO:合并细粒度接口为粗粒度接口、频繁的覆盖操作可以只做最后一次操作。这里一个需要特别注意的地方: 代码中尽量避免在循环中调用外部服务,更好的做法是使用粗粒度批量接口在循环外面只进行一次请求。
  • 分区:频繁访问的数据集规模保持在合理的范围。