分布式系统架构:技术栈详解与快速进阶
上QQ阅读APP看书,第一时间看更新

5.4.2 Varnish核心指令之director

director是后端服务器控制组。前文提到通过backend可定义多个后端服务源,那么如何实现负载均衡呢?可以通过director来管理,Varnish提供多种算法,具体如下。

  • round-robin:采用循环的方式依次选择backend。
  • random:根据所设置的权重来选择backend。
  • client:根据请求的客户端属性(IP、cookie、session)来选择backend。
  • hash:根据hash表来选择。
  • dns:根据DNS解析来选择。

1. round-robin

round-robin是Varnish轮询算法,其实现如代码清单5-5所示。

代码清单5-5 Varnish轮询算法

director zachary round-robin {
    {
        .backend=zachary;        // 引用已存在的backend

    }
    {
        .backend=resource;       // 引用已存在的backend

    }
    {
        .backend={               // 定义新的backend
        }

    }
}

Varnish轮询的代理示意如图5-3所示。

109-1

图5-3 Varnish/director轮询代理图

注意

Nginx发送请求到Varnish后,Varnish会根据策略匹配,如已缓存到数据,直接返回,否则会通过轮询方式去后端服务器获取数据。

2. random

Varnish random算法,如代码清单5-6所示。

代码清单5-6 Varnish random算法

director zachary random{        // 随机
    .retries=5;                 // 查找可用后端次数
    {                           
        .backend=zachary;       // 引用已存在的backend
        .weight=6;
    }
    {
        .backend=resource;      // 引用已存在的backend
        .weight=2;              // 类似Nginx权重
    }
    {
        .backend={              // 定义新的backend

        }
        .weight=2;
    }
}

Varnish random的代理示意如图5-4所示。

110-1

图5-4 Varnish/director random的代理图

3. client

Varnish client算法如代码清单5-7所示。

代码清单5-7 Varnish client算法

director zachary client{
    {
        .backend=zachary;       // 引用已存在的backend

    }
    {
        .backend=resource;      // 引用已存在的backend

    }
    {
        .backend={              // 定义新的backend
        }

    }
}

4. hash

通过hash算法,Varnish会选择后端服务器中压力最小的一台服务器来承担消费。Varnish hash算法如代码清单5-8所示。

代码清单5-8 Varnish hash算法

director zachary hash {
    {
        .backend=zachary;       // 引用已存在的backend

    }
    {
        .backend=resource;      // 引用已存在的backend

    }
    {
        .backend={              // 定义新的backend
        }

    }
}

5. dns

Varnish会通过DNS策略引用后端服务器列表。Varnish dns算法如代码清单5-9所示。

代码清单5-9 Varnish DNS算法

director zachary dns {
    .list = {
            .host_header = "www.zachary.com";
            .port = "80";
            .connect_timeout = 0.4;
            "192.168.15.0"/24; # IP段 0~255
            "192.168.16.128"/25;
    }
    .ttl = 5m;                 #查找缓存时间
    .suffix = "xxx.com";       #主机名后缀
}