微服务器开发检查清单

70 阅读6分钟

基本问题

  1. 这个服务的职责和边界是什么?
  2. 如何自动从代码到产品来构建这个服务?
  3. 如何自动部署,运行,停止,升级和扩展这个服务?
  4. 这个服务使用什么数据存储系统? SQL or NoSQL
  5. 这个服务与其他服务之间通信的方式是什么?
  6. 这个服务依赖哪些其他服务? 又被哪些服务所依赖?其拓扑结构如何?
  7. 这个服务会不会存储敏感数据?如果会,有没有加密,密钥如何管理的?
  8. 这个服务会开放给最终用户使用,还是仅仅在内部使用?
  9. 如何单独测试这个服务? 以及如何与其他服务一起整体进行测试?
  10. 这个服务依赖于哪个平台, 如何利用其服务治理功能?

还有更多的问题需要一一检查:

操作系统

Linux: CentOS 是首选, Ubuntu 或 Redhat 其他系统亦可,不推荐 windows 作为服务器的宿主系统

编程语言

  • C或C++ 是首选,适合于计算量大和对性能要求比较高
  • Java 对于复杂的业务逻辑比较有优势,只要你对由于 GC 导致的延迟不敏感.
  • GO 语言颇有后来居上的势头,只需要发布二进制包,无需解释或执行器,而且跨平台兼容性,性能也不错,内置了并发和网络库也很不错
  • 其他脚本语言: python, ruby, nodejs 也可用于性能要求不高的场景

线程模型:

在服务器内部可以划分为如下线程

  • 网络线程: Non-blocking IO + IO multiplexing + Event loop per thread
  • 业务线程: Blocking queue + Thread Pool
  • 日志和度量事件发送线程:最好和业务线程分开
  • 数据库线程

度量框架

我们需要度量如下的关键指标

  • 系统资源消耗度量如何? 比如 CPU, 内存, 磁盘及网络 IO 等
  • 应用关键指标度量如何? 比如吞吐量和响应时间,成功率等
  • 主要业务功能指标如何? 比如并发在线人数,关键功能的使用率等
  • 高压力之下的性能如何:在高并发,大压力下的性能表现

而度量代码本身应该是非侵入式的,且对资源的消耗低,不影响主要的业务流程。

高可用机制

  • 服务器是否是无状态的,抑或有状态同步机制?
  • 有无有健康检查和心跳机制?
  • 有无集群内和跨集群的冗余备份?
  • 有无分流,限流和断流的机制?
  • 能否快速重启,快速恢复?

可用性和一致性的权衡

CAP 理论上是不可同时满足的, 而分布式系统中 Partial Failure 是不可避免的 所以要在Consistence 和 Availability 上做折衷和权衡。

  • 一致性的目标是什么? 例如金融银行领域的业务服务需要强一致性,宁可牺牲一些可用性,而会议服务器可需要更高的可用性,仅需要最终一致性就好了。

  • 可用性的目标是什么?

高可性性的指标就是可用时间与总时间之比

availability = uptime/(uptime + downtime)

现在普遍要求可用性至少达到两个九, 最好在四个九以上, 也就是说你的服务要达到如下要求

  • 如何权衡可用性和一致性?

高扩展性

业务扩展迅速,如何快速扩展以应对高速增长的流量呢

  1. 是否可以通过单纯地增加服务器来应对流量的增长?
  2. 是否可以进行水平和垂直拆分?例如 DB sharding, 根据业务实体的主键进行分库分表

安全性

  • Authentication 认证要求 - 用户是不是通过认证的合法用户?
  • Authorization 授权要求 - 用户是不是经过授权的合法用户, 所访问的模块是在其权限范围之内的?
  • Audit 可审查和追溯要求 - 用户的访问和操作是不是可以审查和追溯的?

还有对于用户隐私的保护

  • 用户的个人敏感信息 PII (Personal Insentive Information ) 是不是在服务器的日志或数据库中随意存放?

例如密码必须经过不可逆的哈希之后再存储在数据库中, 个人的邮件, 电话等信息均不可存放在日志文件中, 只可以放在有访问限制的数据管理系统中

  • 数据在传输层是不是安全的? 有没有使用 TLS, DTLS 或者 SRTP 进行加密传输?
  • 数据在应用层是不是有上述 “3A” 的保护?

API

  • 是不是采用标准化的协议?
  • 是不是容易理解?
  • 是不是容易扩展,向前兼容?
  • 是不是可自动生成文档?

网络工具包

我们在选择框架和软件工具包应该遵循 4L 原则

  • License is free and open 是不是免费开源的?
  • Lots of people use it 是不是有许多人在使用它?
  • Lots of successful cases 是不是有许多成功的案例?
  • Lots of learn materials 是不是有许多易于学习的资料?

例如,Java 的 Netty 和 C++ 的 Boost 都满足上述原则

以 Java Netty 为例

  • API使用简单,上手快,学习成本低。
  • 功能强大,内置了多种解码编码器,支持多种协议。
  • 性能优秀,高吞量,低延迟,资源消耗低。
  • 社区活跃,bug和问题能及时修复,还在不断迭代和演化中。
  • 使用广泛,有很多成功案例都采用了Netty,质量有保证。

以 Boost asio 的设计为例

特性说明
可移植性该库应支持一系列常用的操作系统,并在这些操作系统之间提供一致的行为。
可扩展性该库应促进可扩展到数千个并发连接的网络应用程序的开发。每个操作系统的库实现应使用最能实现此可伸缩性的机制。
效率该库应支持散布式聚集I / O等技术,并允许程序将数据复制减至最少。
来自已建立的API的模型概念例如BSD套接字。 BSD套接字API得到了广泛的实现和理解,并且在许多文献中都有涉及。其他编程语言通常将类似的接口用于网络API。在合理的范围内,Boost.Asio应该利用现有做法。
使用方便该库应采用工具包而非框架方法,从而为新用户提供一个较低的入门障碍。就是说,它应该在学习一些基本规则和准则的情况下,设法及时减少前期投资。之后,库用户只需要了解所使用的特定功能。
进一步抽象的基础该库应允许开发提供更高抽象级别的其他库。例如,常用协议(例如HTTP)的实现。

参考资料