假如我们有两个服务,A和B,他们分别在深圳和成都都有一个实例,A作为消费者来调用服务提供者B,在轮询负载均衡方式下,那么深圳的A实例的请求将会有一半跑到深圳实例B,另一半跑到成都实例B,深圳和成都相隔千里,仅光速来回就要几十毫秒,而且两个属于不同网段,可能还有其它路由的消耗,最好的办法是深圳A实例优先请求深圳B实例,只有在深圳B实例不可用时才去请求成都B实例。
要解决这个问题,就要解决微服务的区域感知问题——即服务消费者如何感知服务提供者是否在同一个区域,然后利用Ribbon的Zone-Affinity(区域亲和性)来解决。 Ribbon的Zone-Affinity的原理是:服务消费者在获取注册服务的列表时,添加一个filter来过滤注册服务,根据配置选择跟服务消费者在同一个区的服务,这样一般可以降低延迟;如果过滤后的服务正忙或者异常,则停止区域感知。从而可以做到基于实时的服务运行状况,决定是否只选择本区域的服务,当本区域的服务发生故障时,可以快速的切换。
可以通过以下配置项识别实例所在的区域:
eureka.instance.metadata-map.zone=xxx
深圳的服务全部加上:
eureka.instance.metadata-map.zone=sz
成都的服务全部加上:
eureka.instance.metadata-map.zone=cd
这样则可以达到本地优先效果