লিনাক্সে সর্বাধিক সংখ্যক টিসিপি / আইপি সংযোগ বাড়ানো


214

আমি একটি সার্ভার প্রোগ্রাম করছি এবং মনে হচ্ছে আমার সংযোগগুলির সংখ্যা সীমাবদ্ধ হচ্ছে যেহেতু আমি "সীমাহীন" এ সংযোগের সংখ্যা নির্ধারণ করে দিলেও আমার ব্যান্ডউইথ স্যাচুরেট হচ্ছে না।

আমার উবুন্টু লিনাক্স বাক্স একসাথে যে সংযোগগুলি খুলতে পারে সেগুলি আমি কীভাবে বাড়াতে বা অপসারণ করতে পারি? ওএস কি এটিকে সীমাবদ্ধ করে, বা এটি রাউটার বা আইএসপি? নাকি এটা অন্য কিছু?


2
@ সফটওয়্যার বানর: আমি যাইহোক এটির উত্তর দিয়েছি কারণ আমি আশা করি এটি ভবিষ্যতে কোনও সার্ভার লেখার ক্ষেত্রে কারও পক্ষে কার্যকর হতে পারে।
ডারোবার্ট

1
@ডারবার্ট: আমি এটি +1 দেখেছি। আসলে, আমার আগের মন্তব্যের পরে আমারও একই চিন্তা ছিল, তবে ভেবেছিলাম মন্তব্যটি দাঁড়াতে দেব।
লরেন্স ডল

উত্তর:


395

কিছুটা আলাদাভাবে হলেও, সংযোগের সর্বাধিক সংখ্যা ক্লায়েন্ট এবং সার্ভার উভয় পক্ষেই নির্দিষ্ট সীমা দ্বারা প্রভাবিত হয়।

ক্লায়েন্টের পক্ষে: এফেরমাল পোর্টের পরিধি বাড়ান, এবং কমিয়ে দিনtcp_fin_timeout

ডিফল্ট মানগুলি খুঁজে পেতে:

sysctl net.ipv4.ip_local_port_range
sysctl net.ipv4.tcp_fin_timeout

এফেরমাল পোর্ট পরিসীমা একটি হোস্ট একটি নির্দিষ্ট আইপি ঠিকানা থেকে সর্বাধিক সংখ্যক আউটবাউন্ড সকেট তৈরি করতে পারে def fin_timeoutন্যূনতম সময় এই সকেট থাকবে সংজ্ঞায়িত TIME_WAITরাজ্য (একবার ব্যবহার হওয়ার পর অব্যবহারযোগ্য)। সাধারণ সিস্টেমের ডিফল্টগুলি হ'ল:

  • net.ipv4.ip_local_port_range = 32768 61000
  • net.ipv4.tcp_fin_timeout = 60

এর মূল অর্থ হল আপনার সিস্টেমটি (61000 - 32768) / 60 = 470প্রতি সেকেন্ডে সকেটের চেয়ে ধারাবাহিকভাবে গ্যারান্টি দিতে পারে না । আপনি যদি এতে সন্তুষ্ট না হন তবে আপনি এটি বাড়িয়ে শুরু করতে পারেন port_range। পরিসীমা নির্ধারণ করা 15000 61000আজকাল বেশ সাধারণ। আপনি আরও কমিয়ে প্রাপ্যতা বৃদ্ধি করতে পারেন fin_timeout। ধরুন আপনি উভয়ই করেন, আপনার প্রতি সেকেন্ডে 1500 এর বেশি আউটবাউন্ড সংযোগগুলি আরও তাত্ক্ষণিকভাবে দেখা উচিত।

মান পরিবর্তন করতে :

sysctl net.ipv4.ip_local_port_range="15000 61000"
sysctl net.ipv4.tcp_fin_timeout=30

উপরেরগুলি প্রতি সেকেন্ডে আউটবাউন্ড সংযোগ তৈরির জন্য সিস্টেমের ক্ষমতাকে প্রভাবিতকারী কারণগুলি হিসাবে ব্যাখ্যা করা উচিত নয়। তবে এর পরিবর্তে এই উপাদানগুলি "ক্রিয়াকলাপ" এর বৃহত্তর সময়কালের জন্য একটি টেকসই উপায়ে সাম্প্রতিক সংযোগগুলি পরিচালনা করার সিস্টেমের ক্ষমতাকে প্রভাবিত করে।

জন্য একটি টিপিক্যাল লিনাক্স বক্স ডিফল্ট Sysctl মান tcp_tw_recycle& tcp_tw_reuseহবে

net.ipv4.tcp_tw_recycle=0
net.ipv4.tcp_tw_reuse=0

এগুলি "ব্যবহৃত" সকেট (ওয়েট স্টেটে) থেকে সংযোগের অনুমতি দেয় না এবং সকেটগুলিকে সম্পূর্ণ time_waitচক্র স্থায়ী করতে বাধ্য করে । আমি সেট করার পরামর্শ দিচ্ছি:

sysctl net.ipv4.tcp_tw_recycle=1
sysctl net.ipv4.tcp_tw_reuse=1 

এটি time_waitরাজ্যে সকেটগুলির দ্রুত সাইক্লিং এবং সেগুলি পুনরায় ব্যবহারের অনুমতি দেয়। তবে আপনি এই পরিবর্তনটি করার আগে নিশ্চিত হয়ে নিন যে এই সকেটগুলির জন্য প্রয়োজনীয় অ্যাপ্লিকেশনটির জন্য আপনি যে প্রোটোকলগুলি ব্যবহার করবেন তা তার সাথে বিরোধ নয়। এর প্রভাবগুলি বোঝার জন্য ভিনসেন্ট বার্নাতের কাছ থেকে "টিসিপি টাইম-ওয়েটের সাথে মোকাবিলা" পোস্টটি অবশ্যই নিশ্চিত করুন । net.ipv4.tcp_tw_recycle যেমন একই ন্যাট ডিভাইস পিছনে দুটি ভিন্ন কম্পিউটার থেকে সংযোগ হ্যান্ডেল করা হবে না বিকল্প পাবলিক ফেসিং সার্ভারের জন্য বেশ সমস্যাযুক্ত , যা কঠিন একটি সমস্যা সনাক্ত করতে এবং আপনি দান্ত দিয়া ফুটা করা অপেক্ষা করতে। নোট যে লিনাক্স 4.12 থেকে সরানোnet.ipv4.tcp_tw_recycle হয়েছে ।

সার্ভার সাইড অন:net.core.somaxconn মান একটি গুরুত্বপূর্ণ ভূমিকা আছে। এটি শ্রবণ সকেটে সারি সর্বাধিক সংখ্যক অনুরোধের সীমাবদ্ধ করে। আপনি যদি আপনার সার্ভার অ্যাপ্লিকেশনটির সক্ষমতা সম্পর্কে নিশ্চিত হন তবে এটি ডিফল্ট 128 থেকে 128 থেকে 1024 এর মতো কিছুতে ফাটিয়ে ফেলুন Now

sysctl net.core.somaxconn=1024

txqueuelenআপনার ইথারনেট কার্ডের প্যারামিটারেও ভূমিকা রাখতে হবে। ডিফল্ট মানগুলি হ'ল 1000, সুতরাং আপনার সিস্টেম এটি পরিচালনা করতে পারলে 5000 বা আরও বেশি অবধি এগুলিকে ঘর্ষণ করুন।

ifconfig eth0 txqueuelen 5000
echo "/sbin/ifconfig eth0 txqueuelen 5000" >> /etc/rc.local

একইভাবে মান আচমকা net.core.netdev_max_backlogএবং net.ipv4.tcp_max_syn_backlog। তাদের ডিফল্ট মান যথাক্রমে 1000 এবং 1024।

sysctl net.core.netdev_max_backlog=2000
sysctl net.ipv4.tcp_max_syn_backlog=2048

এখন আপনার ক্লায়েন্ট এবং সার্ভারের উভয় অ্যাপ্লিকেশন শেলের মধ্যে এফডি উলিম্টগুলি বাড়িয়ে শুরু করতে ভুলবেন না।

উপরোক্ত প্রোগ্রামারগুলির দ্বারা ব্যবহৃত আরও একটি জনপ্রিয় কৌশল হ'ল টিসিপি রাইটিং কলগুলির সংখ্যা হ্রাস করা । আমার নিজের পছন্দটি হল একটি বাফার ব্যবহার করা যাতে আমি ক্লায়েন্টকে প্রেরণ করতে ইচ্ছুক ডেটাটি পুশ করি এবং তারপরে উপযুক্ত পয়েন্টগুলিতে আমি আসল সকেটে বাফার ডেটা লিখি। এই কৌশলটি আমাকে বড় ডেটা প্যাকেটগুলি ব্যবহার করতে, টুকরো টুকরো করতে হ্রাস করতে, ব্যবহারকারীর জমিতে এবং কার্নেল-স্তরে আমার সিপিইউ ব্যবহার হ্রাস করে।


4
জমকালো উত্তর! আমার সমস্যাটি কিছুটা আলাদা ছিল, অর্থাত্ আমি একটি অ্যাপ্লিকেশন স্তরের সেশন স্টোরেজ থেকে পিএইচপি দিয়ে পুনরায় redis এ সেশন তথ্য সরিয়ে নেওয়ার চেষ্টা করছিলাম। কোনও কারণে, পিএইচপি বা রেডিস লগগুলিতে কোনও ত্রুটি না দেখায় আমি একসাথে প্রচুর ঘুম না যুক্ত করে 28230 টির বেশি সেশন যোগ করতে পারিনি। আমরা পুরো দিন পর্যন্ত এই বিষয়ে মাথা নষ্ট করেছিলাম যতক্ষণ না আমি ভেবেছিলাম সমস্যা পিএইচপি / রেডিসের সাথে নয় তবে টিসিপি / আইপি স্তরটিতে দু'টিকে সংযুক্ত করে এই উত্তরে উপস্থিত হয়েছে। এর পরে আর কোনও সময়ের মধ্যে সমস্যার সমাধান করতে পরিচালিত :) অনেক অনেক ধন্যবাদ!
এস

27
ভুলে যাবেন না যে আমরা সবসময় আইপি + পোর্ট নিয়ে কথা বলি। আপনার অনেকগুলি বিভিন্ন আইপি থেকে এক্সওয়াই পোর্টে "সীমাহীন" সকেট খোলা থাকতে পারে। 470 এর সীমা কেবল একই আইপিতে একযোগে খোলা সকেটের ক্ষেত্রে প্রযোজ্য। একই আইনে অন্য আইপি এর নিজস্ব 470 সংযোগ থাকতে পারে।
Marki555

6
@ মার্কি 555: আপনার মন্তব্যটি খুব সঠিক। বিপুল সংখ্যক বহির্মুখী সংযোগ উত্পাদন ও বজায় রাখার জন্য তৈরি অ্যাপ্লিকেশনগুলির অবশ্যই আউটবাউন্ড সংযোগ তৈরি করার জন্য উপলব্ধ আইপিগুলির একটি "সচেতনতা" থাকা আবশ্যক এবং এরপরে কোনও ধরণের "রাউন্ড-রবিন অ্যালগরিদম" ব্যবহার করে এই আইপি ঠিকানাগুলিতে যথাযথভাবে আবদ্ধ থাকতে হবে, এবং বজায় রাখতে হবে একটি "স্কোরবোর্ড"।
এমডিকে

8
এই উত্তরের ভুল রয়েছে। প্রথমত, নেট.ipv4.tcp_fin_timeout শুধুমাত্র FIN_WAIT_2 রাজ্যের জন্য ( cs.uwaterloo.ca/~brecht/servers/ip-sctl.txt )। দ্বিতীয়ত, @ এরিক যেমন বলেছিলেন, "নির্দিষ্ট সময়ে 470 সকেট" সঠিক নয়।
শারভনাথ

3
@ এমডিকে: আমি এই গণনার অংশটি পরিষ্কার করছি না (61000 - 32768) / 60 = 470 sockets per second। আপনি দয়া করে এই বিস্তারিত বলতে পারেন?
টম টেলর

64

সংযোগের সর্বাধিক সংখ্যা সেট করতে বেশ কয়েকটি ভেরিয়েবল রয়েছে। সম্ভবত, আপনি প্রথমে ফাইল নম্বর শেষ করছেন। Ulimit -n পরীক্ষা করুন। এরপরে, / প্রোকে কিছু সেটিংস রয়েছে তবে দশ হাজারে সেগুলি ডিফল্ট।

আরও গুরুত্বপূর্ণ এটি মনে হচ্ছে আপনি কিছু ভুল করছেন। একটি টিসিপি সংযোগ দুটি পক্ষের মধ্যে ব্যান্ডউইথ সমস্ত ব্যবহার করতে সক্ষম হওয়া উচিত; যদি তা না হয়:

  • আপনার টিসিপি উইন্ডো সেটিংস যথেষ্ট বড় কিনা তা পরীক্ষা করে দেখুন। লিনাক্স ডিফল্টগুলি সত্যই দ্রুত ইনট লিঙ্ক (শত শত এমবিপিএস) বা দ্রুত স্যাটেলাইট লিঙ্কগুলি বাদ দিয়ে সমস্ত কিছুর জন্য ভাল। আপনার ব্যান্ডউইথ * বিলম্ব পণ্যটি কী?
  • বড় প্যাকেটগুলির সাথে পিং ব্যবহার করে প্যাকেটের ক্ষতির জন্য পরীক্ষা করুন ( ping -s 1472...)
  • হার সীমাবদ্ধতার জন্য পরীক্ষা করুন। লিনাক্সে এটি কনফিগার করা আছেtc
  • নিশ্চিত করুন যে আপনি যে ব্যান্ডউইথটি মনে করেন বাস্তবে এটি বিদ্যমান রয়েছে উদাহরণস্বরূপ, iperf
  • নিশ্চিত করুন যে আপনার প্রোটোকলটি বুদ্ধিমান। বিলম্ব মনে রাখবেন।
  • এটি যদি গিগাবিট + ল্যান হয় তবে আপনি কি জাম্বো প্যাকেট ব্যবহার করতে পারবেন? আপনি?

সম্ভবত আমি ভুল বুঝেছি। হতে পারে আপনি বিটোরেন্টের মতো কিছু করছেন, যেখানে আপনার প্রচুর সংযোগ দরকার। যদি তাই হয়, আপনি কতগুলি সংযোগ আপনি আসলে (চেষ্টা ব্যবহার করছেন জিনিসটা প্রয়োজন netstatবা lsof)। যদি সংখ্যাটি যথেষ্ট হয় তবে আপনি এটি করতে পারেন:

  • প্রচুর পরিমাণে ব্যান্ডউইথ আছে, যেমন, 100 এমবিপিএস +। এই ক্ষেত্রে, আপনার আসলে আপ করতে হবে ulimit -n। তবুও, ~ 1000 সংযোগ (আমার সিস্টেমে ডিফল্ট) বেশ কয়েকটি।
  • নেটওয়ার্কগুলির সমস্যা রয়েছে যা আপনার সংযোগগুলি ধীর করে দিচ্ছে (যেমন, প্যাকেটের ক্ষতি)
  • আপনাকে কিছুটা কমিয়ে দেওয়ার মতো আরও কিছু করুন, যেমন, আইও ব্যান্ডউইথ, বিশেষত যদি আপনি সন্ধান করছেন। আপনি পরীক্ষা করেছেন iostat -x?

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

আমি আশা করি এটি কিছু সহায়তা দেয়। আপনি সত্যিই একটি নেটওয়ার্কিং প্রশ্ন জিজ্ঞাসা করছেন।


16

ডারবার্টের দেওয়া উত্তরের উন্নতি করতে,

Nf_conntrack_max ক্যাটিংয়ের মাধ্যমে আপনি নির্ধারণ করতে পারবেন যে আপনার ওএস সংযোগের সীমাটি কী।

উদাহরণস্বরূপ: বিড়াল / proc / sys / নেট / নেটফিল্টার / এনএফ_কন্ট্র্যাক_ম্যাক্স

টিসিপি পোর্টের প্রদত্ত পরিসরে টিসিপি সংযোগের সংখ্যা গণনা করতে আপনি নিম্নলিখিত স্ক্রিপ্টটি ব্যবহার করতে পারেন। ডিফল্টভাবে 1-65535।

আপনি আপনার ওএস সংযোগ সীমাটি সর্বাধিক বাড়িয়েছেন কিনা তা এটি নিশ্চিত করবে।

এখানে স্ক্রিপ্ট।

#!/bin/bash
OS=$(uname)

case "$OS" in
    'SunOS')
            AWK=/usr/bin/nawk
            ;;
    'Linux')
            AWK=/bin/awk
            ;;
    'AIX')
            AWK=/usr/bin/awk
            ;;
esac

netstat -an | $AWK -v start=1 -v end=65535 ' $NF ~ /TIME_WAIT|ESTABLISHED/ && $4 !~ /127\.0\.0\.1/ {
    if ($1 ~ /\./)
            {sip=$1}
    else {sip=$4}

    if ( sip ~ /:/ )
            {d=2}
    else {d=5}

    split( sip, a, /:|\./ )

    if ( a[d] >= start && a[d] <= end ) {
            ++connections;
            }
    }
    END {print connections}'

3
which awk
আফকের

2
@PanagiotisM। whichপ্রোগ্রামটি নির্ভর করে সেই PATHক্ষেত্রে আপনি awkপুরো পথ সরবরাহ না করে কেবল ব্যবহার করতে পারবেন । (এটি বলেছিল যে, আমি নিশ্চিত নই যে স্ক্রিপ্টের সমাধানটি কোনও পরিপূর্ণতার নিকটবর্তী কিনা, তবে স্ক্রিপ্টটি এটাই নয়)।
মাইকেল ক্রেলিন - হ্যাকার

5
আমি এই স্ক্রিপ্টটি কীভাবে awkঅবস্থান নির্ধারণ করতে ব্যালিস্টিক যায় তা আমি পছন্দ করি তবে ধরে /bin/bash নিই যে শেলটি সর্বদা থাকে (প্রো টিপ: এআইএক্স 5/6 এও ডিফল্টরূপে ব্যাশ নেই)।
কুবাঞ্চিক

কি awkসনাক্তকরণ দরকারী? ব্যক্তিগতভাবে আমি কেবলমাত্র একটি সঠিক ধারণা ধরে নিব PATHতবে যথাযথ বিকল্প হতে পারে /usr/bin/env awkএবং /usr/bin/env bashযথাক্রমে হতে পারে । এটির মূল্য কী, এটি আমার লিনাক্স সিস্টেমে লোকেশনটি ভুল পেয়েছে। এটি /usr/bin/awkনেই/bin/awk
ওল্ফ

1
আমি যখন এই স্ক্রিপ্টটি চালাচ্ছি তখন আমি 798 পাই, তবে এর অর্থ কী?

10

অ্যাপ্লিকেশন স্তরে, এখানে বিকাশকারী কিছু করতে পারেন:

সার্ভার দিক থেকে:

  1. লোড ব্যালেন্সার (যদি আপনার থাকে) সঠিকভাবে কাজ করে কিনা তা পরীক্ষা করুন।

  2. ধীরে ধীরে টিসিপি টাইমআউটগুলি 503 দ্রুত তাত্ক্ষণিক প্রতিক্রিয়াতে পরিণত করুন, আপনি যদি ভারসাম্যপূর্ণ কাজটি সঠিকভাবে লোড করেন তবে এটির কার্যকারিতা সংস্থানটি বেছে নেওয়া উচিত এবং অপ্রত্যাশিত ত্রুটিযুক্ত মালিশের সাথে সেখানে ঝুলানো ভাল।

উদাহরণস্বরূপ: আপনি যদি নোড সার্ভার ব্যবহার করেন তবে আপনি এনপিএম থেকে টোবিসি ব্যবহার করতে পারেন। বাস্তবায়ন যেমন:

var toobusy = require('toobusy');
app.use(function(req, res, next) {
  if (toobusy()) res.send(503, "I'm busy right now, sorry.");
  else next();
});

503 কেন? এখানে ওভারলোডের জন্য কিছু ভাল অন্তর্দৃষ্টি রয়েছে: http://ferd.ca/queues-don-t-fix-overload.html

আমরা ক্লায়েন্ট সাইডেও কিছু কাজ করতে পারি:

  1. ব্যাচে গ্রুপ কল করার চেষ্টা করুন, ট্রাফিক এবং মোট অনুরোধ নম্বর বি / ডাব্লু ক্লায়েন্ট এবং সার্ভার হ্রাস করুন।

  2. অপ্রয়োজনীয় সদৃশ অনুরোধগুলি পরিচালনা করতে ক্যাশে মিড-লেয়ার তৈরি করার চেষ্টা করুন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.