首页 > 解决方案 > 消耗所有服务器资源的多任务 Spring Boot RESTful API

问题描述

自从我使用 Spring Boot 开发 RESTful API 以来,已经有大约 2 年了。该项目已经发布。

这是我作为开发人员的第一个项目,从一开始,我就独自为这个项目的服务器端工作。在这个项目之前,我没有任何生产级项目的经验。API 工作正常。

现在我在 API 中添加了一些多任务。除了主任务(线程)之外,还有以下提到的任务(并行运行的线程):

这些所有线程都是相互独立的。

这两个任务的时间段都可以更改。

我在这里面临的主要问题是,在使用主线程运行这些任务后,几乎整个 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);
        }
}

关于目标活动和位置检查的一些注意事项:

如果我能有一些关于我应该知道的事情的指导方针可能对我也有帮助,以使服务器负载健康,比如多线程 API 所需的服务器资源。

标签: javaspringmultithreadingspring-boot

解决方案


推荐阅读