Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thousands of TIME_WAIT despite SO_LINGER, shutdown etc

Tags:

I'm working on a site that connects to many URLs at once, (we are hoping to get to ~600 per minute) and no matter what I try, there are always thousands of TIME_WAIT still open. I understand these are vital to TCP connections, but they are using all the available ports. PHP doesn't have a SO_REUSEPORT, and SO_REUSEADDR doesn't work with remote connections. Here is the beginning of the code:

$s = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($s, SOL_SOCKET, SO_LINGER,array('l_linger'=>0, 'l_onoff'=>0)); //I have tried l_onoff=1 
socket_set_option($s, SOL_SOCKET, SO_RCVTIMEO,array('sec'=>0,'usec'=>500000));
socket_set_option($s, SOL_SOCKET, SO_SNDTIMEO,array('sec'=>0,'usec'=>500000));
socket_set_option($s, SOL_SOCKET, SO_KEEPALIVE,0);
socket_set_option($s, SOL_SOCKET, SO_REUSEADDR,1);
socket_set_nonblock($s);
socket_bind($s,$ip,0);
socket_connect($s,$host,$port);

The $s goes into an array contains all the pending writes, after a write we call socket_shutdown($s,1); to close writing on the socket. Then after a read we:

socket_shutdown($s,2); socket_close($s);

All reading and writing is done in a while loop, the loop has a max of 12 concurrent connections, if that is not hit, then it moves on and proceeds to add another URL to the array. Every loop calls socket_select with a timeout of 0.

Does anyone have any suggestions? I would like to increase the speed as well as reduce the TIME_WAIT's that appear in netstat.

Thanks, James Hartig

like image 417
James Hartig Avatar asked Jan 22 '10 01:01

James Hartig


1 Answers

You could send the HTTP header Connection: close along with your request which would cause the server to send a TCP FIN after it sends you your request. Because the other side sends the first FIN, it'll be the other side that gets to wait around in TIME_WAIT, not you.

like image 102
eater Avatar answered Oct 29 '22 16:10

eater