[AWS] Lambda로 이미지 리사이징 하기

    728x90
    반응형

     

    [AWS] Lambda로 이미지 리사이징 하기

    이미지 리사이징 작업이 성능적으로 많이 무리가 가는 작업이다.

    이미지 리사이징 전용 서버를 분리해놓는게 좋다.

    근데 이거를 위해서 하나를 따로 두는건 쉽지않은데, 이럴때 좋은게 lambda가 있다.

     

     

    lambda

    Lambda는 AWS에서 제공하는 서버리스 컴퓨팅 플랫폼이다.

    서버리스란, 서버가 없다는 뜻이 아니고 개발자가 서버의 존재를 신경쓸 필요가 없다는 뜻이다.

    서버가 잘 돌아가고 있는지, 개수와 사양한 적당한지 등등 신경쓸 필요없이 사용자는 오직 코드에만 집중할 수 있으니 무척 편하다.

    이때 사용한 컴퓨팅 시간, 용량에 대해서만 AWS에게 비용을 지불하면 된다.

    더 자세한 내용은 https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/welcome.html 에서 확인 가능합니다!

    [예시:]

    작은 컴퓨터? 작은 함수 하나?

    이미지 리사이징을 해주는 함수 하나.

    이미지를 업로드했을 때 이 함수를 실행해서 이미지를 리사이징하고 다시 s3에 저장해랏.

    직접호출할 수도 있고, 이미지 업로드 되었을 때 (트리거) 람다 실행 시킬수도 있다. --> 자유롭다.

    누구는 서버없이 ec2 없이 lambda, s3로만 서버리스 웹서비스 만들어서 쓰기도 한다. 

     

     

    언제 쓰면 좋을까?

    코드를 계속 실행시키기 보다는 특정한 시기에만 실행시키는 경우에 Lambda를 사용하면 유용하다.

    예를 들면

    • 서버 띄우지 않고 간단한 코드를 실행시키고 싶은 경우
    • 특정 기간 또는 특정 주기로 코드를 실행시켜야 하는 경우
    • 트리거가 실행될때만 코드를 실행시키고 싶은 경우
    • 파일 처리: 업로드 후 Amazon Simple Storage Service(S3)를 사용하여 Lambda 데이터 처리를 실시간으로 트리거합니다.

     

    하지만 람다의 단점도 존재한다.

    • 코드 용량이 최대 250MB 이다.
    • 함수 실행 시간은 최대 15분이다.
    • 처음 함수 호출시 Cold Start를 하게되고 초기 지연시간이 발생한다.
    • 비싸다.

    등등이 있지만 그래도 서버 걱정 없이 오직 코드에만 집중 할 수 있다는 것은 굉장히 편하고 합리적인 것은 분명하다.

     

     

     

     

     

    사용방법

    0. 프로젝트에 lambda 폴더 생성

     

    폴더 생성 후 필요한 모듈을 받는다.

    npm init
    
    npm i aws-sdk sharp
    
    // aws-sdk = aws 접속 위해서
    // sharp = 이미지 리사이징 위해서

     

     

    1. lambda 함수 생성

    index.js 파일을 만들고 lambda 함수 만들어준다.

     

    /lambda/index.js

    const AWS = require('aws-sdk');
    const sharp = require('sharp');
    
    // AWS.config.update({})하지 않는다.
    // 람다는 aws에 업로드를 하는데 그럼 알아서 실행될때 사용자 정보를 불러오기 때문에
    // 키 값같은걸 넣어줄 필요 없다.
    // 백엔드에서 사용한건 ec2 서버기 때문에 위 함수사용했던 것.
    // 람다는 aws 자체에서 돌려주기 때문에 따로 인증절차 필요 없다.
    const s3 = new AWS.S3();
    
    // 람다는 하나의 기능을 하는 하나의 작은 함수
    // s3에 멀터로 이미지 업로드할 때 같이 실행하게 할 것 
    exports.handler = async (event, context, callback) => {
      const Bucket = event.Records[0].s3.bucket.name; // zzimzzim-s3 (지정한 s3 이름)
      // Key = 파일명
      const Key = decodeURIComponent(event.Records[0].s3.object.key);
      console.log(Bucket, Key);
      const filename = Key.split('/')[Key.split('/').length - 1];
      const ext = Key.split('.')[Key.split('.').length - 1].toLowerCase();
      const requiredFormat = ext === 'jpg' ? 'jpeg' : ext;
    
      // 람다가 끝날 땐 callback 함수써서 끝내주면 된다.
      try {
        // *데이터 가져와서
        const s3Object = await s3.getObject({ Bucket, Key }).promise();
        console.log('original', s3Object.Body.length); // Body에 이미지들 저장되있음, 바이트 확인 콘솔
        // *리사이징 해주고
        const resizedImage = await sharp(s3Object.Body)
          .resize(400, 400, { fit: 'inside' })
          .toFormat(requiredFormat)
          .toBuffer();
        // *다시 업로드 해주기
        await s3.putObject({
          Bucket,
          Key: `thumb/${filename}`,
          Body: resizedImage
        }).promise();
        return callback(null, `thumb/${filename}`);
      } catch (error) {
        console.error(error);
        // (express의 passport의 done과 비슷)
        // 첫번째 인수가 서버쪽 에러, 두번째 인수가 성공
        return callback(error);
      }
    }

     

    git 커밋 해준다

    back서버에서 커밋한 걸 sudo git pull 로 받은 다음

    lambda에서 sudo npm i -> 윈도우에서 설치한 sharp 모듈을 리눅스에서 그대로 쓰면 에러가 나기 때문에

    리눅스에서 다시 설치해줘야 한다.

    git add .
    git commit -m 'Add resizing lambda'
    or
    git commit -am 'Add resizing lambda'
    
    git push origin master
    
    sudo git pull
    
    sudo npm i

     

     

    2. lambda 폴더 압축 (파일 묶어주기)

    EC2에서 S3로 소스코드를 보내기 위한 작업 시작

    보낼 압축파일로 만들기

     

    /lambda 터미널

    // zip 모듈 설치
    sudo apt install zip
    
    // 파일 묶어주기
    // 리눅스에는 파일 압축, 묶어주기가 따로 되어있는데
    // 묶어주기만 해주는 것
    sudo zim -r aws-upload.zip ./*
    
    ** 묶어줄때 필요없는 파일/집파일은 지우고 해줘야 한다.
    aws, awscliv2.zip, 같은 파일 제거후 !!! 안그럼 용량이 너무 커진다.

     

    설치결과로 zip파일들을 확인할 수 있다.

     

     

    3. aws 다운 / 설치

    EC2에서 S3로 소스코드를 보내기 위해 aws 다운 설치

     

    aws 압축 파일 다운

    // awscliv2.zip
    sudo curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"

     

    zip파일 압축 해제

    unzip awscliv2.zip

     

    aws cli install

    sudo ./aws/install

     

    aws 확인

     

     

    4. 압축했던 람다 파일 s3로 보내기

    s3로 보내기

    aws configure
    
    aws s3 cp "aws-upload.zip" s3://zzimzzim-s3

     

    aws s3에서정상적으로 보내진 것 확인

     

     

     

     

    5. AWS Lambda 에서 작업

    람다 생성

    image-resize로 람다 생성

     

    아까 업로드 한 파일 불러오기

    경로는 나의 s3 . s3 . 지정했던 region

    https://zzimzzim-s3.s3.ap-northeast-2.amazonaws.com/aws-upload.zip

     

    아래처럼 나오면 성공

     

     

    런타임 설정 편집

    index.js 파일 안의 exports handler라는 뜻 (우리 작성한 파일 그대로)

     

     

    트리거 추가

    **s3에 업로드 할 때, 

    original폴더안에 파일이 들어갈 때

    lambda를 실행할 것이라는 트리거 설정

    접두사를 반드시 넣어줘야 한다. 그렇지 않으면 무한루프 돌 수가 있다.

     

     

     

     

    6. 소스 수정

    흐름

    멀터로 s3 업로드하면 그 s3가 람다를 트리거해서 우리가 만들었던 람다 함수를 호출.

    리사이징을 하고 다시 s3의 thumb 폴더에 넣어준다.

    그럼 업로드한 이미지를 사용하는 곳에서 thumb폴더의 것을 받아오면 된다.

     

    /back/routes/post.js

    // POST /post/images
    // 이미지 한장이면 upload.single / 없으면 upload.none / 파일 태그가 두개씩 있을때 fields
    // upload에서 이미지를 처리하고 처리된 이미지를 다음 콜백함수에서 req.files로 받는다.
    
    // original폴더를 리사이징한 thumb 폴더로 주소를 바꾼다
    router.post("/images", isLoggedIn, upload.array("image"), (req, res, next) => {
        try {
            console.log(req.files);
            res.json(req.files.map((v) => v.location.replace(/\/original\//, '/thumb/')));
        } catch (error) {
            console.error(error);
            next(error);
        }
    });

     

     

     

    /front/components/ImagesZoom/index.js

    // 원본 이미지 보기 할때에는 리사이징한 thumb 경로를
    // 원래 경로인 original로 바꿔준다.
    {images.map((v) => (
        <ImageWrapper key={v.src}>
            <img src={`${v.src.replace(/\/thumb\//, '/original/')}`} alt={v.src} />
        </ImageWrapper>
    ))}

     

     

     

     

     

    참조!

    https://www.inflearn.com/course/lecture?courseSlug=%EB%85%B8%EB%93%9C%EB%B2%84%EB%93%9C-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%A6%AC%EB%89%B4%EC%96%BC&unitId=49081&category=questionDetail&tab=curriculum&q=1152103

     

    학습 페이지

     

    www.inflearn.com

     

    https://seoyeonhwng.medium.com/aws-lambda%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80-44df535d5487

     

    AWS — Lambda란 무엇인가

    AWS 뿌시기 1탄은 Lambda다.

    seoyeonhwng.medium.com

     

    728x90
    반응형

    댓글