스프링부트 + SQS + LAMBDA 배포하며 어려웠던 점

코코코딩을 합시다·2024년 8월 1일

1 자바? 파이썬?

  • 람다는 보통 콘솔 코드 편집기를 통해 파이썬으로 코드를 작성하는데, 자바와 같은 컴파일 언어는 코드편집기에서 편집을 지원하지 않는다. (원래 람다에 컴파일 언어가 적합하진 않다고 한다.)

  • 그래서 파이썬으로 코드를 다시 작성해야 하나 고민했는데, 첫번째론 파이썬으로 개발해본 적이 없어 숙련도 이슈가 있었고, 자바로 작성했을 때 성능이 더 우수한 면도 있어서 어떻게든 띄워보기로 했다.

따라서 종속성을 포함한 빌드 파일을 zip 파일로 올려야 하는데, 용량이 50메가를 넘어 업로드가 되지 않았다. 10메가를 넘으면 S3를 통한 업로드를 권장한다고 한다.

S3 버킷에 빌드 파일을 객체로 업로드하고, 버킷 url을 람다 코드에 올려서 배포는 간단히 끝났다. (결론은 쉽지만 항상 결론에 도달하는 과정이 어렵다)

2 주입이 안돼요 ..

Cannot invoke "com.goormy.hackathon.repository.UserRepository.findById(Object)" because "this.userRepository" is null

Spring application context 에서 빈이 제대로 주입되지 않는 오류가 발생했다.
FunctionInvoker을 사용하여 해결하였다. FunctionInvoker은 Spring Cloud Function의 일부로 Spring Context를 관리하고 람다 환경에서 스프링 애플리케이션 실행을 도와준다.

implementation 'org.springframework.cloud:spring-cloud-function-adapter-aws:3.2.7'

람다에 올릴 핸들러 클래스는 FunctionInvoker를 상속하게 하였고, 실제 로직은 Spring Cloud Function 클래스에 작성하였다.

FunctionInvoker를 상속받은 FollowHandler은 AWS Lambda와 Spring Cloud Function 사이의 다리 역할을 한다. 정확히는 FunctionInvoker을 상속 받은 클래스는 Lambda 함수의 엔트리 포인트로 동작하며, Lambda 이벤트를 받아서 Spring Cloud Function으로 라우팅한다.

동작 흐름은 다음과 같다.

  1. Lambda가 트리거될 때 핸들러로 등록해놓은 FollowHandler가 호출되고, 이는 부모 클래스인 FunctionInvoker의 동작을 따른다.

  2. FunctionInvoker는 Spring Application Context 를 초기화하고 Function 에서 사용하는 빈이 컨텍스트에 로드된다.

  3. Function에서 정의된 함수형 빈으로 이벤트가 전달되면 해당 함수가 실행된다.

즉, FollowHanlder는 람다의 이벤트 처리에 특화된 핸들러로 스프링과 람다의 연결 역할만 하므로 별도의 로직이 필요 없다.

@Configuration을 달아야 스프링 관리 하로 들어가 빈을 생성할 수 있고, 함수형 빈을 Bean으로 등록할 수 있게 된다.

요기서 도움을 받았다.

3 15초가 초과돼 람다가 종료됨

이건 걍 람다 제한 시간을 15초에서 늘려주기만 하면 된다.. 물론 어떤 문제가 있어서 15초 이상이 걸리는거기 때문에 이렇게 수정한다고 문제가 바로 해결되진 않지만 적어도 어떤 문제인지 로그로 뜨긴 한다.

4 Main Class 인식 불가

META-INF/MANIFEST.MF 파일에 Main-Class 경로를 명시적으로 정의해줘야 한다고 한다.
정의가 누락되면 자바 애플리케이션을 실행할 때 어떤 클래스의 메서드를 실행해야 하는지 알 수 없어서 실행이 안된다.

jar {
    manifest {
        attributes(
            'Main-Class': '[애플리케이션 경로]'
        )
    }
}

gradle 기반에서 빌드 설정에 다음과 같이 정의해주니 해결되었다.

+) SpringBootLambdaContainer

SpringBoot 애플리케이션을 람다에 올릴 때 이 라이브러리를 사용한 예제도 많은 것 같다
해당 라이브러리는 @SpringBootApplication이 달린 메소드를 자동으로 로드한다고 하니 메인 클래스 인식 문제도 쉽게 해결 가능할 것 같다

+) 읽어보면 좋은 자료

https://medium.com/@wconceptTech/aws-lambda%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-spring-boot-application-%EC%8B%A4%ED%96%89-e11d72b6f190

나중에 참고해봐야징

profile
좋아하는 걸로 밥 벌어먹기

0개의 댓글