Çok hızlı çalışan bir RESTful servisim var. Ben localhost üzerinde test ediyorum. İstemci Spring REST şablonunu kullanıyor. Bu kapalı ve TIME_WAIT asılı olmamak bağlantıları kaynaklanırSpring REST şablonunu kullanarak ya çok fazla bağlantı oluşturuyor ya da yavaş çalışıyor
Caused by: org.springframework.web.client.ResourceAccessException: I/O error on POST request for "http://localhost:8080/myservice":No buffer space available (maximum connections reached?): connect; nested exception is java.net.SocketException: No buffer space available (maximum connections reached?): connect
: Aşağıdaki özel durum alıyorum ben bu istekleri bir sürü yaptığınızda
RestTemplate restTemplate = new RestTemplate(Collections.singletonList(new GsonHttpMessageConverter()));
Result result = restTemplate.postForObject(url, payload, Result.class);
: Ben naif bir yaklaşım kullanarak başladı belirtmek, bildirmek. İstisna noktaları geçici olarak bittiğinde istisna başlar. Daha sonra yürütme, bağlantı noktalarının tekrar serbest olmasını bekler. Uzun aralarla en yüksek performansı görüyorum. Aldığım oran neredeyse ihtiyacım olan şey, ama tabi ki bu TIME_WAIT bağlantıları iyi değil. Hem Linux (Ubuntu 14) hem de Windows (7) üzerinde test edilmiş, farklı sonuçlar için farklı zaman aralıklarında benzer sonuçlar elde edilmiştir.
Bu sorunu gidermek için, HttpClientBuilder ile HttpClient uygulamasını Apache Http Components kitaplığından kullanmayı denedim.
RestTemplate restTemplate = new RestTemplate(Collections.singletonList(new GsonHttpMessageConverter()));
HttpClient httpClient = HttpClientBuilder.create()
.setMaxConnTotal(TOTAL)
.setMaxConnPerRoute(PER_ROUTE)
.build();
restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory(httpClient));
Result result = restTemplate.postForObject(url, payload, Result.class);
Bu istemci ile hiçbir özel durum göremiyorum. Müşteri şimdi sadece çok sınırlı sayıda geçici bağlantı noktası kullanıyor. Ama kullandığım ayarları (TOTAL ve PER_ROUTE), ihtiyacım olan performansı alamıyorum.
netstat
komutunu kullanarak, sunucuya çok fazla bağlantı yapılmadığını görüyorum. Sayıları binlerce kişiye ayarlamayı denedim, ama müşterinin bu kadar fazla kullanmadığı görülüyor.
Çok sayıda bağlantı açmadan performansı artırmak için yapabileceğim bir şey var mı?
GÜNCELLEME: Ben 5000 ve 2500 toplam ve başına rota bağlantı sayısını ayarlama denedim ama istemci (netstat -n | wc -l
bakarsak) yüzden fazla yaratmak değil gibi hala görünüyor. REST servisi JAX-RS kullanılarak ve Jetty üzerinde çalışıyor.
UPDATE2: Sunucuyu bazı bellek ayarlarıyla ayarlıyorum ve gerçekten iyi bir iş çıkışı elde ediyorum. Naif yaklaşım hala biraz daha hızlı, ama bence müşteri tarafında havuzun küçük bir yükü.
"Ara bellek alanı yok" hatası, kodunuzla daha az sisteminizle ilişkilidir. TIME_WAIT bağlantılarının birçoğu, bağlantıların havuzlanmadığını gösterir. TIME_WAIT ayarlarını değiştirmeyin, çözdüğünden daha fazla soruna neden olacaktır (http://vincent.bernat.im/en/blog/2014-tcp-time-wait-state-linux.html). Kullanılabilir arabellek alanı için olağan nedenler, kırık ağ kartları veya Linux'ta küçük bir wmem_max. Yuvalardan çıkmadan (IP dörtgenler) önce aynı bağlantı noktasındaki bir uzak ana bilgisayara en az 50k - 60k arası bağlantılar oluşturabilmeniz gerekir. – mp911de