最近研究了一些服务端内容,程序很简单,通过restful接口往数据库中写数据。问题不在服务端程序上,而是在调用接口大批量插入数据时候。
因为数据比较多,所以写了个简单的java程序从excel表格中读取数据,然后调用接口发送数据
for (int i = 1; i < rowNum; i++) {
...
sendRequest(url, params);
...
}
使用的是这种循环的方式写的,sendRequest
中使用了Okhttp3框架。
这种方式当数据较少时候没什么问题,但是当数据多了(超过10000)条,就会出现socket timeout的错误,导致不能插入:
No buffer space available (maximum connections reached?)
问题很明确,连接数达到最大了,但是考虑到这个服务只有我自己在调用,而且我在sendRequest
中使用的是okhttp的同步写法,因此在for循环中也是应该一次请求执行完毕后再进入第二次循环,所以按道理来说应该不会造成连接数超了。
对此我考虑把数据分块插入,分块中间等待一段时间,比如先插入8000条数据,然后等待一分钟,再插8000条,依次插入。这样的做法确实能解决问题。因此我就考虑了,可能是由于okhttp的连接没有断开,导致的服务器端超出最大连接数。
并且在等待的时候,偶然出现了以下的log
WARNING: A connection to xxxxx was leaked. Did you forget to close a response body?
没有关闭response body,查阅了一些资料发现确实存在这个情况,okhttp的response body需要调用close()
。
由于之前在Android端使用okhttp发送的请求并不多,因此不会出现这种情况,也就忽视了这种问题,加上close关闭body,问题解决,for循环中循环几万条数据也不会出现问题。