1. 你应当明确强弱依赖
系统中的模块之间、系统与外部系统之间,都需要明确了解他们的依赖关系,这样不仅能够很清楚的了解到系统的稳定性风险在哪里,而且对于设计出合理、灵活的技术架构都有重大意义。并且服务间的强弱依赖又会影响甚至决定其SLA。
1.1 强依赖
服务A强依赖于服务B,意味着服务A的正常运行很大程度上依赖于服务B的可用性和性能,那么服务A各项指标则会受到服务B的显著影响。
如果我们的服务本质上只是外部服务的一种包装、通道、或者增强,那本质上我们提供的就是服务B。比如支付服务和银行接口,本质上支付平台仅是渠道、流量入口,这种情况下必须是强依赖。
此外如果我们的服务是独立的服务,外部服务是服务于我们的,那么需要考虑下是否应该强依赖,还是将其降级为弱依赖。
1.2 弱依赖
服务A若依赖于服务B,意味着服务A的核心功能并不需要服务B的参与。只不过某些情况下如果服务B宕机,服务A的功能上需要受损或降级,但这并不影响服务A的正常运行。
通常这种情况下,既然服务B不是核心服务,也就比较容易找到服务B的替换方案,以此来作为服务B的
2. 你应当根据服务量级提供不同的SLA
这个概念举个例子,就很容易理解:
银行转账的服务,对于小额转账,可以做到2小时内到账,但对于大额转账,通常会以天级别计算。这就是典型的SLA划分。
针对统一服务的不同水平的SLA划分,这对于用户的预期管理、使用体验,其实非常重要,同时对于技术上的实现也非常重要。
同样是银行转账服务,如果不同的金额的对外SLA相同,这就意味着客户认为大额转账也应该小时级别到账,在有着这样的预期之后,就很容易出现体验落差。
同时在技术上要求无论什么金额,都需要满足小时级别的到账,这无疑是不合理的,也是有很大的风险的。
因此你应该在业务的设计之初就考虑到针对不同的用户、数据体量来提前做好用户的预期管理、技术选型等等;3. 你应当明确外部依赖的SLA
当你的服务,依赖了外部服务、中间件,就像不停地在向你的木桶中增加新的木板,这些木板可能会让你的木桶容量变大,也有可能变少。通常业界优秀的中间件都有着很高的可用性和性能,这往往不会出现问题,但我们仍需要关注SLA,以及它是否能match我们的业务。
3.1 API网关服务
在微服务架构中,服务间的依赖、调用十分常见,各个服务内部对流量的控制策略也不尽相同,在使用其他服务时,对于这些外部服务的流量控制策略、响应时间、超时时间等等都需要明确了解。
限流策略:服务A调用服务B,如果服务A的流量远大于服务B,或者服务A内部放大了对服务B的流量,比如1次服务A的调用,可能触发多次服务B的调用。此时了解服务B的限流策略是非常有必要的,这完全有可能影响服务A的正常运行。
通常情况下,服务间调用都会有着重试机制,在有限流策略的服务面前,慎重重试;
响应和超时时间:服务B的响应时间过长,在大流量的场景下,很容易出现拖垮上游服务的情况。因此对于了解或实时监控外部服务的RT,对超时时间的把控,十分重要。
通常需要将服务A内部的所有依赖和自己的计算耗时相加,最终计算出服务A对外的响应时间。
3.2 消息队列服务
MessageQueue中间件的SLA通常体现在:
- 可用性:对于大部分优秀的MQ中间件都有着出色的可用性。如Kafka、RabbitMQ;
- 消息传递可靠性:通常由副本机制、确认机制来决定。关注以下2点:
- 保证消息不丢失;
- 消息不重复;
- 消息延迟:不同的MQ的消息实时性不尽相同,如Kafka的延迟在毫秒级,而RabbitMQ能做到微秒级。
- 吞吐量:kafka拥有着极高的吞吐量,特别适合大规模的消息流处理、日志采集等;
3.3 数据库
数据库的SLA通常体现在:
- 分布式场景的数据一致性;
- 强一致性保证;
- 读写性能
- 并发读写能力
- 查询性能及优化能力
- 可用性:数据库往往是一个系统中的瓶颈,不仅是性能瓶颈,更有着单点问题。
3.4 缓存中间件
缓存组件,如Redis、Memcached等,通常对于性能要求比较高:
- 并发读写性能:通常以QPS来衡量并发读写性能;
- 内存淘汰策略:在内存吃紧时,通过什么样的内存淘汰策略,来保证服务的可用性;