Приветствую!
Есть исходные данные:
веб-сервис vfs-nginx
, запущенный в 3х экземплярах и зарегистрированный в Consul DNS
Настроенный Angie, который может резолвить SRV записи из Consul.
Апстрим, следующей конфигурации
upstream vfs-nginx {
least_conn;
zone upstream_vfs-nginx 128k;
server service.consul service=vfs-nginx resolve;
}
Можно ли каким-либо образом сделать так, чтобы директива proxy_next_upstream
шла по серверам, которые отрезолвились в SRV записи?
Просто у меня ситуация:
Один из серверов, которые отрезолвились в SRV записи сервера апстрима, отдаёт 404 ошибку. В этом случае мне необходимо переотправить запрос на другие сервера, которые отдала SRV-запись. И пока что я никак не могу добиться такого поведения.
Буду очень признателен за помощь.
VBart
April 2, 2024, 8:55pm
2
Для proxy_next_upstream
нет никакой разницы откуда эти сервера. Были они в конфиге указаны или были получены через DNS запрос.
У вас указана опция http_404
в proxy_next_upstream
?
Хм, тогда всё очень странно.
Опция http_404
, указана:
proxy_pass http://vfs-nginx;
include snippets/proxy.conf;
proxy_next_upstream timeout http_500 http_404 http_403 invalid_header;
expires max;
содержимое proxy.conf:
add_header X-Request-ID $upstream_request_id;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Uid-Got $uid_got;
proxy_set_header X-Uid-Set $uid_set;
proxy_set_header X-Country $geoip2_data_country_code;
proxy_set_header X-Request-ID $request_id;
proxy_http_version 1.1;
proxy_max_temp_file_size 0;
proxy_redirect off;
proxy_read_timeout 240s;
proxy_connect_timeout 10s;
proxy_ignore_client_abort on;
proxy_next_upstream error http_502;
Причем я сейчас переделал upstream на указание конкретных серверов и всё стало работать как надо. Апстрим получился такой:
upstream vfs-nginx {
least_conn;
zone upstream_vfs-nginx 128k;
server 10.1.20.1:25518 max_fails=3 fail_timeout=60s weight=1;
server 10.1.20.2:21591 max_fails=3 fail_timeout=60s weight=1;
server 10.1.20.3:25788 max_fails=3 fail_timeout=60s weight=1;
}
VBart
April 2, 2024, 9:15pm
4
Можно включить debug-лог - там будет видно, что происходит и почему.
Могу предположить, что для SRV записей заданы различные значения priority из-за чего часть серверов попадает в backup-группу.
Проверил в SRV-записях priority и weigth - они одинаковые для всех инстансов:
;; ANSWER SECTION:
vfs-nginx.service.consul. 0 IN SRV 1 1 25788 0a011403.addr.dc1.consul.
vfs-nginx.service.consul. 0 IN SRV 1 1 21591 0a011402.addr.dc1.consul.
vfs-nginx.service.consul. 0 IN SRV 1 1 25518 0a011401.addr.dc1.consul.
Включил debug лог, попробовал воспроизвести проблему, и не увидел в дебаг-логе чтобы angie пытался бы пойти в следующий сервер в апстриме после того как получил от одного сервера в апстриме 404 ошибку:
2024/04/02 21:43:06 [debug] 430873#430873: *3049 http cleanup add: 000055ECF3E56418
2024/04/02 21:43:06 [debug] 430873#430873: *3049 init least conn peer
2024/04/02 21:43:06 [debug] 430873#430873: *3049 get least conn peer, try: 1
2024/04/02 21:43:06 [debug] 430873#430873: *3049 get least conn peer, many
2024/04/02 21:43:06 [debug] 430873#430873: *3049 stream socket 6
2024/04/02 21:43:06 [debug] 430873#430873: *3049 epoll add connection: fd:6 ev:80002005
2024/04/02 21:43:06 [debug] 430873#430873: *3049 connect to 10.1.20.2:21591, fd:6 #3050
2024/04/02 21:43:06 [debug] 430873#430873: *3049 http upstream connect: -2
2024/04/02 21:43:06 [debug] 430873#430873: *3049 posix_memalign: 000055ECF421DBA0:128 @16
2024/04/02 21:43:06 [debug] 430873#430873: *3049 event timer add: 6: 60000:544398031
2024/04/02 21:43:06 [debug] 430873#430873: *3049 http finalize request: -4, "/media/users/123.jpg?" a:1, c:2
2024/04/02 21:43:06 [debug] 430873#430873: *3049 http request count:2 blk:0
2024/04/02 21:43:06 [debug] 430873#430873: *3049 http2 frame complete pos:000055ECF4232EC6 end:000055ECF4232EC6
2024/04/02 21:43:06 [debug] 430873#430873: *3049 http2 frame out: 000055ECF3FF4F08 sid:0 bl:0 len:0
2024/04/02 21:43:06 [debug] 430873#430873: *3049 http2 frame out: 000055ECF3FF4E58 sid:0 bl:0 len:4
2024/04/02 21:43:06 [debug] 430873#430873: *3049 http2 frame out: 000055ECF3FF4DA0 sid:0 bl:0 len:18
2024/04/02 21:43:06 [debug] 430873#430873: *3049 posix_memalign: 000055ECF3EA0780:512 @16
2024/04/02 21:43:06 [debug] 430873#430873: *3049 malloc: 000055ECF4192250:4096
2024/04/02 21:43:06 [debug] 430873#430873: *3049 SSL buf copy: 27
2024/04/02 21:43:06 [debug] 430873#430873: *3049 SSL buf copy: 13
2024/04/02 21:43:06 [debug] 430873#430873: *3049 SSL buf copy: 9
2024/04/02 21:43:06 [debug] 430873#430873: *3049 SSL to write: 49
2024/04/02 21:43:06 [debug] 430873#430873: *3049 SSL_write: 49
2024/04/02 21:43:06 [debug] 430873#430873: *3049 http2 frame sent: 000055ECF3FF4DA0 sid:0 bl:0 len:18
2024/04/02 21:43:06 [debug] 430873#430873: *3049 http2 frame sent: 000055ECF3FF4E58 sid:0 bl:0 len:4
2024/04/02 21:43:06 [debug] 430873#430873: *3049 http2 frame sent: 000055ECF3FF4F08 sid:0 bl:0 len:0
2024/04/02 21:43:06 [debug] 430873#430873: *3049 delete posted event 000055ECF3FF50B0
2024/04/02 21:43:06 [debug] 430873#430873: *3049 http run request: "/media/users/123.jpg?"
2024/04/02 21:43:06 [debug] 430873#430873: *3049 http upstream check client, write event:0, "/media/users/123.jpg"
2024/04/02 21:43:06 [debug] 430873#430873: *3049 http upstream request: "/media/users/123.jpg?"
2024/04/02 21:43:06 [debug] 430873#430873: *3049 http upstream send request handler
2024/04/02 21:43:06 [debug] 430873#430873: *3049 http upstream send request
2024/04/02 21:43:06 [debug] 430873#430873: *3049 http upstream send request body
2024/04/02 21:43:06 [debug] 430873#430873: *3049 chain writer buf fl:1 s:110
2024/04/02 21:43:06 [debug] 430873#430873: *3049 chain writer in: 000055ECF412A490
2024/04/02 21:43:06 [debug] 430873#430873: *3049 writev: 110 of 110
2024/04/02 21:43:06 [debug] 430873#430873: *3049 chain writer out: 0000000000000000
2024/04/02 21:43:06 [debug] 430873#430873: *3049 event timer del: 6: 544398031
2024/04/02 21:43:06 [debug] 430873#430873: *3049 event timer add: 6: 60000:544398034
2024/04/02 21:43:06 [debug] 430873#430873: *3049 http upstream request: "/media/users/123.jpg?"
2024/04/02 21:43:06 [debug] 430873#430873: *3049 http upstream process header
2024/04/02 21:43:06 [debug] 430873#430873: *3049 malloc: 000055ECF4009AE0:4096
2024/04/02 21:43:06 [debug] 430873#430873: *3049 recv: eof:0, avail:-1
2024/04/02 21:43:06 [debug] 430873#430873: *3049 recv: fd:6 303 of 4096
2024/04/02 21:43:06 [debug] 430873#430873: *3049 http proxy status 404 "404 Not Found"
2024/04/02 21:43:06 [debug] 430873#430873: *3049 http proxy header: "Server: nginx/1.25.4"
2024/04/02 21:43:06 [debug] 430873#430873: *3049 http proxy header: "Date: Tue, 02 Apr 2024 21:43:06 GMT"
2024/04/02 21:43:06 [debug] 430873#430873: *3049 http proxy header: "Content-Type: text/html"
2024/04/02 21:43:06 [debug] 430873#430873: *3049 http proxy header: "Content-Length: 153"
2024/04/02 21:43:06 [debug] 430873#430873: *3049 http proxy header: "Connection: close"
2024/04/02 21:43:06 [debug] 430873#430873: *3049 http proxy header done
Может я что-то не то делаю? Буду признателен, если подскажете что еще можно посмотреть.
На всякий случай уточню, что использую последнюю версию Angie.
При этом если я делаю использую не SRV-записи а пишу конкретные сервера в апстриме, то тогда proxy_next_upstream
отрабатывает как надо, в дебаг логе это видно:
2024/04/02 21:50:10 [debug] 431200#431200: *4645 http upstream request: "/media/users/123.jpg?"
2024/04/02 21:50:10 [debug] 431200#431200: *4645 http upstream send request handler
2024/04/02 21:50:10 [debug] 431200#431200: *4645 http upstream send request
2024/04/02 21:50:10 [debug] 431200#431200: *4645 http upstream send request body
2024/04/02 21:50:10 [debug] 431200#431200: *4645 chain writer buf fl:1 s:110
2024/04/02 21:50:10 [debug] 431200#431200: *4645 chain writer in: 000055ECF3E55600
2024/04/02 21:50:10 [debug] 431200#431200: *4645 writev: 110 of 110
2024/04/02 21:50:10 [debug] 431200#431200: *4645 chain writer out: 0000000000000000
2024/04/02 21:50:10 [debug] 431200#431200: *4645 event timer del: 6: 544821945
2024/04/02 21:50:10 [debug] 431200#431200: *4645 event timer add: 6: 60000:544821948
2024/04/02 21:50:10 [debug] 431200#431200: *4645 http upstream request: "/media/users/123.jpg?"
2024/04/02 21:50:10 [debug] 431200#431200: *4645 http upstream process header
2024/04/02 21:50:10 [debug] 431200#431200: *4645 recv: eof:0, avail:-1
2024/04/02 21:50:10 [debug] 431200#431200: *4645 recv: fd:6 303 of 4096
2024/04/02 21:50:10 [debug] 431200#431200: *4645 http proxy status 404 "404 Not Found"
2024/04/02 21:50:10 [debug] 431200#431200: *4645 http proxy header: "Server: nginx/1.25.4"
2024/04/02 21:50:10 [debug] 431200#431200: *4645 http proxy header: "Date: Tue, 02 Apr 2024 21:50:10 GMT"
2024/04/02 21:50:10 [debug] 431200#431200: *4645 http proxy header: "Content-Type: text/html"
2024/04/02 21:50:10 [debug] 431200#431200: *4645 http proxy header: "Content-Length: 153"
2024/04/02 21:50:10 [debug] 431200#431200: *4645 http proxy header: "Connection: close"
2024/04/02 21:50:10 [debug] 431200#431200: *4645 http proxy header done
2024/04/02 21:50:10 [debug] 431200#431200: *4645 http next upstream, 200
2024/04/02 21:50:10 [debug] 431200#431200: *4645 free rr peer 2 2
2024/04/02 21:50:10 [debug] 431200#431200: *4645 close http upstream connection: 6
2024/04/02 21:50:10 [debug] 431200#431200: *4645 event timer del: 6: 544821948
2024/04/02 21:50:10 [debug] 431200#431200: *4645 reusable connection: 0
2024/04/02 21:50:10 [debug] 431200#431200: *4645 free: 000055ECF4224CC0, unused: 48
2024/04/02 21:50:10 [debug] 431200#431200: *4645 get least conn peer, try: 1
2024/04/02 21:50:10 [debug] 431200#431200: *4645 stream socket 6
2024/04/02 21:50:10 [debug] 431200#431200: *4645 epoll add connection: fd:6 ev:80002005
2024/04/02 21:50:10 [debug] 431200#431200: *4645 connect to 10.1.20.1:25518, fd:6 #4648
2024/04/02 21:50:10 [debug] 431200#431200: *4645 http upstream connect: -2
2024/04/02 21:50:10 [debug] 431200#431200: *4645 posix_memalign: 000055ECF4224CC0:128 @16
2024/04/02 21:50:10 [debug] 431200#431200: *4645 event timer add: 6: 60000:544821949
2024/04/02 21:50:10 [debug] 431200#431200: *4645 http upstream request: "/media/users/123.jpg?"
2024/04/02 21:50:10 [debug] 431200#431200: *4645 http upstream send request handler
2024/04/02 21:50:10 [debug] 431200#431200: *4645 http upstream send request
2024/04/02 21:50:10 [debug] 431200#431200: *4645 http upstream send request body
2024/04/02 21:50:10 [debug] 431200#431200: *4645 chain writer buf fl:1 s:110
2024/04/02 21:50:10 [debug] 431200#431200: *4645 chain writer in: 000055ECF3E55600
2024/04/02 21:50:10 [debug] 431200#431200: *4645 writev: 110 of 110
2024/04/02 21:50:10 [debug] 431200#431200: *4645 chain writer out: 0000000000000000
2024/04/02 21:50:10 [debug] 431200#431200: *4645 event timer del: 6: 544821949
2024/04/02 21:50:10 [debug] 431200#431200: *4645 event timer add: 6: 60000:544821950
2024/04/02 21:50:10 [debug] 431200#431200: *4645 http upstream request: "/media/users/123.jpg?"
2024/04/02 21:50:10 [debug] 431200#431200: *4645 http upstream process header
2024/04/02 21:50:10 [debug] 431200#431200: *4645 recv: eof:0, avail:-1
2024/04/02 21:50:10 [debug] 431200#431200: *4645 recv: fd:6 4096 of 4096
2024/04/02 21:50:10 [debug] 431200#431200: *4645 recv: avail:10694
2024/04/02 21:50:10 [debug] 431200#431200: *4645 http proxy status 200 "200 OK"
VBart
April 2, 2024, 11:35pm
7
У меня получилось воспроизвести проблему. Будем разбираться.
VBart
April 3, 2024, 12:51am
8
Похоже проблема наблюдается только в том случае, если в блоке upstream
присутствует только одна директива server
.
В качестве обходного решения могу порекомендовать добавить ещё одну директиву server
. В ней можно указать доменное имя, которое ни во что не резолвится и опцию resolve
, можно указать флаг backup
, можно указать локальный IP адрес и порт, на котором никто не слушает - любой из этих вариантов поможет обойти ошибку. Только нельзя указывать флаг down
- такая директива будет проигнорирована.
1 Like
Спасибо!
Добавил server 127.0.0.1:65535 backup;
и после этого проблема исчезла.
Хорошее обходное решение.
Подскажите еще пожалуйста, а есть ли смысл добавлять параметры max_fails
и fail_timeout
у сервера, который работает с SRV записями? Распространятся ли эти параметры на адреса, которые будут получены от SRV записи? В документации об этом ничего не сказано, поэтому возникает непонимание.
VBart
April 3, 2024, 10:02am
10
Да, распространяются. Спасибо за замечание, попрошу нашего технического писателя доработать документацию.
1 Like
VBart
May 16, 2024, 1:16pm
11