我们正在使用ServiceStack 3.x运行自托管的AppService
如果作为主服务器运行的当前服务失败,我们希望在客户端上有自动故障转移机制。
目前客户端是使用默认SS JSONClient的强类型C#,但我们将来会添加基于Web的客户端(AngularJS)。
有人有想法,怎么做?
答案 0 :(得分:2)
这是一个非常广泛的问题。 ServiceStack自托管应用程序与任何其他面向Web的资源没有什么不同。所以你可以像网站一样对待它。
您可以使用常规网站监控工具对其进行监控。这些工具可以像正常运行时监控站点一样简单,只需定期ping您的Web服务以确定它是否已启动,如果不采取措施,例如触发服务器重启,或者只是向您发送电子邮件说它没有用。
如果您使用的是Amazon EC2等云提供商,他们会提供可配置为监控主机和服务运行状况的CloudWatch服务。如果发生故障,它可能会重新启动您的实例,或者启动另一个实例。其他提供商提供类似的工具。
您还可以考虑DNS故障转移。许多DNS提供商可以监控服务的正常运行时间,并且在发生故障转移时,他们的服务会将DNS路由更改为指向另一个备用服务。因此,故障转移对客户端是透明的。
另一种选择是将您的服务置于负载均衡器后面,并让多个实例运行您的服务。除非您的服务设计存在灾难性错误,否则负载均衡器后面的所有节点失败的可能性通常很低。
当您使用自托管应用程序时,您可以考虑在系统上创建另一个应用程序,该应用程序只检查您的服务应用程序主机是否正在运行,如果没有重新启动它。这将处理异常导致应用程序意外终止的情况 - 当然这不是一个长期解决方案,您将需要修复异常。
如果您在Linux平台上使用Mono运行ServiceStack应用程序,则有许多高可用性解决方案,包括HAProxy或NGINX。如果您在Windows Server上运行,则会提供failover mechanisms。
正确的解决方案取决于您的环境,项目预算,以及解决故障转移所需的速度。最终的考虑应该是服务故障转移到哪里?
有很多关于网站故障转移的文章,因为您的网络服务像网站一样使用HTTP,它们也适用于此处。您应该研究高可用性。
亚马逊AWS提供了许多帮助进行故障转移的解决方案。他们的Route 53 service在这方面非常好,他们的负载均衡器也是如此。
客户端故障转移很少实用。在您的客户端,您最终只能测试连接性。
如果与您的服务连接失败,您将获得例外。获得异常后,唯一的解决方案是更改目标服务URL,然后重试该请求。但是这有很多问题:
它可能与服务器端故障转移一样昂贵,因为您必须始终将故障转移服务保持在线状态才能实现正常情况。 某些服务器端解决方案允许您按需启动故障转移服务,从而显着降低成本。
所有客户端也必须知道要进行故障转移的URL。 如果你在DNS(即服务器端)管理故障转移,那么客户就不必担心这种复杂性。
您的客户端只能看到连接失败,服务器可能没有问题,可能是他们的连接。 想象一下,客户端wifi在服务于主服务服务器的请求时会停机几秒钟。在此期间,客户端获取连接异常,并尝试将请求发送到故障转移辅助服务服务器,此时它们的wifi将联机。现在您有客户端同时使用主服务和辅助服务。因此,他们的网络连接问题会成为您的数据一致性问题。
如果您计划基于Web的客户端,则必须在服务器上设置CORS支持,并且所有客户端都需要兼容的浏览器,以便他们可以更改目标服务URL。 CORS请求的缺点是常规请求的开销更大,因为客户端也必须发送OPTIONS请求。
客户端中的连接错误检测很少。有时,在客户将请求失败之前可能需要超过30秒。
如果您的服务API是公共的,那么您依赖最终用户实现故障转移机制。您无法保证他们会这样做,或者他们会这样做,或者他们不会利用知道您的其他服务网址并在那里发送请求。此外,它看起来非常不专业。
您无法保证故障转移在需要时能够正常运行。很难保证对于任何系统,即使是大公司也存在故障转移问题。服务器端故障转移解决方案有时无法正常工作,但对于客户端解决方案来说更是如此,因为您可以在所有不同的客户端环境因素下提前测试故障转移解决方案。仅仅因为您的客户端中的故障转移实现在您的部署中工作,它是否适用于所有部署?毕竟,故障转移解决方案的目的是最大限度地降低风险。服务器端故障转移无法工作的风险远低于客户端,因为它是一个较小的可控环境,您可以测试。
因此,虽然我的考虑因素可能不利于客户端故障转移,但如果您打算这样做,则可以捕获连接异常并决定如何处理它们。您可能需要等待几秒钟,然后重新向主服务器重试请求,然后立即交换到辅助服务器,以防它出现间歇性错误。
所以: