【发布时间】:2021-02-16 12:50:55
【问题描述】:
我在发送身份验证请求的 Spring Boot 应用程序中使用 Callable 接口:
public class TestCallable implements Callable<TestDto> {
TestEntity testEntity;
public TestCallable(TestEntity testEntity) {
this.testEntity = testEntity;
}
@Override
public TestDto call() throws Exception {
String authRequestBody = "{" +
"\"username\": \"" + testEntity.getLogin() + "\"," +
"\"password\": \"" + testEntity.getPassword() + "\"," +
"\"client_id\": \"" + testEntity.getClientId() + "\"," +
"\"client_secret\": \"" + testEntity.getClientSecret() + "\"" +
"}";
HttpHeaders authHeaders = new HttpHeaders();
authHeaders.setContentType(MediaType.APPLICATION_JSON);
authHeaders.set("Accept", "application/json");
authHeaders.set("Grant_type", "password");
HttpEntity<String> authEntity = new HttpEntity<String>(authRequestBody, authHeaders);
RestTemplate restTemplate = new RestTemplate();
TestDto testDto = testDto = restTemplate.postForObject(testEntity.getEndpoint(), authEntity, TestDto.class);
return testDto;
}
}
我在 4 个线程中发送这些请求:
List<Future<TestDto>> futuresList = new ArrayList<Future<TestDto>>();
ExecutorService pool = Executors.newFixedThreadPool(4);
for (Integer i=0; i<4; i++) {
Callable<TestDto> callable = new TestCallable(testEntity);
Future<TestDto> future = pool.submit(callable);
futuresList.add(future);
}
问题是有时我会收到错误“401 Unauthorized: [no body]”。例如,我可以从 4 个可调用作业中接收 4 个令牌 5 次,并在第 6 次尝试时收到错误。
如果我将线程数更改为 2,则错误的频率会降低。每次有 10 个线程失败。
而且它在 Postman 中总是可以正常工作。
如何理解问题的原因?
【问题讨论】:
-
您是否一直发送完全相同的数据,有时会出错?
-
@SergeiTonoian 是的,完全正确
-
这对我来说听起来像是一种竞争条件。例如通过传递给可调用对象的 testEntity 对象的并发修改。池中的更多线程 => 更快的执行和更高的竞争条件风险。端点是您自己的吗?也许有任何访问限制,例如每次最多?!
-
在将所有内容提交到线程池后,您是否在任何地方修改了TestEntity?尝试将 TestEntity 的所有字段声明为 final。
-
@Indivon 我从 Callable 调用的端点不是我的。将来,我将使用相同的身份验证令牌,而不是每次都调用此请求。如果它是每个时间限制的最大值,它将被修复。但我现在想确定。
标签: java spring-boot resttemplate callable