多任务spring boot restful api消耗所有服务器资源

1hdlvixo  于 2021-09-13  发布在  Java
关注(0)|答案(0)|浏览(223)

自从我使用SpringBoot开发RESTfulAPI以来,已经有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所需的服务器资源,那么我可能也会对我有所帮助。

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题