Возникла проблема с многопоточным Java-приложением в Cloud Foundry

В моем приложении Java есть программа, которая одновременно выполняет несколько потоков для выполнения задачи. Он очень хорошо работает на моем локальном компьютере, поскольку у него 4 ядра и 8 логических процессоров, но когда я развертываю свое приложение в облачном хранилище, оно не позволяет создать более 1 потока. Я отлаживал и обнаружил, что Cloud Foundry JVM имеет только 1 выделенный процессор, поэтому он не может запускать несколько потоков одновременно.

Как я могу исправить эту проблему?

Нужно ли мне покупать больше процессоров или есть способ изменить конфигурацию JVM, чтобы установить несколько процессоров для приложения java.


person Gippy Aulakh    schedule 24.07.2020    source источник
comment
Количество потоков Java не должно зависеть от ядер процессора ... Какую ошибку вы получите, если запустите второй поток?   -  person saurav    schedule 13.08.2020
comment
Я не получаю никаких ошибок. Я разделил задачу на 4 потока, которые отлично работают на моем локальном ПК, поскольку для завершения требуется всего 15 минут, но когда я развертываю в CF, это занимает около 8-10 часов, даже хуже, чем последовательная (однопоточная) программа. Я обнаружил, что потоки спят очень долго (около 4 часов). Интересно, решит ли проблему настройка размера кучи.   -  person Gippy Aulakh    schedule 19.08.2020


Ответы (2)


В SAP Cloud Platform Cloud Foundry количество процессоров зависит от выделенной памяти. Вы можете получить максимальное вертикальное масштабирование 8 ГБ ОЗУ и 2 ЦП. См. Рацион в цитате ниже.

В среде Cloud Foundry приложения получают гарантированную долю ЦП в размере ¼ ядра на 1 ГБ памяти экземпляра. Поскольку максимальный объем памяти экземпляра для каждого приложения составляет 8 ГБ, это позволяет вертикальное масштабирование до 2 ЦП.

Здесь вы можете найти дополнительную информацию об .

Это блог содержит интересные сведения о тестировании производительности SCP.

Чтобы обновить квоту, перейдите в раздел обзора вашего приложения и следуйте инструкциям на снимке экрана: введите описание изображения здесь

person Artyom Kovalyov    schedule 25.07.2020
comment
Спасибо за ответ Артём. Я попытался увеличить квоту, но безуспешно. Я увеличил квоту до максимума (8 ГБ), и это дает мне 16 логических процессоров. Эти 16 логических процессоров все еще не могут выполнять мой код в параллельной обработке. После долгого исследования я обнаружил, что Cloud Foundry использует Open JDK для виртуальных машин Java, и эти виртуальные машины настроены на использование одноядерного процессора, и нам нужно настроить его вручную для использования многоядерных процессоров. Эта ссылка описывает ситуацию. Я сообщу вам, как только решу проблему. - person Gippy Aulakh; 29.07.2020
comment
Это, вероятно, пропустило мой радар, Гиппи, мне также любопытно, как вы настраиваете многоядерность для Java на CF. Я постараюсь выяснить. Кроме того, согласно документации, у вас должно быть только 2 процессора с 8 ГБ ОЗУ, где вы обнаружили, что у вас их 16? Как сказано в документации, они дают вам 0,25 процессора на каждый гигабайт оперативной памяти. - person Artyom Kovalyov; 03.08.2020
comment
Я еще не настраивал многоядерность. Я сообщу вам, как только получу ответ от SAP. int availableProcessors = Runtime.getRuntime (). availableProcessors (); дал мне доступные процессоры. - person Gippy Aulakh; 05.08.2020
comment
Это круто! Мне будет интересно узнать, каковы окончательные результаты ваших усилий по обеспечению многоядерной производительности вашего приложения. Я также спросил, как этого добиться, но пока ничего не слышал. - person Artyom Kovalyov; 06.08.2020

Я даю ответ на свой вопрос, так как разобрался в проблеме. Тупиковый поток был основной причиной проблемы. Несколько потоков одновременно вызывали одни и те же методы, и потоки попадали в ловушку, ожидая друг друга, чтобы снять блокировку. Поэтому казнь перестала отвечать. Чтобы исправить это, я изменил все методы, используемые в методе вызова Callable, чтобы иметь синхронизацию с использованием ключевого слова synchronized в объявлении метода. Теперь он отлично работает локально и в облачной среде. Единственное, чего я до сих пор не понимаю, это почему тупик происходил только в облачной среде, а не локально. Я предполагаю, что это может быть другая конфигурация JVM в облаке.

@ Артём Ковалёв, вот как я разделил задачи для параллельной обработки.

final int numberOfWorkers = 4;
List<Callable<Void>> tasks = new ArrayList<Callable<Void>>();

//code here to create and add tasks to list

final List<List<Callable<Void>>> dividedTasks = Lists.partition(tasks, numberOfWorkers);
final ExecutorService executor = Executors.newFixedThreadPool(numberOfWorkers);
for (List<Callable<Void>> subsetOfTasks : dividedTasks) {
    try {

// you can invoke all tasks in one go but I prefer invoking number of taks same as thread pool max thread number

        executor.invokeAll(subsetOfTasks);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}
executor.shutdownNow();
person Gippy Aulakh    schedule 20.08.2020