I need to get up to 1000 threads to send HTTP request simultaneously. Yet it seems on Mac I am hitting some limit, which causes Apache HTTPClient to return exception:
INFO: I/O exception (java.net.SocketException) caught when processing request to {}->http://my.url:80: Connection reset
The limit appears to be somewhere between 200 and 300 concurrent connections.
I created a simple app and able to reproduce the issue even with that app:
import java.io.IOException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
public class App implements Runnable
{
private static final int NUMBER_THREADS = 1000;
public static void main( String[] args )
{
Thread[] threads = new Thread[NUMBER_THREADS];
for(int i = 0; i < NUMBER_THREADS; i++)
{
threads[i] = new Thread(new App());
}
for(int i = 0; i < NUMBER_THREADS; i++)
{
threads[i].start();
}
}
public void run()
{
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpget = new HttpGet("http://my.url/test.html");
CloseableHttpResponse response = null;
try
{
System.out.println( System.nanoTime() + " " + Thread.currentThread().getName() + " started" );
response = httpclient.execute(httpget);
System.out.println( System.nanoTime() + " " + Thread.currentThread().getName() + " finished" );
}
catch (ClientProtocolException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
try
{
if(response != null)
{
response.close();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
I updated some Mac settings, but that didn't help anything:
> sysctl -a | grep files
kern.maxfiles = 12288
kern.maxfilesperproc = 10240
kern.maxfiles: 12288
kern.maxfilesperproc: 10240
kern.num_files: 3202
> ulimit -n 10240
> ulimit -n
10240
> sysctl -a | grep somax
kern.ipc.somaxconn: 128
> sudo sysctl -w kern.ipc.somaxconn=2048
Password:
kern.ipc.somaxconn: 128 -> 2048
> sysctl -a | grep somax
kern.ipc.somaxconn: 2048
So I want to understand where this limit is coming from? OsX / Apache HttpClient itself? And is it possible to control it?
Thanks in advance.
The problem was indeed with maxfiles, but I was not changing them right. This article helped me to solve it by showing the correct procedure for updating file limits on Mac OS X Yosemite / El Capitan.
Create and update /Library/LaunchDaemons/limit.maxfiles.plist file:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>limit.maxfiles</string> <key>ProgramArguments</key> <array> <string>launchctl</string> <string>limit</string> <string>maxfiles</string> <string>65536</string> <string>65536</string> </array> <key>RunAtLoad</key> <true/> <key>ServiceIPC</key> <false/> </dict> </plist>
Create /Library/LaunchDaemons/limit.maxproc.plist file:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple/DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>limit.maxproc</string> <key>ProgramArguments</key> <array> <string>launchctl</string> <string>limit</string> <string>maxproc</string> <string>2048</string> <string>2048</string> </array> <key>RunAtLoad</key> <true /> <key>ServiceIPC</key> <false /> </dict>
Add .bashprofile with the following lines:
ulimit -n 65536 ulimit -u 2048
Restart your system
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.