grpc 잘못 사용함 ㅠㅠ

박근수·2024년 4월 21일
0

ssafy_특화

목록 보기
1/2

python server에 요청 많이 보내니까 시간도 오래 걸리고 처리가 안돼서 client에서 시간 보내다가 timeout이 발생.
spring에서 grpc pool 만들어서 pool size 조절해서 python이 순차적으로 처리할 수 있도록 만들었음. 병렬처리를 순차처리로 역설계...

  1. Python이 여러 요청을 한번에 처리하려고 하는데 Image processing에 어차피 시간 오래 걸리는데 한번에 하다보니 하나도 만들지 못하고 time out이 발생해버렸음.
  2. 이럴바에 하나씩 완성해서 응답하기로 함.
  3. gRPC pool size를 1개로 만들어서 spring에서 요청을 동기적으로 보내도록 만들었음.

이미지 사이즈도 client에서 resize해서 작게 만들었음. python 처리 시간을 줄이기 위해서.

gRPC stub을 통해 요청이 마구마구 날아갈 수 있는데 stub 객체를 하나만 쓸 수 있게 만듬.

이렇게 만들면 gRPC를 쓰는 이유도 없고 서버가 한번에 한 요청만 처리할 수 있는 몹시 나쁜 구조지만 AI 이미지 생성이 느려서 모든 요청을 처리하지 못하는 것보다는 낫다는 판단으로 어쩔 수 없었음.

추후에 GPU를 연결해서 AI처리 속도를 높이면 그때는 설계대로 복구할 예정

grpc Stub

 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를 하나로 만들었음.

gRPC Client

 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;
profile
개성이 확실한편

0개의 댓글