Spring protobuf 부분 로딩 오류 해결(GCP Storage Signed Url)
서버개발

Spring protobuf 부분 로딩 오류 해결(GCP Storage Signed Url)

서버에서 클라이언트로 사진, 음원, 영상을 보내야하는 작업이 있었다.

영상을 서버에 저장해서 클라이언트로 보내는 것은 서버에 큰 부하가 있기 때문에 GCP Storage에 영상을 저장하고 해당 링크를
클라이언트로 보내주기로 했다.

Storage를 사용하면 영구히 변하지 않는 PublicUrl을 제공하는 방법과 만료 시간을 정할 수 있는 SignedUrl을 제공하는 방법이 있다. PublicUrl이 주어지면 이를 클라이언트 단에서 탈취해 부적절한 접근을 할 수 있으므로 SignedUrl을 사용하기로 했다.

송신하는 응답 패킷에는 SignedUrl을 사용하는 필드가 3개 있었는데, SignedUrl로 변경하자마자 클라이언트단에서 데이터 중 일부를 받지 못하는 상황이 발생했다.

패킷이라면 일부가 전송이 실패하면 모든 패킷이 도달하지 못해야하는데 일부 데이터만 전송되는 것이 의아했고 원인을 찾아보니 signed url이 800자 가까이 되었고, 하나의 오브젝트가 2,000byte를 넘는 상황이 발생했다.

패킷은 페이징 처리가 되어있어 클라이언트에서 원하는 만큼 데이터를 요청할 수 있는데, 클라이언트에서 100개를 요청하자 200,000byte가 요청되었고 이를 압축한채로 전송이 되었다.

그러나 서버단에서 압축하기 전 사이즈를 알려주지 않아 클라이언트는 160,000byte를 맥시멈으로 잡아두었고(이 크기를 넘지 않으리라 판단하여 임의로) 압축된 메시지가 도착하여 압축 해제를 하자 사이즈에 넘치는 데이터는 제외하고 나머지 데이터만 담겨서 생긴 문제였다.

이를 해결하기 위해 네 가지 방법을 생각하였다.

1. Url 압축 사이트 API를 호출하여 해당 SignedUrl을 압축시킨다
- 이 방법은 bit.ly, tiny-url 등 여러가지 사이트 API가 존재한다. 그러나 로그인 후 토큰을 필요로 하는 사이트들이 있었는데, 프로 젝트에 내 개인 토큰을 사용하는 것은 적절하지 않으리라 판단하여 토큰이 필요없는 tiny-url을 선택하였다.
- 이로 인해 url이 약 800자에서 20자 정도로 줄어드는 효과를 얻을 수 있었으나, 외부 API 호출로 인해 90ms 정도 걸리던 호출이 800ms가 걸리게 되었다.
- 그렇기 때문에 100개를 호출한다면 (페이징 처리를 하기 때문에 한 번에 100개를 호출할 일은 거의 없으나) 80초 가량이 걸리는 것이다. 이를 해결하기 위해 2번 방법을 생각해본다.

2. 얻게된 SignedUrl들을 tiny-url로 변환 시 병렬스트림으로 처리한다
- 해당 방법은 Java의 ParallelStream을 이용하여 변환 시 여러 쓰레드를 이용하는 것이다. 서버 컴퓨터의 성능에 따라 다르겠지만 cpu가 5800x인 컴퓨터로는 10배정도 빠른 성능을 보였다. 그러나, 유저가 많다면 ParellelStream의 성능 이슈가 발생할 수 있다.
결국 서버의 쓰레드 수는 정해져있고 유저가 많아지면 비슷한 성능을 보일 것이다.

3. 자주 사용되는 정적 리소스는 signed url이 아닌 public url을 사용
- 이전에는 영상 뿐만이 아닌 모든 사진과 음원까지 SignedUrl로 제공하려고 했고, 이들이 모두 위의 상황을 초래하였다. 그렇기 때문에 해당하는 부분들은 따로 버킷을 판 다음 PublicUrl로 접근하도록 구성하였다.

4. 서버에서 압축되기 전 사이즈를 담아 클라이언트 단에서 압축을 해제하기 전 버퍼 사이즈를 늘리도록 설정
- 애초에 url을 신경쓰지 않도록 소켓 통신에 대한 설정을 해두는 것이다. 이로 인해 압축된 패킷을 받더라도 정상적으로 사이즈를 책정할 수 있고 기존의 문제가 발생하지 않을 것이다. 그러나 이는 권한 밖이라 행하지는 못했다.


'서버개발' 카테고리의 다른 글

벌크 연산과 @Modifying 어노테이션  (0) 2023.02.28
비관적 락, 낙관적 락  (3) 2023.02.28
SpringBoot JUnit5 테스트 및 어노테이션  (0) 2023.02.10
Protobuf(Protocol Buffers)와 RPC  (0) 2023.02.07
GraalVM 소개  (0) 2023.02.01