nginx বিপরীত প্রক্সি - প্রবাহের এ, তারপরে বি, তারপরে আবার এ চেষ্টা করুন


22

আমি প্রচুর সংখ্যক ব্যাকএন্ড সার্ভার সহ বিপরীত প্রক্সি হিসাবে এনগিনেক্স সেট আপ করার চেষ্টা করছি। আমি অন-ডিমান্ডে (প্রথম অনুরোধটি আসবে) ব্যাকেন্ডগুলি শুরু করতে চাই, সুতরাং আমার কাছে একটি নিয়ন্ত্রণ প্রক্রিয়া রয়েছে (এইচটিটিপি অনুরোধ দ্বারা নিয়ন্ত্রিত) যা অনুরোধটি পেয়েছে তার উপর নির্ভর করে ব্যাকএন্ড শুরু হয়।

আমার সমস্যা এটি করার জন্য এনগিনেক্স কনফিগার করছে। আমার এখন পর্যন্ত যা আছে তা এখানে:

server {
    listen 80;
    server_name $DOMAINS;

    location / {
        # redirect to named location
        #error_page 418 = @backend;
        #return 418; # doesn't work - error_page doesn't work after redirect

        try_files /nonexisting-file @backend;
    }

    location @backend {
        proxy_pass http://$BACKEND-IP;
        error_page 502 @handle_502; # Backend server down? Try to start it
    }

    location @handle_502 { # What to do when the backend server is not up
        # Ping our control server to start the backend
        proxy_pass http://127.0.0.1:82;
        # Look at the status codes returned from control server
        proxy_intercept_errors on;
        # Fallback to error page if control server is down
        error_page 502 /fatal_error.html;
        # Fallback to error page if control server ran into an error
        error_page 503 /fatal_error.html;
        # Control server started backend successfully, retry the backend
        # Let's use HTTP 451 to communicate a successful backend startup
        error_page 451 @backend;
    }

    location = /fatal_error.html {
        # Error page shown when control server is down too
        root /home/nginx/www;
        internal;
    }
}

এটি কাজ করে না - nginx নিয়ন্ত্রণ সার্ভার থেকে ফিরে আসা কোনও স্থিতি কোডগুলি উপেক্ষা করে বলে মনে হচ্ছে। অবস্থানের কোনও error_pageনির্দেশিকা @handle_502কাজ করে না এবং 451 কোডটি ক্লায়েন্টকে যেমন পাঠানো হয় তেমন।

আমি এটির জন্য অভ্যন্তরীণ এনজিনেক্স পুনর্নির্দেশটি ব্যবহার করার চেষ্টা ছেড়ে দিয়েছি এবং একই জায়গায় 307 পুনর্নির্দেশের জন্য কন্ট্রোল সার্ভারকে সংশোধন করার চেষ্টা করেছি (যাতে ক্লায়েন্ট একই অনুরোধটি আবার চেষ্টা করবে তবে এখন ব্যাকএন্ড সার্ভার শুরু হয়ে যাবে)। যাইহোক, এখন nginx ব্যাক-এন্ড অনুরোধ প্রচেষ্টা (502) থেকে প্রাপ্ত একটিটির সাথে স্ট্যাটাস কোডটি বোকামি দিয়ে ওভাররাইট করছে, তবুও নিয়ন্ত্রণ সার্ভার "অবস্থান" শিরোনাম প্রেরণ করছে। আমি অবশেষে ত্রুটি_পৃষ্ঠা রেখায় পরিবর্তন করে এটি "কাজ করে" পেয়েছিerror_page 502 =307 @handle_502;, এইভাবে সমস্ত কন্ট্রোল সার্ভারের জবাবগুলি ক্লায়েন্টকে 307 কোড দিয়ে ফেরত পাঠাতে বাধ্য করে। এটি অত্যন্ত হ্যাকি এবং অবাঞ্ছিত, কারণ 1) কন্ট্রোল সার্ভারের প্রতিক্রিয়ার উপর নির্ভর করে এনজিনেক্সের পরবর্তী কী করা উচিত তার উপর কোনও নিয়ন্ত্রণ নেই (আদর্শভাবে আমরা কেবল নিয়ন্ত্রণ সার্ভারের সাফল্যের খবর জানালে কেবল ব্যাকএন্ডে আবার চেষ্টা করতে চাই), এবং ২) সমস্ত এইচটিটিপি নয় ক্লায়েন্টরা HTTP পুনঃনির্দেশগুলি সমর্থন করে (যেমন কার্ল ব্যবহারকারী এবং libcurl- ব্যবহার অ্যাপ্লিকেশনগুলি নিম্নলিখিত পুনঃনির্দেশগুলি স্পষ্টভাবে সক্ষম করার প্রয়োজন)।

প্রবাহের সার্ভার এ, তারপরে বি, তারপরে বি, তারপরে আবার (আদর্শভাবে, কেবল যখন বি নির্দিষ্ট স্থিতির কোড ফেরায়) প্রিন্সি করার চেষ্টা করার জন্য এনগিনেক্স পাওয়ার উপযুক্ত উপায় কী?

উত্তর:


20

গুরুত্বপূর্ণ দিক:

  • upstreamফেইলওভারের জন্য ব্লকগুলি নিয়ে বিরক্ত করবেন না , যদি একটি সার্ভারকে পিং করা অন্য একটিটিকে নিয়ে আসে - প্রথম সার্ভারটি আবার চালু হয়েছে বলে এনজিনেক্স (কমপক্ষে, FOSS সংস্করণ নয়) বলার উপায় নেই। nginx কোনো সত্ত্বেও প্রথম অনুরোধে অনুক্রমে সার্ভার চেষ্টা করবে, কিন্তু না ফলো-আপ অনুরোধ, backup, weightবা fail_timeoutসেটিংস।
  • আপনার নামকরণ করা অবস্থানগুলি ব্যবহার করে ফেলওভার বাস্তবায়ন করার সময় আপনাকে সক্ষম করতে হবেrecursive_error_pageserror_page
  • proxy_intercept_errorsআপস্ট্রিম সার্ভার থেকে প্রেরিত ত্রুটি কোডগুলি পরিচালনা করতে সক্ষম করুন ।
  • =সিনট্যাক্স (যেমন error_page 502 = @handle_502;) সঠিকভাবে নামে অবস্থানে ত্রুটি কোডের হ্যান্ডেল করতে প্রয়োজন হয়। যদি =ব্যবহার না করা হয় তবে এনগিনেক্স আগের ব্লক থেকে ত্রুটি কোডটি ব্যবহার করবে।

আসল উত্তর / গবেষণা লগ অনুসরণ করুন:


আমি এখানে একটি আরও ভাল কাজ খুঁজে পেয়েছি, যা একটি ক্লায়েন্ট পুনর্নির্দেশ প্রয়োজন হয় না যেহেতু এটি একটি উন্নতি:

upstream aba {
    server $BACKEND-IP;
    server 127.0.0.1:82 backup;
    server $BACKEND-IP  backup;
}

...

location / {
    proxy_pass http://aba;
    proxy_next_upstream error http_502;
}

তারপরে, কন্ট্রোল সার্ভারকে "সাফল্য" তে 502 ফিরিয়ে আনার জন্য আশা করুন এবং কোডটি কখনই ব্যাকেন্ডের মাধ্যমে ফিরে আসে না।


আপডেট: এনজিনেক্স upstreamব্লকে প্রথম প্রবেশটিকে নীচে হিসাবে চিহ্নিত করে রাখে , সুতরাং এটি ক্রমাগত অনুরোধের ভিত্তিতে সার্ভারগুলি চেষ্টা করে না। আমি weight=1000000000 fail_timeout=1প্রথম প্রবেশে কোনও প্রভাব ছাড়াই যুক্ত করার চেষ্টা করেছি । এখনও অবধি আমি কোনও সমাধান পাইনি যা কোনও ক্লায়েন্টকে পুনর্নির্দেশের সাথে জড়িত না।


সম্পাদনা: আর একটি জিনিস আমি জানতাম যে আমি জানতাম - error_pageহ্যান্ডলারের কাছ থেকে ত্রুটি স্থিতি পেতে , এই বাক্য গঠনটি ব্যবহার করুন: error_page 502 = @handle_502;- যে চিহ্নটির সমান চিহ্ন হ্যান্ডলারের কাছ থেকে ত্রুটির স্থিতি অর্জনের জন্য এনজিনেক্সকে সৃষ্টি করবে।


সম্পাদনা করুন: এবং আমি এটি কাজ করেছিলাম! error_pageউপরের ফিক্স ছাড়াও , প্রয়োজনীয় সমস্ত কিছু সক্ষম করা ছিল recursive_error_pages!


1
আমার জন্য proxy_next_upstreamকৌতুকটি করেছেন (ভাল আমার পরিস্থিতি আপনার মতো জটিল ছিল না), আমি কেবলমাত্র এনগিনেক্সটি চেয়েছিলাম পরবর্তী কোনও সার্ভার চেষ্টা করে যদি কোনও ত্রুটি ঘটে তবে এইভাবে আমাকে যুক্ত করতে হয়েছিল proxy_next_upstream error timeout invalid_header non_idempotent;( non_idempotent, কারণ আমি POSTঅনুরোধগুলি মূলত ফরওয়ার্ড করতে চাই )।
ফিলিপ

1

আপনি নিম্নলিখিত মত কিছু চেষ্টা করতে পারেন

upstream backend {
    server a.example.net;
    server b.example.net backup;
}

server {
    listen   80;
    server_name www.example.net;

    proxy_next_upstream error timeout http_502;

    location / {
        proxy_pass http://backend;
        proxy_redirect      off;
        proxy_set_header    Host              $host;
        proxy_set_header    X-Real-IP         $remote_addr;
        proxy_set_header    X-Forwarded-for   $remote_addr;
    }

}

nginx a.example.netএকই অনুরোধে একবার ব্যর্থ হওয়ার পরে আবার চেষ্টা করবে না । এটি সংযোগের চেষ্টা করার সময় ক্লায়েন্টকে ত্রুটিটি প্রেরণ করবে b.example.net, যা আমি কন্ট্রোল সার্ভারেও প্রক্সিং বাস্তবায়ন না করা হলে তারা যা প্রত্যাশা করেছিল তা ঘটবে না।
ভ্লাদিমির পানতেলিভ

এবং পরবর্তী পরিস্থিতিতে আপনার কনফিগারেশনের সাথে কী থাকবে: প্রবাহের কাছে অনুরোধ একটি রিটার্ন ব্যর্থ হবে, প্রবাহের বি রিটার্ন ব্যর্থ হবে, তারপরে আমরা আবার উজানের এ চেষ্টা করব এবং ব্যর্থও হব (502)?
ALex_hha

আপস্ট্রিম বি হ'ল কন্ট্রোল সার্ভার। এর উদ্দেশ্য হ'ল নিশ্চিত করা যে ওপরে প্রবাহের জন্য পরবর্তী অনুরোধটি সফল হবে। লক্ষ্যটি হ'ল উজানের এটিকে প্রবাহিত করা, যদি এটি প্রবাহের বি চেষ্টা করে ব্যর্থ হয়, যদি এটি "সফল" হয় (আমাদের সাফল্যের "অভ্যন্তরীণ কনভেনশনটি ব্যবহার করে"), আবার প্রবাহ এটিকে আবার চেষ্টা করুন। যদি আমার প্রশ্নটি যথেষ্ট পরিমাণে পরিষ্কার না হয়, তবে আমি কীভাবে এটি উন্নত করতে পারি তা আমাকে জানান।
ভ্লাদিমির পানতেলিভ

হুম, ধরে নেওয়া যাক আপ স্ট্রিম এ ডাউন রয়েছে, যেমন কিছু হার্ডওয়্যার ইস্যু। আপ স্ট্রিম বি কী করবে? এটি কি ক্লায়েন্টের অনুরোধের প্রতিক্রিয়া ফিরিয়ে দিতে সক্ষম?
ALex_hha

এই সমস্যাটি হার্ডওয়্যার ব্যর্থতার জন্য ব্যর্থতা সম্পর্কিত নয়। এই সমস্যাটি অন-চাহিদা অনুসারে প্রবাহের ব্যাকেন্ডগুলি শুরু করার বিষয়ে। যদি কন্ট্রোল সার্ভার (আপস্ট্রিম বি) ব্যাকএন্ড (আপস্ট্রিম এ )টিকে পুনরায় সক্রিয় করতে না পারে, তবে আদর্শভাবে ব্যবহারকারীর একটি উপযুক্ত ত্রুটি বার্তা পাওয়া উচিত, তবে এটি যে সমস্যাটি আমি সমাধান করার চেষ্টা করছি তা নয় - সমস্যাটি আবার চেষ্টা করার জন্য এনজিন্স পেয়ে যাচ্ছে একই অনুরোধের মধ্যে আবার বি এর পরে।
ভ্লাদিমির পানতেলিভ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.