https://docs.oracle.com/javase/8/docs/api/java/net/InetAddress.html
注意
networkaddress.cache.ttl
和
networkaddress.cache.negative.ttl
是安全参数,不能直接通过 -D 配置,可以通过下面两个系统参数做对应配置:
sun.net.inetaddr.ttl
dns缓存时间(秒),未配置
networkaddress.cache.ttl
时使用此配置项
sun.net.inetaddr.negative.ttl
未配置
networkaddress.cache.negative.ttl
时使用此配置项
如果开启了 SecurityManager,优先从 ${java.home}/jre/lib/security/java.security 中读取参数 networkaddress.cache.ttl 单位为秒。
如果未读取到,则会读取启动参数 sun.net.inetaddr.ttl 作为缓存 ttl.
如果以上参数均未读取到,并且未开启 SecurityManager 则会使用默认值 30s.
否则使用初始值 -1,表示永久生效。
相关代码在 sun.net.InetAddressCachePolicy.class 中
JVM DNS 缓存配置
https://www.jianshu.com/p/048e8bd3ea46
How to make Java honor the DNS Caching Timeout?
https://stackoverflow.com/questions/1256556/how-to-make-java-honor-the-dns-caching-timeout
https://stackoverflow.com/questions/15785175/java-io-ioexception-broken-pipe/15785439
一次SocketException:Connection reset 异常排查
https://www.cnblogs.com/shoren/p/httpclient-connectionreset.html
org.apache.catalina.connector.ClientAbortException: java.io.IOException: Broken pipe
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:380)
at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:420)
at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:345)
https://stackoverflow.com/questions/38692035/java-io-ioexception-ut010029-stream-is-closed
Failed to invoke @ExceptionHandler method: public com.nio.common.web.HttpResponse com.nio.common.web.ErrorHandler.handleAllException(java.lang.Exception,javax.servlet.http.HttpServletRequest)
java.io.IOException: UT010029: Stream is closed
at io.undertow.servlet.spec.ServletOutputStreamImpl.write(ServletOutputStreamImpl.java:137) ~[undertow-servlet-1.4.26.Final.jar!/:1.4.26.Final]
at com.fasterxml.jackson.core.json.UTF8JsonGenerator._flushBuffer(UTF8JsonGenerator.java:2039) ~[jackson-core-2.8.11.jar!/:2.8.11]
at com.fasterxml.jackson.core.json.UTF8JsonGenerator.flush(UTF8JsonGenerator.java:1051) ~[jackson-core-2.8.11.jar!/:2.8.11]
at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:953) ~[jackson-databind-2.8.11.3.jar!/:2.8.11.3]
https://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html
解决:
虽然网上解释这个参数与接口处理超时无关,但是设置 server.tomcat.connection-timeout=1800000
后,确实解决了大文件(3GB)下载中断报错的问题。
https://docs.oracle.com/javase/8/docs/technotes/guides/net/articles/connection_release.html
http://www.4e00.com/blog/linux/2019/03/27/tcp-option-so-linger.html
https://stackoverflow.com/questions/7348711/recommended-way-to-get-hostname-in-java
https://www.cnblogs.com/ooo0/p/9846073.html
Java: how to use UrlConnection to post request with authorization?
https://stackoverflow.com/questions/2026260/java-how-to-use-urlconnection-to-post-request-with-authorization
https://www.cnblogs.com/guodongli/archive/2011/04/05/2005930.html
www.protocol.http 包里有个 HttpURLConnection
继续实现了 java.net.HttpURLConnection
package sun.net.www.protocol.http;
public class HttpURLConnection extends java.net.HttpURLConnection {
www.http.KeepAliveCache.java 中有一个线程,每 5 秒执行一次,检查缓存的连接的空闲时间是否超过 keepAliveTimeout,如果超过则关闭连接。从 KeepAliveCache 中获取缓存的连接时也会检查获取到的连接的空闲时间是否超过 keepAliveTimeout,如果超过则关闭连接,并且获取下一个连接,再执行以上检查,直达获取到空闲时间在 keepAliveTimeout 以内的缓存连接为此。
www.protocol.http.HttpURLConnection 的 内部类 HttpInputStream 的 int read(byte[] b)
方法,最终到
ChunkedInputStream 类的 processRaw() 方法,里面处理原始输出字节流,关闭连接时调用 closeUnderlying() 方法。
sun.net.www.http.ChunkedInputStream.closeUnderlying() 方法的注释可以看出,这个方法里将连接放入 KeepAliveCache 或是 关闭连接:
* Close the underlying input stream by either returning it to the
* keep alive cache or closing the stream.
* As a chunked stream is inheritly persistent (see HTTP 1.1 RFC) the
* underlying stream can be returned to the keep alive cache if the
* stream can be completely read without error.
private void closeUnderlying() throws IOException {
if (in == null) {
return;
if (!error && state == STATE_DONE) {
hc.finished();
} else {
if (!hurry()) {
hc.closeServer();
in = null;
sun.net.www.http.HttpClient.finished()
方法中,判断是 keep-alive 连接且剩余连接数大于0且未超时,调用 putInKeepAliveCache() 方法加入 keep-alive 缓存。
protected static KeepAliveCache kac = new KeepAliveCache();
/* return it to the cache as still usable, if:
* 1) It's keeping alive, AND
* 2) It still has some connections left, AND
* 3) It hasn't had a error (PrintStream.checkError())
* 4) It hasn't timed out
* If this client is not keepingAlive, it should have been
* removed from the cache in the parseHeaders() method.
public void finished() {
if (reuse) /* will be reused */
return;
keepAliveConnections--;
poster = null;
if (keepAliveConnections > 0 && isKeepingAlive() &&
!(serverOutput.checkError())) {
/* This connection is keepingAlive && still valid.
* Return it to the cache.
putInKeepAliveCache();
} else {
closeServer();
protected synchronized void putInKeepAliveCache() {
if (inCache) {
assert false : "Duplicate put to keep alive cache";
return;
inCache = true;
kac.put(url, null, this);
最终放入缓存的操作在 sun.net.www.http.KeepAliveCache
类的 put()
方法中
https://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html#application-properties.server.server.tomcat.keep-alive-timeout
server.tomcat.connection-timeout
单位毫秒,默认值 60000,创建连接后 server 等待 client 发送请求数据的超时时间。
server.tomcat.keep-alive-timeout
单位毫秒,连接关闭前等待下一个请求的超时时间,这个时间会放到调用方接收到的 response Keep-Alive header 中,未设置时自动使用 server.tomcat.connection-timeout
时间,设置为 -1 表示无超时。
直接对应到原生 Tomcat 的配置参数
Apache Tomcat 9 Configuration Reference - The HTTP Connector
https://tomcat.apache.org/tomcat-9.0-doc/config/http.html
connectionTimeout
The number of milliseconds this Connector will wait, after accepting a connection, for the request URI line to be presented. Use a value of -1 to indicate no (i.e. infinite) timeout. The default value is 60000 (i.e. 60 seconds) but note that the standard server.xml that ships with Tomcat sets this to 20000 (i.e. 20 seconds). Unless disableUploadTimeout is set to false, this timeout will also be used when reading the request body (if any).
keepAliveTimeout
The number of milliseconds this Connector will wait for another HTTP request before closing the connection. The default value is to use the value that has been set for the connectionTimeout attribute. Use a value of -1 to indicate no (i.e. infinite) timeout.
https://openjdk.org/jeps/110
JEP 321,将 Java 9 引入的 HttpClient 标准化
https://openjdk.org/jeps/321
java.net.http.HttpClient
接口
age jdk.internal.net.http.HttpClientImpl
实现类
https://openjdk.org/groups/net/httpclient/
发送 post json 请求示例:
public CompletableFuture<Void> postJSON(URI uri, Map<String,String> map) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
String requestBody = objectMapper
.writerWithDefaultPrettyPrinter()
.writeValueAsString(map);
HttpRequest request = HttpRequest.newBuilder(uri)
.header("Content-Type", "application/json")
.POST(BodyPublishers.ofString(requestBody))
.build();
return HttpClient.newHttpClient()
.sendAsync(request, BodyHandlers.ofString())
.thenApply(HttpResponse::statusCode)
.thenAccept(System.out::println);
- JVM DNS 缓存
- Java 常见网络异常
- BindException: Address already in use
- ConnectException: Connection refused
- SocketException: Socket is closed
- SocketException: Connection reset
- SocketException: Connection reset by peer
- SocketException: Broken pipe
- java.io.IOException: UT010029: Stream is closed
- SocketTimeoutException
- Orderly Versus Abortive Connection Release in Java
- Socket
- close()
- setSoLinger()
- InetAddress
- Java InetAddress 获取本机IP和端口号
- InetAddress.getLocalHost().getHostAddress()获取的ip为127.0.0.1
- 获取本机IP列表
- getHostName() 获取hostname
- getCanonicalHostName
- URL
- openConnection() 创建连接
- URL.openConnection() 和 URLConnection.connect()
- openStream()
- URLConnection
- connect()
- setRequestProperty() 设置请求参数
- setConnectTimeout() 设置连接超时时间
- setReadTimeout() 设置读取超时时间
- setDoOutput() 设置可写入body数据
- 使用示例
- Java HttpURLConnection 发送 GET 请求
- Java HttpURLConnection 发送 POST 请求
- Java HttpURLConnection 测试 POST 接口连通性
- Java下载图片最简单的方式
- 使用Java URL下载图片
- 使用SafeHttpURLConnection代替
- 异常
- IllegalStateException: connect in progress
- HttpURLConnection
- setRequestMethod() 设置http方法
- getResponseCode() 获取http响应码
- HttpURLConnection 长连接/持久连接/保活(keep-alive)
- HttpURLConnection 连接加入缓存过程
- HttpURLConnection 从缓存获取连接过程
- SpringBoot 内置 Tomcat 超时配置
- server.tomcat.connection-timeout
- HttpClient