我們正在使用Spring引導來發展我們servies。我們選擇做在一個異步的方式,我們都面臨着以下問題:我們有以下方面對我們所有的異步其餘資源的頂部:春季啓動DeferredResult方面使得CPU去比天高
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.async.AsyncRequestTimeoutException;
import org.springframework.web.context.request.async.DeferredResult;
@Aspect
@Component
public class TerminatedUsersAspect {
private static final Logger LOGGER = LoggerFactory.getLogger("[TERMINATED_USERS]");
public static final ThreadLocal<String> ID_LOCAL = new ThreadLocal<>();
@Autowired
private UserRepository userRepo;
@Autowired
private UserService userService;
@Autowired
private ExecutorService executorService;
@SuppressWarnings("unchecked")
@Around("within(com.test..*) && @annotation(authorization)")
public Object checkForId(ProceedingJoinPoint joinPoint, Authorization authorization) throws Throwable {
final MethodInvocationProceedingJoinPoint mJoinPoint = (MethodInvocationProceedingJoinPoint) joinPoint;
final MethodSignature signature = (MethodSignature) mJoinPoint.getSignature();
final DeferredResult<Object> ret = new DeferredResult<>(60000L);
final String id = ID_LOCAL.get();
if (signature.getReturnType().isAssignableFrom(DeferredResult.class) && (id != null)) {
userRepo.getAccountStatus(id).thenAcceptAsync(status -> {
boolean accountValid = userService.isAccountValid(status, true);
if (!accountValid) {
LOGGER.debug("AccountId: {} is not valid. Rejecting with 403", id);
ret.setErrorResult(new ResponseEntity<String>("Invalid account.", HttpStatus.FORBIDDEN));
return;
}
try {
final DeferredResult<Object> funcRet = (DeferredResult<Object>) joinPoint.proceed();
funcRet.setResultHandler(r -> {
ret.setResult(r);
});
funcRet.onTimeout(() -> {
ret.setResult(new AsyncRequestTimeoutException());
});
} catch (Throwable e) {
ret.setErrorResult(ret);
}
}, executorService).exceptionally(ex -> {
ret.setErrorResult(ex);
return null;
});
return ret;
}
return joinPoint.proceed();
}
}
我們在應用嵌入式服務器是暗流。問題隨着時間而出現。看起來在經過將近一天之後,由於這方面的原因,CPU實際上最終會紅起來100%。我調試了代碼,從我的角度來看似乎很好,但也許我錯過了一些東西? 任何想法都會受到歡迎。謝謝, C.
我同意everyathing在這裏說。你似乎太寬泛地應用了這個方面,大的「if」和所有昂貴的反射材料都沒有必要。那麼'if()'後面的'proceed()'首先是不必要的,但是如果你使用它,至少把它放到'else'分支中。我會爲你準備一些小樣本。 – kriegaex