Назад | Перейти на главную страницу

циклический директор ВСЕГДА направляет запрос в один и тот же бэкэнд

Я установил один сервер с Varnish в качестве балансировщика нагрузки и два сервера с nginx / unicorn / sinatra для демонстрационных целей. Доступны все три сервера! Мой vcl файл с лаком:

backend web2 {
  .host = "10.169.42.243";
  .port = "80";
  .probe = {
    .url = "/";
    .interval = 5s;
    .timeout = 1 s;
    .window = 5;
    .threshold = 3;
  }
}

backend web1 {
    .host = "10.47.137.196";
    .port = "80";
    .probe = {
      .url = "/";
      .interval = 5s;
      .timeout = 1 s;
      .window = 5;
      .threshold = 3;
    }
  }

director demo round-robin {
    { .backend = web1; }
    { .backend = web2; }
}

sub vcl_recv {
    set req.backend = demo; 
}

Проверка работоспособности также хороша для обоих бэкэндов:

0 Backend_health - web1 Still healthy 4--X-RH 5 3 5 0.004336 0.003621 HTTP/1.1 200 OK
0 Backend_health - web2 Still healthy 4--X-RH 5 3 5 0.003388 0.004753 HTTP/1.1 200 OK

Мое приложение Sinatra просто показывает IP хоста: требуется «rubygems», требуется «sinatra / base», требуется «сокет»

class MyApp < Sinatra::Base

  get '/' do
    headers \
      "Cache-Control"   => "no-cache, no-store, must-revalidate",
      "Pragma"   => "no-cache",
      "Expires"   => "0"
    'Hello, nginx and unicorn! - ' + Socket.gethostname
  end

end

Но когда я получаю доступ к адресу балансировщика нагрузки, я всегда показываю один и тот же IP-адрес. Я могу посетить оба бэкэнда вручную и увидеть их уникальные IP-адреса.

Я пропустил что-то очевидное?

Изменить: я также пробовал curl с машины Varnish и можете видеть правильный ответ от бэкэндов. При выключении одного из веб-серверов Varnish будет использовать другой. Но разве это не должно происходить по каждому запросу?

Edit2: Хорошо, я провел больше исследований с помощью файлов nginx access_log, и я мог видеть, что Varnish не выполняет новый поиск для каждого запроса. Я думал, что с данными заголовками Varnish не кэширует содержимое. Что за ошибка?

Вы не упомянули, какую версию Varnish вы используете. Если мне не изменяет память, Лак не всегда уважал Cache-Control заголовок. Электрический ток builtin.vcl хотя проверяет заголовок.

Попробуйте добавить в свой default.vcl и посмотрите, имеет ли это значение:

sub vcl_fetch {

  # Varnish determined the object was not cacheable
  if (!(beresp.ttl > 0s)) {
    set beresp.http.X-Cacheable = "NO:Not Cacheable";
    return(hit_for_pass);
  }
  elseif (req.http.Cookie) {
    set beresp.http.X-Cacheable = "NO:Got cookie";
    return(hit_for_pass);
  }
  elseif (beresp.http.Cache-Control ~ "private") {
    set beresp.http.X-Cacheable = "NO:Cache-Control=private";
    return(hit_for_pass);
  }
  elseif (beresp.http.Cache-Control ~ "no-cache" || beresp.http.Pragma ~ "no-cache") {
    set beresp.http.X-Cacheable = "Refetch forced by user";
    return(hit_for_pass);
  # You are extending the lifetime of the object artificially
  }
  elseif (beresp.ttl < 1s) {
    set beresp.ttl   = 5s;
    set beresp.grace = 5s;
    set beresp.http.X-Cacheable = "YES:FORCED";
  # Varnish determined the object was cacheable
  } else {
    set beresp.http.X-Cacheable = "YES";
  }
}

VCL, приведенный выше, предназначен для Varnish 3.0, и он проверяет различные условия, которые должны препятствовать кэшированию содержимого, возвращает hit_for_pass для не кэшируемых элементов и устанавливает X-Cacheable заголовок соответственно.