java - 消耗所有服务器资源的多任务 Spring Boot RESTful API
问题描述
自从我使用 Spring Boot 开发 RESTful API 以来,已经有大约 2 年了。该项目已经发布。
这是我作为开发人员的第一个项目,从一开始,我就独自为这个项目的服务器端工作。在这个项目之前,我没有任何生产级项目的经验。API 工作正常。
现在我在 API 中添加了一些多任务。除了主任务(线程)之外,还有以下提到的任务(并行运行的线程):
- 一个任务(线程)检查数据库是否存在活动的目标活动,如果有,则它将检查数据库中是否存在此目标活动的目标用户。如果没有活动的广告系列,则不会进行用户搜索,但此线程将继续查看是否已在 5 秒内一直放置新的有针对性的广告系列。对于每个有针对性的活动,将启动一个新线程(我假设这将导致 CPU 消耗最多)
- 另一个任务每 5 秒检查一次用户的位置
这些所有线程都是相互独立的。
这两个任务的时间段都可以更改。
我在这里面临的主要问题是,在使用主线程运行这些任务后,几乎整个 CPU 都被消耗(~95%),而用户没有任何活动。我停止了并行线程以查看情况如何改变,结果发现主线程仅消耗了 9-10% 的 CPU。这表明并行任务(线程)消耗大约 70-80% 的 CPU(我假设是因为它们不断检查数据库和用户位置。)另一方面,只有用户处于活动状态的主线程处于活动状态。
考虑到所有踏板都在运行但仍然无法解决它,我正在尝试自己减少 CPU 消耗。我尝试在 Stackeoverflow 中在线和此处搜索,特别是这个问题已关闭,不幸的是,使用它有帮助,我无法解决我的问题。我不确定,但在想,我是否应该增加服务器中的资源(如处理器核心)?
这就是为什么我正在寻找一些帮助、建议、意见或指导,这可以帮助我解决这个问题。或者至少有一些提示或提示我应该如何着手解决这个问题。
在项目中我使用的是 PostgreSQL 数据库。
如果这个问题的形成不是那么容易理解,请评论一下,我会尽力解释。
发送有针对性的礼物(活动)的代码:
public void sendSuperTargetedGift(Gift gift){
SuperTargetedGiftCourier superTargetedGiftCourier = new SuperTargetedGiftCourier(userRepository, giftService, userLocationRepository,
locationRepository, userGiftService, giftRepository, notificationsRepository, userAgeTester, imageRepository);
superTargetedGiftCourier.setGift(gift);
taskExecutor.execute(superTargetedGiftCourier);
}
运行方法:
@Override
public void run() {
try {
Location location = locationRepository.getLocationByGiftIDForGiftWhoHasOnlyOneLocation(gift);
int count = location.getGiftCount();
int giftID = gift.getGiftID();
int taken;
while (giftAvailable(gift)) {
Set<Integer> targetedUser = giftService.targetedUsers(gift);
List<User> users = getOrderedUsersByLastLocationUpdate();
if(users.size() > 0){
for (User user : users) {
try {
if(giftAvailable(gift)){
int userID = user.getUserID();
if (!userGiftService.IsUserHaveThisGift(giftID, userID) && ageCheck(gift, userID)
&& !notificationsRepository.getByNotificationByUserIdAndGiftIdForSuperTargetedGift(userID, gift.getGiftID()).isPresent())
{
//make sure user has location in database
if(userLocationRepository.getByUserUserID(userID).isPresent()){
UserLocation userLocation = userLocationRepository.getByUserUserID(userID).get();
double latitude = userLocation.getUserLatitude();
double longitude = userLocation.getUserLongitude();
if (giftService.userUnderSuperTargetedCriteria(userID, gift, latitude, longitude, targetedUser)){
giftService.setSuperTargetedNotification(userID, gift);
Location n_location = locationRepository.getLocationByGiftIDForGiftWhoHasOnlyOneLocation(gift);
taken = n_location.getGiftCollected();
if(count == taken || new Date().after(gift.getGiftDateMapEnd())){
break;
}
}
}
}//end of outer if block
}
else {
return;
}
}
catch (Exception e){
System.out.println("Exception super target gift sending: " + e);
}
}//end for loop
}
}
}
catch (Exception e) {
System.out.println("Super targeted gift sending exception: " + e);
}
}
关于目标活动和位置检查的一些注意事项:
- 正如它所提到的,只有存在现有的目标广告系列才会运行,否则它不会运行,但如果出现新的目标广告系列,它会检查数据库。到目前为止,还没有任何目标广告系列。因此,到目前为止,服务器 CPU 消耗仅用于检查数据库中的目标活动。
- 类似的位置检查。只有在有条件的情况下才会发生。而为此,在数据库中还没有满足检查用户位置的必要条件。因此位置检查线程正在检查条件是否已出现在数据库中。
如果我能有一些关于我应该知道的事情的指导方针可能对我也有帮助,以使服务器负载健康,比如多线程 API 所需的服务器资源。
解决方案
推荐阅读
- python - StratifiedKFold的混淆矩阵和分类报告
- swift - 如果调用 NSApp.terminate,是否会清理 DispatchQueue 线程?
- json - 使用vue和axios post到json文件问题
- javascript - 遍历json对象的所有元素
- css - 如何在多行中获得 33.33% 宽度的 flex div?
- c# - 从 CSV 读取值数字格式
- php - Imagick 的 'thumbnailImage' 功能不起作用
- javascript - 不允许启动 AudioContext。AngularJS 记录器 Chrome 71
- google-maps - Flutter - 拖动标记并获得新位置
- python - 合并两个数据框python