大佬教程收集整理的这篇文章主要介绍了Springboot TomcatEmbeddedServletContainer KeepAliveTimeout不起作用,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
看来您想关闭移动设备上可能发生的废弃http连接。
@RestController
@SpringBootApplication
public class DemoApplication {
public static voID main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
public EmbeddedServletContainerFactory getEmbeddedServletContainerFactory() {
tomcatEmbeddedServletContainerFactory containerFactory = new tomcatEmbeddedServletContainerFactory();
containerFactory
.addConnectorCustomizers(new tomcatConnectorCustomizer() {
@OverrIDe
public voID customize(Connector connector) {
((AbstractProtocol) connector.getProtocolHandler()).setConnectionTimeout(100);
}
});
return containerFactory;
}
@requestMapPing
public String echo(@requestbody String body) {
return body;
}
}
连接超时已设置为100毫秒,以便快速运行测试。数据按块发送。在每个块之间,正在运行的线程被挂起x毫秒。
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = DemoApplication.class)
@WebIntegrationTest("server.port:19000")
public class DemoApplicationTests {
private static final int CHUNK_SIZE = 1;
private static final String HOST = "http://localhost:19000/echo";
@Rule
public ExpectedException expectedException = ExpectedException.none();
@Test
public voID slowConnection() throws Exception {
final httpURLConnection connection = openChunkedConnection();
OutputStreamWriter out = new OutputStreamWriter(connection.getoutputStream());
writeAnDWait(500, out, "chunk1");
writeAnDWait(1, out, "chunk2");
out.close();
expectedException.expect(IOException.class);
expectedException.expectmessage("Server returned http response code: 400 for URL: " + HOST);
assertResponse("chunk1chunk2=", connection);
}
@Test
public voID fastConnection() throws Exception {
final httpURLConnection connection = openChunkedConnection();
OutputStreamWriter out = new OutputStreamWriter(connection.getoutputStream());
writeAnDWait(1, out, "chunk1");
writeAnDWait(1, out, "chunk2");
out.close();
assertResponse("chunk1chunk2=", connection);
}
private voID assertResponse(String expected, httpURLConnection connection) throws IOException {
ScAnner scAnner = new ScAnner(connection.geTinputStream()).useDelimiter("\\A");
Assert.assertEquals(expected, scAnner.next());
}
private voID writeAnDWait(int millis, OutputStreamWriter out, String body) throws IOException, InterruptedException {
out.write(body);
Thread.sleep(millis);
}
private httpURLConnection openChunkedConnection() throws IOException {
final URL url = new URL(HOST);
final httpURLConnection connection = (httpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setChunkedStreamingMode(CHUNK_SIZE);
return connection;
}
}
将包的日志级别设置org.apache.catalina.core
为DEBUG
logging.level.org.apache.catalina.core=DEBUG
您会看到一个SocketTimeoutException
要slowConnection
测试的。
我不知道为什么要使用http状态代码502作为错误响应状态。http 502说:
客户端Postman
调用您的服务器应用程序。我看不到两者之间的任何网关或代理。
如果您只是将问题压缩到最低限度,而实际上您想自己构建一个代理,则可以考虑使用Netflix Zuul。
这是OP关于Stackoverflow的问题的根本原因:
该实现实际上阻止了tomcat工作线程处理新的http请求。因此,每增加一个长时间运行的操作,您的请求吞吐量就会降低。
我建议将长时间运行的操作卸载到单独的线程中。客户端(浏览器)启动一个新请求以获取结果。根据处理状态,服务器将返回结果或通知/错误/警告/。
这是一个非常简单的示例:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.Annotation.PathVariable;
import org.springframework.web.bind.Annotation.requestMapPing;
import org.springframework.web.bind.Annotation.requestMethod;
import org.springframework.web.bind.Annotation.RestController;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executorservice;
import java.util.concurrent.Executors;
import static org.springframework.http.httpStatus.CREATED;
import static org.springframework.http.httpStatus.NOT_FOUND;
import static org.springframework.http.httpStatus.OK;
@RestController
@SpringBootApplication
public class DemoApplication {
public static voID main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
private Executorservice executorservice = Executors.newFixedThreadPool(10);
private Map<String, String> results = new ConcurrentHashMap<>();
@requestMapPing(path = "put/{key}", method = requestMethod.POST)
public ResponseEntity<VoID> put(@PathVariable String key) {
executorservice.submit(() -> {
try {
//simulate a long running process
Thread.sleep(10000);
results.put(key, "success");
} catch (InterruptedException E) {
results.put(key, "error " + e.getmessage());
Thread.currentThread().interrupt();
}
});
return new ResponseEntity<>(CREATED);
}
@requestMapPing(path = "get/{key}", method = requestMethod.GET)
public ResponseEntity<String> get(@PathVariable String key) {
final String result = results.get(key);
return new ResponseEntity<>(result, result == null ? NOT_FOUND : OK);
}
}
我已经将嵌入tomcat服务器的Spring Boot中的保持活动超时设置为30秒。所以我在下面的Application.java中使用
@Bean
public EmbeddedServletContainerFactory getEmbeddedServletContainerFactory() {
tomcatEmbeddedServletContainerFactory containerFactory = new tomcatEmbeddedServletContainerFactory();
containerFactory
.addConnectorCustomizers(new tomcatConnectorCustomizer() {
@Override
public void customize(Connector connector) {
((AbstractProtocol) connector.getProtocolHandler())
.setKeepAliveTimeout(30000);
}
});
return containerFactory;
}
然后我从我的休息控制器睡了一个请求线程40秒钟。但是,当我通过邮递员发出请求时,它成功返回http状态代码200,而应返回网关超时错误。
我同时尝试了setConnectionTimeout和setKeepAliveTimeout,但它没有用。
我在这里想念什么?
编辑问题:我最初的问题
让我解释一下我的原始问题,这使我提出了上述问题。
好吧,我有一个漫长的投票过程,通常运行大约5 minits。
因此,发生什么事是当我为longpoll调用Rest API时,在经过2.2次微型操作后,我在浏览器中收到504 http错误。
我正在使用一个AWS环境,其中有一个ELB和一个安装在AWS EC2实例中的HAProxy。
根据AWS文档, ELB的默认空闲连接超时为60秒 。因此,我将其最多增加了30分钟。
而且它说,
因此,将上述代码段之类的嵌入式tomcat保持活动超时时间增加到30.2分钟
因此,现在我希望我的长时间轮询请求能够完成,并且不会出现504错误。但是我在浏览器中仍然收到504错误吗?
参考:AWS开发人员指南
以上是大佬教程为你收集整理的Springboot TomcatEmbeddedServletContainer KeepAliveTimeout不起作用全部内容,希望文章能够帮你解决Springboot TomcatEmbeddedServletContainer KeepAliveTimeout不起作用所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。