按照研发前后端约定的API规范来制定API文档,Swagger用于开发和记录REST API的工具。
这种方法在许多场景中都很有效,但对于更复杂的场景来说,它通常是不够的。实现它也可能很耗时。可使用GraphQL来支持高效的数据获取。
按照dubbo接口设计规范来制定接口文档。
这种服务发现方法是两种模式的组合。第一种模式是自注册模式。服务实例调用服务注册表的注册API来注册其网络位置。它还可以提供运行状况检查URL,运行状况检查URL是一个API端点,服务注册表会定期调用该端点来验证服务实例是否正常且可用于处理请求。服务注册表还可能要求服务实例定期调用“心跳” API以防止其注册过期。
当客户端想要调用服务时,它会查询服务注册表以获取服务实例的列表。为了提高性能,客户端可能会缓存服务实例。然后,服客户端使用负载平衡算法(例如循环或随机)来选择服务实例。然后它向选择的服务实例发出请求。
分布式系统中,当服务试图向另一个服务发送同步请求时,永远都面临着局部故障的风险。因为客户端和服务端是独立的进程,服务端很有可能无法在有限的时间内对客户端的请求做出响应。服务端可能因为故障或维护的原因而暂停。或者,服务端也可能因为过载而对请求的响应变得极其缓慢。
客户端等待响应被阻塞,这可能带来的麻烦就是在其他客户端甚至使用服务的第三方应用之间传导,并导致服务中断。
使用Hystrix只是解决方案的一部分。还必须根据具体情况决定如何从无响应的远程服务中恢复服务。一种选择是服务只是向其客户端返回错误。返回备用值(fallback value,例如默认值或缓存响应)可能会有意义。
服务还可以使用发布/订阅的方式对外发布事件。此API风格的规范包括事件通道以及服务发布到通道的事件式消息的类型和格式。
消息和消息通道模型是一种很好的抽象,也是设计服务异步API的好方法。但是,为了实现服务,需要选择具体的消息传递技术并确定如何使用它们的能力来实现设计。
消息代理是所有消息的中介节点。发送方将消息写入消息代理,消息代理将消息发送给接收方。使用消息代理的一个重要好处是发送方不需要知道接收方的网络位置。另一个好处是消息代理缓冲消息,直到接收方能够处理它们。 有许多消息代理可供选择。流行的开源消息代理包括:
如何在保留消息顺序的同时,横向扩展多个接收方的实例。为了同时处理消息,拥有多个实例是一个常见的要求。而且,即使单个服务实例也可能使用线程来同时处理多个消息。使用多个线程和服务实例来并发处理消息可以提高应用程序的吞吐量。但同时处理消息的挑战是确保每个消息只被处理一次,并且是按照它们发送的顺序来处理的。
Kafka使用consumer group,特定的每个事件都发布到同一个分片,而且该分片中的消息始终由同一个接收方实例读取。这样做就能够保证按顺序处理这些消息。
理想情况下,消息代理应该只传递一次消息,但保证有且仅有一次的消息传递通常成本很高。相反,大多数消息代理承诺至少成功传递一次消息。当系统正常工作时,保证传递的消息代理只会传递一次消息。但是客户端、网络或消息代理的故障可能导致消息被多次传递。假设客户端在处理消息后、发送确认消息之前,它的数据库崩溃了,这时消息代理将再次发送未确认的消息,在数据库重新启动时向该客户端或客户端的另一个副本发送。
如果应用程序处理消息的逻辑是满足幂等的,那么重复的消息就是无害的。通常情况下应用程序逻辑通常不是幂等的。或者可能正在使用消息代理,该消息代理在重新传递消息时不会保留排序。重复或无序消息可能会导致错误。在这种情况下,就必须编写跟踪消息并丢弃重复消息的消息处理程序。
消息接收方使用message id跟踪它已处理的消息并丢弃任何重复项。