Суть задачи в том числе и во втором "но": > Второе но: если этот прокси недоступен/не ответил/просто 500-тит, то > сделать fallback опять на локальную node.
то есть если у меня есть: > upstream remote { server 127.0.0.1:8081; } > upstream local { server 127.0.0.1:7070; } > server { listen 8081; return 200 remote\n; } > server { listen 7070; return 200 local\n; } то по заголовку я хожу в remote сервер: > curl -fs -H "X-Some-Header: yes" hamilton.rinet.ru/some_header > remote Если же remote 500-тит, или вообще закоментировать его, то чтобы ходил в local: > curl -fs -H "X-Some-Header: yes" hamilton.rinet.ru/some_header > local и да, эта конструкция ведет себя как надо: > location =/some_header { > proxy_intercept_errors on; > if ($remote) { > proxy_pass http://remote; > error_page 500 502 504 = @local; > } > proxy_pass http://local; > } > location @local { > internal; > proxy_pass http://local; > } Но в большой оригинальной задаче и так уже много if-ов, поэтому и хочется получить решение без использования if-а. В идеале: собственно в виде backup_proto=http :) поскольку эта же задача максимально элегантно решалась через > upstream remote { > server remote; > server local backup; > } пока не появилось требование к https у upstream-а 16.12.17 22:52, Aziz Rozyev пишет: > может я, конечно, не уловил сути задачи, но и без error_page переключается: > > 39 map $http_x_myheader $remote { > 40 "" 0; > 41 "test" 1; > 42 } > 43 > 44 upstream remote_up { > 45 server nginx.org:443; > 46 } > 47 > 48 upstream local_up { > 49 server localhost:7070; > 50 } > > 58 server { > 59 listen 8085; > 60 location / { > > 62 proxy_set_header Host $host; > 63 proxy_set_header Connection ""; > 64 proxy_http_version 1.1; > 65 > 66 if ($remote) { > 67 proxy_pass https://remote_up; > 68 } > 69 proxy_pass http://local_up; > 70 } > 71 } > > 73 server { > 74 listen 7070; > 75 return 200 "OK"; > 76 } > > > [root@tc ~]# curl http://localhost:8085/ > OK > > [root@tc ~]# curl -H 'X-Myheader: test' http://localhost:8085/ > > <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" > "http://www.w3.org/TR/html4/loose.dtd"> > <html><head><meta http-equiv="Content-Type" content="text/html; > charset=utf-8"><link rel=“alternate" > type="application/rss+xml" title="nginx news" > href="http://nginx.org/index.rss"><title>nginx news</title> > [ … ] > > > без if-a что-то не придумал, как обойтись. > > br, > Aziz. > > > > > >> On 16 Dec 2017, at 19:28, Fedor Dikarev <f...@hamilton.rinet.ru> wrote: >> >> Попробовал этот вариант, и без error_page он не переключается на local. >> Но если вписать error_page внутрь if-а, то вроде как работает как нужно. >> Осталось убедить самого себя, что без if-а тут не обойтись. Хотя и очень >> хочется. >> >> 16.12.17 15:21, Aziz Rozyev пишет: >>> а вариант с 2 апстримами не подходит? >>> >>> upstream remote_up { >>> remote_upstream:443; >>> } >>> >>> upstream local_up { >>> localhost:7070; >>> } >>> >>> map $http_x_some_header $remote { >>> “” 0; >>> “default” 1; >>> } >>> >>> if ($remote) { >>> proxy_pass https://remote; >>> } >>> proxy_pass http://local; >>> >>> >>> br, >>> Aziz. >>> >>> >>> >>> >>> >>>> On 16 Dec 2017, at 12:50, Fedor Dikarev <f...@hamilton.rinet.ru> wrote: >>>> >>>> Привет! >>>> >>>> Я тут пытаюсь навести красоту в одном конфиге Nginx-а и что-то пока >>>> совсем беда :-( >>>> >>>> Формулировка, правда, изначально довольно извращенная: >>>> есть Nginx, по-умолчанию проксирует запрос в локально работающую node. >>>> Но если в запросе есть заголовок X-Some-Header, то запрос >>>> нужно спроксировать на другой сервер по https. >>>> Второе но: если этот прокси недоступен/не ответил/просто 500-тит, то >>>> сделать fallback опять на локальную node. >>>> >>>> первая мысль была: >>>> map $http_x_some_header $use_backend { >>>> "" http://localhost:7070; >>>> default https://remote_upstream; >>>> } >>>> upstream remote_upstream { >>>> server remote:443; >>>> server localhost:7070 backup; >>>> } >>>> >>>> но локальный сервер не https, и все не очень красиво :-( >>>> думал тут еще поднять на этом же nginx локальный https на порту 7073, >>>> проксировать в него как backup, но тут начинаются сложности с >>>> сертификатами. >>>> >>>> Опять же думал о другом варианте: >>>> proxy_pass $use_backend; >>>> error_page 500 502 504 = @fallback_local_node; >>>> >>>> location @fallback_local_node { >>>> internal; >>>> proxy_pass http://localhost:7070; >>>> } >>>> >>>> но тут получается что если заголовка не было, node ответил 502, то мы >>>> пойдем в node еще раз. Не то, чтобы прям ужас, но некрасиво >>>> получается... >>>> >>>> Может кто подскажет тут красивое решение? >>>> >>>> Ну и как feature request: может можно добавить к опции backup для >>>> директивы server в upstream еще какой-нибудь параметр backup_proto=http >>>> или другую опцию backup_http, чтобы при переключении на backup сервер >>>> менялся и протокол обращения. > > _______________________________________________ > nginx-ru mailing list > nginx-ru@nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-ru > _______________________________________________ nginx-ru mailing list nginx-ru@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-ru