python server에 요청 많이 보내니까 시간도 오래 걸리고 처리가 안돼서 client에서 시간 보내다가 timeout이 발생.
spring에서 grpc pool 만들어서 pool size 조절해서 python이 순차적으로 처리할 수 있도록 만들었음. 병렬처리를 순차처리로 역설계...
이미지 사이즈도 client에서 resize해서 작게 만들었음. python 처리 시간을 줄이기 위해서.
gRPC stub을 통해 요청이 마구마구 날아갈 수 있는데 stub 객체를 하나만 쓸 수 있게 만듬.
이렇게 만들면 gRPC를 쓰는 이유도 없고 서버가 한번에 한 요청만 처리할 수 있는 몹시 나쁜 구조지만 AI 이미지 생성이 느려서 모든 요청을 처리하지 못하는 것보다는 낫다는 판단으로 어쩔 수 없었음.
추후에 GPU를 연결해서 AI처리 속도를 높이면 그때는 설계대로 복구할 예정
public class GrpcStubPool {
private final ManagedChannel channel;
private final BlockingQueue<CreateImageGrpc.CreateImageBlockingStub> stubPool;
private final String aiUrl = System.getenv("AI_URL");
private final int poolSize = 1;
public GrpcStubPool() {
this.channel = ManagedChannelBuilder.forTarget(aiUrl).usePlaintext().build();
this.stubPool = new ArrayBlockingQueue<>(poolSize);
for (int i = 0; i < poolSize; i++) {
CreateImageGrpc.CreateImageBlockingStub stub = CreateImageGrpc.newBlockingStub(channel);
stubPool.offer(stub);
}
}
public CreateImageGrpc.CreateImageBlockingStub getStub() throws InterruptedException {
return stubPool.take();
}
public void returnStub(CreateImageGrpc.CreateImageBlockingStub stub) throws InterruptedException {
stubPool.put(stub);
}
@PreDestroy
public void close() {
channel.shutdown();
}
}
파이썬이 이미지 하나 만들어서 response를 보내면 해당 service가 stub을 반납함.
기다리던 다른 service가 stub을 가져가서 사용하고 response 받으면 stub을 반납함.
pool size를 하나로 만들었음.
try {
imageStub = grpcStubPool.getStub();
Image.OriginalImageInfo buildImageInfo = Image.OriginalImageInfo.newBuilder()
.setOriginalImage(imageData)
.setOptions(options)
.build();
System.out.println(buildImageInfo.getOptions().getSex());
receiveData = imageStub.sendImage(buildImageInfo);
} catch (IllegalStateException | InterruptedException e) {
throw ApiExceptionFactory.fromExceptionEnum(ImageExceptionEnum.GRPC_ERROR);
}
if (Image.ImageProcessingResult.SUCCESS.equals(receiveData.getResult())) {
byte[] processedImageData = receiveData.getProcessedImage().toByteArray();
ByteArrayResource byteArrayResource = getBufferedImage(processedImageData,768,1024);
Image.ResponseUrl responseUrl = receiveData.getResponseUrl();
ImageInfo imageInfo = new ImageInfo(
userId,
responseUrl.getOriginalImageUrl(),
responseUrl.getThumbnailImageUrl(),
responseUrl.getProcessedImageUrl(),
optionStore.get()
);
ImageInfo insertResult = imageRepository.insertImageUrls(imageInfo,optionStore.get());
log.info("DB insert Image info : " + insertResult.getImageInfoId());
CreateImageDto imageInfoDto = new CreateImageDto(
imageInfo.getImageInfoId(),
imageInfo.getThumbnailImageUrl(),
imageInfo.getOriginalImageUrl(),
imageInfo.getProcessedImageUrl(),
byteArrayResource
);
try{
grpcStubPool.returnStub(imageStub);
} catch (InterruptedException e){
ApiExceptionFactory.fromExceptionEnum(GrpcExceptionEnum.NO_STUB);
}
return imageInfoDto;