it-swarm-tr.com

Bir Linux sunucusundaki maksimum bağlantı sayısını sınırlayan nedir?

Hangi çekirdek parametresi veya diğer ayarlar bir Linux sunucusunda açılabilecek maksimum TCP yuva sayısı) nı kontrol eder? Daha fazla bağlantıya izin verme gelenekleri nelerdir?

ab ile bir Apache sunucusunu yüklerken sunucudaki açık bağlantıları en üst düzeye çıkarmak oldukça kolay olduğunu fark ettim. Bağlantıların yeniden kullanılmasına izin veren ve yaklaşık 10.000'den fazla istek göndermesini sağlayan ab'nin -k seçeneğini bırakırsanız, Apache ilk 11.000 kadar istekte bulunur ve 60 saniye boyunca durur. Netstat çıkışına bakıldığında TIME_WAIT durumunda 11.000 bağlantı gösterilir. Görünüşe göre, bu normal. İstemciler TCP güvenilirlik nedenleriyle nedeniyle istemci onlarla yapıldıktan sonra bile bağlantılar varsayılan olarak 60 saniye açık tutulur.

Bu bir sunucu DoS için kolay bir yol gibi görünüyor ve bunun için her zamanki ayarların ve önlemlerin ne olduğunu merak ediyorum.

İşte test çıktım:

# ab -c 5 -n 50000 http://localhost/
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> Apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.Apache.org/

Benchmarking localhost (be patient)
Completed 5000 requests
Completed 10000 requests
apr_poll: The timeout specified has expired (70007)
Total of 11655 requests completed

İşte test sırasında çalıştırdığım netstat komutu:

 # netstat --inet -p | grep "localhost:www" | sed -e 's/ \+/ /g' | cut -d' ' -f 1-4,6-7 | sort | uniq -c 
  11651 tcp 0 0 localhost:www TIME_WAIT -
      1 tcp 0 1 localhost:44423 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44424 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44425 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44426 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44428 SYN_SENT 7831/ab
91
Ben Williams

Sonunda gerçekten bağlantı sayısını sınırlayan ayarı buldum: net.ipv4.netfilter.ip_conntrack_max. Bu 11.776 olarak ayarlandı ve ne yaparsam yapayım, daha fazla bağlantının kullanılabilir olması için tcp_fin_timeout Saniye beklemeden önce testimde sunabileceğim istek sayısı. conntrack tablosu, çekirdeğin bağlantıların durumunu izlemek için kullandığı tablodur, bu yüzden dolu olduktan sonra çekirdek paketleri bırakmaya ve günlüğe yazdırmaya başlar:

Jun  2 20:39:14 XXXX-XXX kernel: ip_conntrack: table full, dropping packet.

Bir sonraki adım, çekirdeği paketleri bırakmak yerine TIME_WAIT Durumundaki tüm bağlantıları geri dönüştürmeye almaktı. Bunu tcp_tw_recycle 'İ açarak veya ip_conntrack_max' U ip_local_port_range Tarafından bağlantı için kullanılabilir yerel bağlantı noktalarının sayısından daha fazla artırarak gerçekleştirebilirim. Çekirdek yerel bağlantı noktalarından çıktığında bağlantıları geri dönüştürmeye başlar sanırım. Bu, daha fazla bellek izleme bağlantısı kullanır, ancak dokümanlar bunun tehlikeli olduğunu ima ettiğinden tcp_tw_recycle Açmaktan daha iyi bir çözüm gibi görünüyor.

Bu yapılandırma ile tüm gün ab çalıştırabilir ve hiçbir zaman bağlantı bitmeyebilir:

net.ipv4.netfilter.ip_conntrack_max = 32768
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_tw_reuse = 0
net.ipv4.tcp_Orphan_retries = 1
net.ipv4.tcp_fin_timeout = 25
net.ipv4.tcp_max_orphans = 8192
net.ipv4.ip_local_port_range = 32768    61000

tcp_max_orphans Ayarının testlerim üzerinde bir etkisi olmadı ve nedenini bilmiyorum. Ben 8192 tanesi vardı bir kez TIME_WAIT Devlet bağlantıları kapatır düşünürdüm ama bunu benim için yapmaz.

66
Ben Williams

/ Proc dosya sisteminin bu konuda size neler sunduğuna gerçekten bakmak istiyorsunuz.

Bu son sayfada aşağıdakilerin ilginizi çekebileceğini görebilirsiniz:

  • / proc/sys/net/ipv4/tcp_max_orphans , sistem tarafından tutulan maksimum soket sayısını kontrol eder değil bir şeye bağlı. Bunu artırmak 64kbayt kadar değiştirilemez bellek tüketebilir Yetim soketi başına.
  • / proc/sys/net/ipv4/tcp_Orphan_retries , bir yuva yetim olmadan ve kapatılmadan önce yeniden deneme miktarını kontrol eder. Bu sayfada, web sunucuları hakkında sizi doğrudan ilgilendiren özel bir not var ...
24
Avery Payne

Bunu doğrudan ayarlamak için bir ayarlanabilir olduğunu düşünmüyorum. Bu TCP/IP ayarı kategorisine girer. Neleri ayarlayabileceğinizi öğrenmek için 'man 7 tcp' komutunu deneyin. Bunları ayarlamak için sysctl ('man 8 sysctl') kullanılır. 'sysctl -a | grep tcp 'size ayarlayabileceğiniz şeylerin çoğunu gösterecektir, ancak hepsini gösterip göstermeyeceğinden emin değilim. Ayrıca, bu durum değişmedikçe, TCP/IP yuvaları dosya tanıtıcıları gibi görünür. Yani this ve bu bağlantıdaki bir sonraki bölüm aradığınız şey olabilir.

3
Kyle Brandt

Aşağıdakileri ayarlamayı da deneyin tcp_fin_timeout. Bunun TIME_WAIT daha hızlı kapanması gerekir.

net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
2
Jauder Ho

Stok Apache (1) önceden 250 eşzamanlı bağlantıyı desteklemek için önceden tanımlanmış olarak geliyordu - daha fazlasını istiyorsanız, daha eşzamanlı oturumlara izin vermek için değiştirilecek bir başlık dosyası vardı. Apache 2 ile bunun hala geçerli olup olmadığını bilmiyorum.

Ayrıca, Apache'yi çalıştıran hesap için daha fazla açık dosya tanımlayıcısına izin vermek için bir seçenek eklemeniz gerekir - bu, önceki yorumların işaret edemediği bir şeydir.

Çalışan ayarlarınıza ve Apache'nin içinde ne tür bir tutma zaman aşımına sahip olduğunuza, aynı anda kaç tane yedek sunucu çalıştırdığınıza ve bu ekstra işlemlerin ne kadar hızlı öldürüldüğüne dikkat edin.

2
rasjani

TIME_WAIT durumunda harcanan zamanı azaltabilirsiniz (Set net.ipv4.tcp_fin_timeout). Apache'yi YAWS veya nginx veya benzeri bir şeyle değiştirebilirsiniz.

Daha fazla bağlantı geleneği genellikle bellek kullanımını içerir ve bir çatallama işleminiz varsa, CPU'nuzu değiştiren birçok çocuk işlemi vardır.

1
Devdas

2.4 sürümünde Apache HTTP sunucusu karşılaştırma aracı ab , - s zaman aşımı seçeneğine sahiptir. Ayrıca bkz. ab (Apache Bench) hatası: apr_poll: Belirtilen zaman aşımı süresi doldu (Windows'ta 70007).

Bu seçenek sorununuzu çözer.

0
Dzwiedziu-nkg

Tek bir IP adresinde açılabilen mutlak soket sayısı 2 ^ 16'dır ve çekirdek tarafından değil, TCP/UDP tarafından tanımlanır.

0
Jason Tan