Re: подстановка переменных в имя апстрима.

Ruslan Ermilov ru на nginx.com
Чт Мар 2 12:17:56 UTC 2017


On Wed, Mar 01, 2017 at 11:06:20AM -0500, syswipe wrote:
> Добрый день!
> 
> хочется странного, пока не понимаю, как бы это реализовать красивей.есть
> пачка конфигов, для различных виртуальных хостов. так же есть один общий
> набор локейшенов, который они все инклюдят. локейшенов очень много, они
> одинаковые но ведут на разные апстримы в каждом виртхосте. Упрощенно это
> выглядит следующим образом:
> 
> VHOST1.conf:
> 
> upstream upstream_vhost1_backend {
>    server host1;
>    server host2;
> }
> 
> server {
>   server vhost1;
>   ...
>   set $upstream_backend upstream_vhost1_backend;
>   include common_config;
> }
> 
> VHOST2.conf:
> 
> upstream upstream_vhost2_backend {
>    server host3;
>    server host4;
> }
> 
> server {
>   server vhost2;
>   ...
>   set $upstream_backend upstream_vhost2_backend;
>   include common_config;
> }
> 
> в common_config задается соответствующий локейшн:
> ...
> location /somelocation {
>    proxy_pass http://$upstream_backend;
> }
> 
> тут все хорошо. проблема начинается, когда в common_config нужно задать
> локейшены следующего вида:
> location /somelocation/module1/ {
>    proxy_pass http://$upstream_module1;
> }
> 
> location /somelocation/module2/ {
>    proxy_pass http://$upstream_module2;
> }
> 
> location /somelocation/moduleN/ {
>    proxy_pass http://$upstream_moduleN;
> }
> 
> проблема в том, что количество таких схожих локейшенов может расти и
> хотелось бы конфиг свернуть.
> хочется получить что-то вроде
> 
> location ~ ^/somelocation/module(\d+)/ {
>    proxy_pass http://$upstream_module$1;
> }
> 
> как это сделать по уму?

При использовании переменных в proxy_pass nginx после раскрытия
переменных будет сначала искать среди явно описанных апстримов,
и если у вас будет блок upstream{} с таким именем, он и будет
использоваться.  Никакого DNS resolving'а.  Т.е. вот прямо как
вы и написали, примерно.  Вопрос исключительно в том, как из
переменных получить имя апстрима.  Либо явно, либо через map.
Пример:

http {
    upstream u1 {
	server 127.0.0.1:10001;
    }

    upstream u2 {
	server 127.0.0.1:10002;
    }

    server {
	listen 10001;
	listen 10002;
	return 200 "$server_port\n";
    }

    server {
	listen 8000;
	server_name ~^s(\d)$;

	location / {
	    proxy_pass http://u$1;
	}
    }
}

$ curl -H 'Host: s1' http://127.1:8000
10001
$ curl -H 'Host: s2' http://127.1:8000
10002


Подробная информация о списке рассылки nginx-ru