Har*_*ana 1 java spring tomcat spring-boot
我已经在spring boot embeded tomcat server中将keep alive timeout设置为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;
}
Run Code Online (Sandbox Code Playgroud)
然后我从我的休息控制器睡了40秒的请求线程.但是当我通过邮递员发出请求时,它成功返回HTTP状态代码200,而不应该返回网关超时错误.
我尝试setConnectionTimeout和setKeepAliveTimeout,它不起作用.
我在这里失踪了什么?
编辑问题:我最初的问题
让我解释一下我的原始问题,这个问题引导我提出上述问题.
好吧,我有一个很长的民意调查过程,通常运行超过5分钟.
那么当我为longpoll调用Rest API时会发生什么,在2.2分钟后我在浏览器中得到504 http错误.
我正在使用AWS环境,其中我有一个安装在AWS EC2实例中的ELB和HAProxy.
根据AWS doc,它表示ELB的默认空闲连接超时为60秒.所以我把它增加到最多30分钟.
而且它说,
如果您使用HTTP和HTTPS侦听器,我们建议您为EC2实例启用keep-alive选项.您可以在Web服务器设置或EC2实例的内核设置中启用keep-alive.
因此,将上面的代码片段中的嵌入式tomcat保持活动超时增加到30.2分钟
所以现在我希望我的长轮询请求能够完成,而不会出现504错误.但是我仍然在浏览器中出现504错误?
参考:AWS开发指南
看起来您想关闭可能在移动设备上发生的放弃的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;
}
}
Run Code Online (Sandbox Code Playgroud)
连接超时已设置为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;
}
}
Run Code Online (Sandbox Code Playgroud)
将包的日志级别设置org.apache.catalina.core为DEBUG
logging.level.org.apache.catalina.core=DEBUG
Run Code Online (Sandbox Code Playgroud)
你可以看到一个SocketTimeoutException用于slowConnection测试.
我不知道为什么你想要HTTP状态代码502作为错误响应状态.HTTP 502说:
502(错误网关)状态代码表示服务器在充当网关或代理时,在尝试完成请求时从其访问的入站服务器收到无效响应.
客户端Postman调用您的服务器应用程序 我之间没有看到任何网关或代理.
如果您只是将问题简化为最低限度,并且实际上您想要自己构建代理,则可以考虑使用Netflix Zuul.
2016年3月23日更新:
这是OP在Stackoverflow上的问题的根本原因:
我用longpolling做的是,从服务api,我睡了一段时间并唤醒它并一次又一次地做,直到一些db状态完成.
该实现实际上阻止了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);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9081 次 |
| 最近记录: |