• 路由
    • 随机 {#random_selector}
    • 轮询 {#roundrobin_selector}
    • WeightedRoundRobin {#weighted_selector}
    • 网络质量优先 {#ping_selector}
    • 一致性哈希 {#hash_selector}
    • 地理位置优先 {#geo_selector}
    • 定制路由规则 {#user_selector}

    路由

    在大型的微服务系统中,我们会为同一个服务部署多个节点, 以便服务可以支持大并发的访问。它们可能部署在同一个数据中心的多个节点,或者多个数据中心中。

    那么, 客户端该如何选择一个节点呢? rpcx通过 Selector来实现路由选择, 它就像一个负载均衡器,帮助你选择出一个合适的节点。

    rpcx提供了多个路由策略算法,你可以在创建XClient来指定。

    注意,这里的路由是针对 ServicePathServiceMethod的路由。

    随机 {#random_selector}

    示例: random

    从配置的节点中随机选择一个节点。

    最简单,但是有时候单个节点的负载比较重。这是因为随机数只能保证在大量的请求下路由的比较均匀,并不能保证在很短的时间内负载是均匀的。

    轮询 {#roundrobin_selector}

    示例: roundrobin

    使用轮询的方式,依次调用节点,能保证每个节点都均匀的被访问。在节点的服务能力都差不多的时候适用。

    WeightedRoundRobin {#weighted_selector}

    示例: weighted

    使用Nginx 平滑的基于权重的轮询算法。

    比如如果三个节点abc的权重是{ 5, 1, 1 }, 这个算法的调用顺序是 { a, a, b, a, c, a, a },
    相比较 { c, b, a, a, a, a, a }, 虽然权重都一样,但是前者更好,不至于在一段时间内将请求都发送给a

    网络质量优先 {#ping_selector}

    示例: ping

    首先客户端会基于ping(ICMP)探测各个节点的网络质量,越短的ping时间,这个节点的权重也就越高。但是,我们也会保证网络较差的节点也有被调用的机会。

    假定t是ping的返回时间, 如果超过1秒基本就没有调用机会了:

    • weight=191 if t <= 10
    • weight=201 -t if 10 < t <=200
    • weight=1 if 200 < t < 1000
    • weight=0 if t >= 1000

    一致性哈希 {#hash_selector}

    示例: hash

    使用 JumpConsistentHash 选择节点, 相同的servicePath, serviceMethod 和 参数会路由到同一个节点上。 JumpConsistentHash 是一个快速计算一致性哈希的算法,但是有一个缺陷是它不能删除节点,如果删除节点,路由就不准确了,所以在节点有变动的时候它会重新计算一致性哈希。

    地理位置优先 {#geo_selector}

    示例: geo

    如果我们希望的是客户端会优先选择离它最新的节点, 比如在同一个机房。
    如果客户端在北京, 服务在上海和美国硅谷,那么我们优先选择上海的机房。

    它要求服务在注册的时候要设置它所在的地理经纬度。

    如果两个服务的节点的经纬度是一样的, rpcx会随机选择一个。

    比必须使用下面的方法配置客户端的经纬度信息:

    1. func (c *xClient) ConfigGeoSelector(latitude, longitude float64)

    定制路由规则 {#user_selector}

    示例: customized

    如果上面内置的路由规则不满足你的需求,你可以参考上面的路由器自定义你自己的路由规则。

    曾经有一个网友提到, 如果调用参数的某个字段的值是特殊的值的话,他们会把请求路由到一个指定的机房。这样的需求就要求你自己定义一个路由器,只需实现实现下面的接口:

    1. type Selector interface {
    2. Select(ctx context.Context, servicePath, serviceMethod string, args interface{}) string
    3. UpdateServer(servers map[string]string)
    4. }

    -Select: defines the select algorithm.
    -UpdateServer: clients init the nodes and update if nodes change.