วิธีการเขียน DRY โมดูลาร์ nginx conf (reverse proxy) ด้วยตำแหน่งที่ระบุชื่อ


25

ฉันใช้ nginx ส่วนใหญ่เป็นพร็อกซี cachining แบบย้อนกลับหน้าแอพพลิเคชั่น gunicon / mod_wsgi หลายตัวและแน่นอนกับเซิร์ฟเวอร์แบบคงที่ไฟล์

ฉันพบว่าเร็ว nginx confs ของฉันเป็นไปไม่ได้ที่จะรักษา; ปัญหาคือฉันมีรูปแบบไม่กี่อย่างที่คล้ายกัน (หรือเหมือนกัน) แต่ฉันไม่สามารถจัดการเพื่อให้มันสะอาด

หนึ่งในปัญหาที่ใหญ่ที่สุดที่ฉันมีคือฉันชอบที่จะใช้สถานที่ที่มีชื่อเป็นวิธีการจัดกลุ่มชุดของ confs เช่น

location @django_modwsgi {
    include proxy.conf;
    proxy_pass  http://127.0.0.1:8080;        
}

location @django_gunicorn {
    include proxy.conf; # this could also be included directly in the server {} block?
    proxy_pass  http://gunicorn_builder;
}

NB ปัญหาไม่ได้มีทั้ง gunicorn และ wsgi นั่นเป็นเพียงตัวอย่าง อีกหนึ่งคือ:

location @namedlocation_1 {
     some cache settings;
     some cache_key settings;
     ignore some headers;
     expires;
     proxy_pass
}

location @namedlocation_2 {
     other cache settings;
     other cache_key settings;
     ignore some headers;
     expires;
     proxy_pass
}

แต่การโทรไปยังตำแหน่งที่ระบุชื่อวิธีเดียวที่ฉันพบคือ:

location /somelocation {
    try_files $uri @named_location;
}

สิ่งนี้รู้สึกไม่ถูกต้องฉันไม่ต้องการให้ nginx ไปหาไฟล์สแตติกฉันต้องการให้มันไปยังตำแหน่งที่ระบุชื่อโดยตรง! มีวิธี "เรียก" ตำแหน่งที่ตั้งชื่อโดยตรงหรือไม่!

อีกวิธีที่ฉันคิดว่าฉันสามารถไปได้ในที่แห้งคือinclude...

location /somelocation {
    include django_unicorn.conf;
}

แต่นี่เป็นวิธีที่ดีที่จะทำหรือไม่ มันฟังดูโอเคสำหรับการตั้งค่าทั่วไป (เช่นพร็อกซี่) แต่ก็ไม่สามารถอ่านได้มากจนต้องเปิดไฟล์ที่แตกต่างกันเพื่อให้ได้ข้อมูลที่ครบถ้วน

นอกจากนี้ในบางกรณีฉันสามารถจัดกลุ่มสถานที่บางแห่งด้วย regexp แต่ฉันชอบที่จะทำเช่นนั้นเฉพาะเมื่อพวกเขามีความสัมพันธ์เชิงตรรกะไม่เพียง แต่จะสามารถตั้งค่าทั่วไปในบล็อกเดียวกันได้

คำถาม

มีวิธีปฏิบัติที่ดีที่สุด "ทางการ" ในการเขียนดีกำหนดค่า nginx DRY หรือไม่

ฉันชอบที่จะหารูปแบบเช่น:

location / {
    common confs
    try_files $uri @name_location
}

** แต่ฉันจะเขียนเคสเฉพาะสำหรับสถานที่ต่างกันได้อย่างไร **

ฉันสามารถเพิ่มสถานที่หลายแห่งด้วยส่วนที่ไม่ธรรมดาของ conf และสถานที่ทั่วไปใน @named_location ได้หรือไม่

location /1/ {
    some cache expire settings;
    NOTHING ELSE;
}

location /2/ {
    some other cache expire settings;
    NOTHING ELSE;
}

location / {
    common settings
    try_files
}

location @named_location {
    other common settings for this named location only
    proxy_pass
}

เมื่อฉันมี url ที่แตกต่างกันชี้ไปที่ทรัพยากรเดียวกันฉันก็สามารถเขียนใหม่ได้หรือไม่?

location /1/ {
    rewrite  ^  /3/  last;
}

location /2/ {
    rewrite ^   /4/  last; 
}

location / {
    common settings
    try_files
}

location @named_location {
    other common settings for this named location only
    proxy_pass
}

หรือควรจัดกลุ่มทั้งหมดไว้ในที่เดียวหรือไม่

location / {
    rewrite ^/1/$  /3/  last;
    rewrite ^/2/$   /4/  last; 

    common settings
    try_files
}

location @named_location {
    other common settings for this named location only
    proxy_pass
}

ที่เกี่ยวข้อง

ฉันไม่สามารถหาอะไรมากในรายการส่งเมลแม้แต่น้อยในวิกิ

โปรดทราบว่านี่คือ / ไม่ / เหมือนคำถามNGinx วิธีปฏิบัติที่ดีที่สุด - เป็นคำถามทั่วไป

อีกอันหนึ่งมีความเกี่ยวข้องมากกว่า: ฉันจะลองกำหนดค่า Nginx นี้ได้อย่างไร

คำตอบ:


6

ฉันแก้ไขปัญหาที่คล้ายกันโดยใช้คุณสมบัติแผนที่ nginx

สร้างชื่อโดเมนก่อนเพื่อทำแผนที่แบ็กเอนด์:

map $http_host $backend {
  myhost1.tld 192.168.1.100;
  myhost2.tld 192.168.1.101;
  default     upstream_pool1;
}

จากนั้นใช้แผนที่ในที่ตั้ง

location / {
  common settings
  proxy_pass $backend; 
}

คุณสามารถใช้ตัวแปรอื่นใดแทน $ http_host ดูคู่มือนี้: http://nginx.org/en/docs/http/ngx_http_map_module.html


ฉันไม่รู้เกี่ยวกับmap- หรืออย่างน้อยฉันไม่เคยสังเกตและคิดว่าฉันสามารถใช้สิ่งนี้ได้ ... ขอให้ฉันไตร่ตรองเรื่องนี้ให้มากขึ้นและดูว่าฉันมีคำถาม / ความคิดเห็นเพิ่มเติมหรือไม่!
Stefano

2

มีวิธี "เรียก" ตำแหน่งที่ตั้งชื่อโดยตรงหรือไม่!

มีอีกวิธีหนึ่งอย่างน้อยคือ:

location /somelocation {
    error_page 418 = @named_location;
    return 418;
}

พบว่าแฮ็คนี้ทำให้ nginx ลืมเช่น "proxy_read_timeout" ตั้งอยู่ใน "/ somelocation" เมื่อ nginx "return" -s เป็น "@named_location"
เดนิส Ryzhkov

1
418 ฉันเป็นกาน้ำชาจริงเหรอ?
Walf

0

คำสั่งบางอย่างสามารถใช้ได้ทั้งกับบริบท "เซิร์ฟเวอร์" และ "ตำแหน่ง" ทำให้เป็นแบบแห้ง:

# The variables below are evaluated on each request,
# allowing to DRY configs of locations.
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Real-IP $remote_addr;

location /special {
    proxy_send_timeout 10m;
    proxy_read_timeout 10m;
    proxy_pass http://pool;
}

location / {
    proxy_pass http://pool;
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.