I am trying to lift an OptaPlanner project into the cloud as an Azure Function. My goal in this would be to enhance the scaling so that our company can process more solutions in parallel.
Background: We currently have a project running in a Docker container using the optaplanner-spring-boot-starter
MVN package. This has been successful when limited to solving one solution at a time. However, we need to dramatically scale the system so that a higher number of solutions can be solved in a limited time frame. Therefore, I'm looking for a cloud-based solution for the extra CPU resources needed.
I created an Azure Function using the optaplanner-core
MVN package and our custom domain objects for our existing solution as a proof of concept. The Azure Function uses an HTTP trigger, this seems to work to get a solution, but the performance is seriously degraded. I'm expecting to need to upgrade the consumption plan so that we can specify CPU and memory requirements. However, it appears that Azure is not scaling out additional instances as expected leading to OptaPlanner blocking itself.
Here is the driver of the code:
@FunctionName("solve")
public HttpResponseMessage run(
@HttpTrigger(name = "req", methods = {HttpMethod.POST },authLevel = AuthorizationLevel.FUNCTION)
HttpRequestMessage<Schedule> request,
final ExecutionContext context) {
SolverConfig config = SolverConfig.createFromXmlResource("solverConfig.xml");
//SolverManagerConfig managerConfig = new SolverManagerConfig().withParallelSolverCount("2");
//SolverManagerConfig managerConfig = new SolverManagerConfig().withParallelSolverCount("10");
//SolverManagerConfig managerConfig = new SolverManagerConfig().withParallelSolverCount("400");
SolverManagerConfig managerConfig = new SolverManagerConfig().withParallelSolverCount("AUTO");
SolverManager<Schedule, UUID> solverManager = SolverManager.create(config ,managerConfig);
SolverJob<Schedule, UUID> solverJob = solverManager.solve(UUID.randomUUID(), problem);
// This is a blocking call until the solving ends
Schedule solution = solverJob.getFinalBestSolution();
return request.createResponseBuilder(HttpStatus.OK)
.header("Content-Type", "application/json")
.body(solution)
.build();
}
Question 1: Does anyone know how to set up Azure so that each HTTP call causes a scaling out of a new instance? I would like this to happen so that each solver isn't competing for resources. I have tried to configure this by setting FUNCTIONS_WORKER_PROCESS_COUNT=1
and maxConcurrentRequests=1
. I have also tried changing OptaPlanners parallelSolverCount
and moveThreadCount
to different values without any noticeable differences.
Question 2: Should I be using Quarkus with Azure instead of the core MVN package? I've read that Geoffrey De Smet answered, "As for AWS Lambda (serverless): Quarkus is your friend".
I'm out of my element here as I haven't coded with Java for over 20 years AND I'm new to both Azure Functions and OptaPlanner. Any advice would be greatly appreciated.
Thanks!