我有以下代码:
var threadsWaiter = new CountDownLatch(customers.size());
for(var c: List<Customer> customers) {
sendSms(c.phoneNr, threadsWaiter)
}
threadsWaiter.await();
public void sendSms(String phoneNr, CountDownLatch threadsWaiter) {
ResteasyClientBuilder.newClient()
.target(smsUrl)
.queryParam("to", phoneNr)
.queryParam("message", message)
.request()
.async()
.get(new InvocationCallback<String>() {
@Override
public void completed(String res) {
threadsWaiter.countDown();
if (res != null && !res.contains("code=ok") {
logger.error("Received sms response for '{}'\n{}", phoneNr, res);
} else {
logger.debug("Sms sent to '{}'", phoneNr);
}
}
@Override
public void failed(Throwable throwable) {
threadsWaiter.countDown();
logger.error("Error sending sms for {}: \n{}", phoneNr, throwable.getMessage());
}
});
}
Run Code Online (Sandbox Code Playgroud)
我从控制台收到以下警告:
RESTEASY004687: Closing a class org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient43Engine instance for you. Please close clients yourself.
关闭此客户端调用的正确方法是什么?因为这可能是应用程序中潜在内存泄漏的来源。甚至我从 RestEasy 收到了这个警告,它会自动为我关闭客户端,但我有一种强烈的感觉,它不会关闭所有客户端,因为我看到指标中的内存大幅增加,这不会“去下来”一段时间后。
我已经在 try-finally 之间放置了其余的客户端调用,但问题在于您可以在调用完成之前关闭客户端。可以关闭InvocationCallback 中的客户端completed(..)和failed(..)方法,还是有更好的方法?
使用 Quarkus 执行此操作的最佳方法是使用具有异步支持的 REST 客户端。例子:
/**
* This is the client stub.
*/
@Path("/sms/response") // base URL is set in application.yml
@RegisterRestClient
public interface SmsServiceClient {
@GET
@Produces(MediaType.TEXT_PLAIN)
CompletionStage<String> sendSms(
@QueryParam("to") String phoneNr,
@QueryParam("message") String message);
}
Run Code Online (Sandbox Code Playgroud)
在下面的示例中,我使用SmallRye Mutiny将 转换CompletionStage为Uni具有更精简 API 的 。但您可以使用CompletionStage. 通常,我不会用该CountDownLatch.await()方法阻止执行。我把它放在那里是为了保持代码与您的示例相似。
/**
* This class will actually use the client.
*/
@Slf4J
@ApplicationScoped
public class MySomething {
@Inject
@RestClient
SmsServiceClient smsClient;
public void sendSmsInLoop() {
var waiter = new CountDownLatch(customers.size());
customers.forEach(customer -> {
Uni.createFrom().completionStage(
smsClient.sendSms(customer.getPhoneNr(), "Lorem Ipsum...")
).onItem().invoke(responseString -> {
if (responseString == null || !responseString.contains("code=ok")) {
log.error("Unexpected sms response for '{}'\n{}", customer.getPhoneNr(), responseString);
} else {
log.debug("Sms sent to '{}'", customer.getPhoneNr());
}
}).onFailure().invoke(throwable -> {
log.error("Error sending sms to '{}'\n{}", customer.getPhoneNr(), throwable.getMessage());
}).eventually(() -> waiter.countDown());
});
waiter.await();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1348 次 |
| 最近记录: |