🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 容错 在分布式系统中,世界各地的故障一直在发生。Micro试图用一些容错的最佳实践来解决这个问题。本文档介绍了一些可以配置的方法。 ## 心跳 心跳是服务发现中刷新注册的机制。 ### 基本原理 服务在启动时注册服务发现,并在关闭时取消注册。有时这些服务可能会意外死亡,被强行杀死或面临暂时的网络问题。在这些情况下,遗留的节点将存在服务发现中。如果服务被自动删除,这将是理想的。 ### 解决办法 由于这个确切原因,Micro支持注册的TTL选项和间隔。TTL指定在发现之后注册的信息存在多长时间,然后过期并被删除。时间间隔是服务应该重新注册的时间,以保留其在服务发现中的注册信息。 这些选项可以用micro工具包中提供的标志。 ### 用法 对于micro工具包,只需使用内置标志来设置ttl和间隔。 ``` micro --register_ttl=30 --register_interval=15 api ``` 以上这个例子,我们设置了一个30秒的ttl,重新注册间隔为15秒。 对于go-micro,当声明一个微服务时,你可以通过time.duration传递选项。 ``` service := micro.NewService( micro.Name("com.example.srv.foo"), micro.RegisterTTL(time.Second*30), micro.RegisterInterval(time.Second*15), ) ``` ## 负载均衡 负载均衡是传输请求负载或维持高可用性的一种方式 ### 基本原理 任何单个流程应用程序的可用性和扩展都存在限制。如果应用程序因任何原因死亡,您将无法再处理请求。如果有足够的请求负载发送到应用程序,它可能会开始缓慢响应或根本不响应。通过发送请求至多个应用程序副本可以解决这些问题。 ### 解决办法 Micro通过[选择器](https://godoc.org/github.com/micro/go-micro/selector#Selector)接口进行客户端负载平衡,以在任意数量的服务节点上传播请求。当服务启动时,它将服务发现注册为具有唯一地址和ID的服务节点。在发出请求时,Micro客户端使用选择器来决定向哪个节点发出请求。选择器使用服务注册表查找服务的节点,然后使用负载均衡策略(例如:随机哈希或循环法)选择要发送请求的节点。 ### 用法 客户端负载平衡内置于go-micro客户端。这是自动完成的。 ## 重试 重试是一种在不成功时重试请求的方法 ### 基本原理 由于许多原因,请求可能会失败; 网络错误,请求加载,应用程序死亡。在这些情况下,如果我们可以针对不同的应用程序副本重试请求以获得成功的响应,那将是理想的。 ### 解决办法 微客户端包括一个重试请求的机制。选择器(如上所述)返回一个Next函数,该函数在执行时使用负载平衡策略从列表中返回一个节点。Next函数可以执行多次,根据负载均衡策略返回一个新节点。如果设置了重试次数,如果请求失败,则会执行Next函数,并且将针对新节点重试请求。 ### 用法 重试可以设置为客户端的标志或选项。它默认为1,意味着1次尝试请求。 通过标志进行更改。 ``` micro --client_retries=3 ``` 通过选项进行设置。 ``` client.Init( client.Retries(3), ) ``` ## 缓存发现 发现缓存是服务发现信息的客户端缓存 ### 基本原理 服务发现是微服务的核心依赖,但如果架构不正确,也可能成为单点故障。每个发现系统都有自己的扩展性和高可用性。在事件发生下降的情况下,由于服务不知道如何解析名称到地址,系统的其余部分将无法使用。如果为系统中的每个请求执行查找,发现也可能成为瓶颈。 ### 解决办法 客户端缓存是一种消除服务发现瓶颈和单点故障的方法。Micro包含一个选择器(客户端负载平衡器),它在服务发现信息的内存缓存中维护与之相关的信息。如果发生缓存未命中,选择器将使用服务注册表进行查找并缓存数据。缓存也会周期性地被TTL掉,以确保陈旧的数据不会存在。 ### 用法 高速缓存选择器可以通过标志或在创建新服务时进行设置。 作为工具包的标志执行以下操作 ``` micro --selector=cache api ``` 如果调用Init方法,Go-micro服务也可以使用相同的标志。或者,选择器可以用代码设置。 ``` import ( "github.com/micro/go-micro/client" "github.com/micro/go-micro/selector/cache" ) service := micro.NewService( micro.Name("com.example.srv.foo"), ) service.Client().Init(cache.NewSelector()) ```