반응형

사용하고 있는 서버 중 small, medium 서버에서 메모리가 너무 빨리 차서 메모리릭 현상이 발생하는 이슈가 있었습니다.

 

매일 scheduler로 메모리 청소를 해주지만 이것도 한계가 있고,

비용문제로 큰 서버로 늘리는 것은 부담되므로 가상 메모리를 확보하는 방식으로 사용하기로 했습니다 !!

 

Swap file을 사용해서 해결하기로 결정

 

swap file 이 뭔데 ?

메모리가 부족할 때 디스크 공간을 가상 메모리로 사용하는 방법입니다.

대체하여 사용하는 방식이기 때문에 실제 메모리에 비해 속도도 느리고 성능이 저하될 수 있지만 메모리가 부족해서 서버가 다운되는 이슈를 방지하는 면에서 swap을 사용하는 것도 좋은 방법입니다.

 

 

1. 기존 메모리 사용량 확인

 

현재 total 메모리 1.9G 이기 때문에 1.5 ~ 2배 정도 확보 해준다. (4G 정도면 적당하겠지 . . . ?)

 

2. 메모리 할당

sudo fallocate -l 4G /swapfile
ls /swapfile

 

3. 접근 권한 설정

sudo chmod 600 /swapfile

 

4. 메모리 파티션 설정

sudo mkswap /swapfile
sudo swapon /swapfile

 

5. 마운트 추가

sudo vi /etc/fstab
// 파일에 아래 한 줄 추가
/swapfile swap swap defaults 0 0

 

6. 가상 메모리 확보 완료

 

free -h 명령어로 현재 메모리 사용량을 알 수 있습니다.

 

Swap도 4G 설정 완료 끝입니다 :)

반응형
반응형

AWS Lambda와 SQS를 사용해서 카카오 메시지 전송하는 기능을 만들었는데 

 

1. [AWS SQS] Nestjs로 SQS 전송, 수신 구현하기

 

[AWS SQS] Nestjs로 SQS 전송, 수신 구현하기

AWS SQS가 뭐지?Amazon Simple Queue Service(SQS)는 쉽게 말해서 Queue입니다. 마이크로서비스, 분산 시스템 등에서 메시지 손실 걱정 없이 어떤 볼륨의 메시지든 전송, 저장 및 수신이 가능한 메시지 대기열

zsunn.tistory.com

2. [AWS] Lambda + SQS로 카카오 알림톡 서비스 구현하기

 

[AWS] Lambda + SQS로 카카오 알림톡 서비스 구현하기

저번에는 SQS 송수신하는 코드를 구현해 보았는데요! 이번에는 이어서 SQS로 전송한 데이터를 Lambda로 받아서 알림톡으로 전송하는 서비스를 구현해 보겠습니다! 이전 글 참고 해주세요! [AWS SQS] Ne

zsunn.tistory.com

 

이전 게시글에서 SQS 송수신 구현하고 Lambda 설정까지 끝냈습니다.

다음 lambda 코드 소스를 짜보겠습니다.

 

저는 Node로 코드 구성을 했고, 하단에 런타임 설정에서 언어 설정 가능합니다.

 

 

코드 소스

환경변수 가지고 와서 카카오 API로 메시지 전송하는 부분까지 코드를 간단하게 작성했습니다.

const request = require('request');

exports.handler = function (event) {
    console.log('consume sqs message event', JSON.stringify(event.Records[0].body));
    
    try {
        const headers = {
            'Content-type': 'application/json',
            'userid' : process.env.BIZMSG_USER_ID,
          };
        
        const options = {
            uri: process.env.BIZMSG_API_HOST,
            method: 'POST',
            headers: headers,
            body: event.Records[0].body
        };
    
        request.post(options, function (error, response, body) {
            if (error) {
                console.error(error);
            }
            console.log(body);
        });
    } catch (error) {
        console.error(error);
    }
    
};

 

 

하지만 이렇게 끝내면 오류가 발생합니다!!

이유는 request 라는 라이브러리를 가지고 올 수 없기 때문이죠

 

Lambda 에서 사용하고 싶은 라이브러리는 직접 layer로 생성을 해서 부여해주셔야 합니다

 

Layers 추가

1. 새로운 폴더를 만들어줍니다.

mkdir nodejs && cd nodejs

 

 

2. 원하는 라이브러리를 다운로드합니다.

npm init
npm install --save request

 

3. zip 파일로 변경해 줍니다.

cd ..
zip -r layer.zip nodejs

 

4. awscli 다운로드해줍니다.

brew install awscli

 

5. lambda layer로 올려줍니다.

aws lambda publish-layer-version --layer-name request-layer --description "add request library" --zip-file fileb://layer.zip --compatible-runtimes nodejs14.x nodejs16.x nodejs18.x\n

 

6. 계층 > [Add a layer]

사용자 지정 계층을 보면 이제까지 올렸던 layer들의 목록이 보입니다.

 

원하는 layer를 선택 후 추가하면 아래와 같이 목록이 생성됩니다!

 

 

layer 목록에서 삭제하는 방법은 다음과 같습니다.

aws lambda delete-layer-version --layer-name request-layer --version-number

 

 

테스트도 해볼 수 있습니다.

 

반응형
반응형

오늘은 AWS EC2와 Jenkins를 활용한 CI/CD 구성을 해보려고 합니다!

인프라 관련 일을 할 때마다 어렵지만 재밌고 공부하는 재미가 쏠쏠한데 나중에 DevOps도 해보고 싶네요

 

DNS 설정은 아임웹을 사용했고, 깃허브 웹훅을 Jenkins와 연동해서 자동 빌드 테스트까지 해보겠습니다!

 

 

1. 프로젝트 생성 후 웹훅 설정

 

2. AWS 인스턴스 생성

 

3. 아임웹 추가

 

1) 환경설정 > 도메인

 

 

2) 보안그룹 > 인바운드 규칙

 

보안그룹 생성

 

netstat -tulpn

→ 위의 포트가 사용 안 하고 있는 포트인지 확인 필요

 

4. 대상 그룹 생성

로드 밸런싱 > 대상 그룹 > 대상 그룹 생성

5. 로드밸런서 DNS 연동

아임웹에서 만든 ip 주소 등록
방금 만든 대상그룹 등록

 

 

6. Jenkins 설정

1) Jenkins 관리 > 시스템 설정 > SSH Server 추가

Hostname : 인스턴스 프라이빗 IPv4 주소

 

 

 

2) Jenkins 새로운 Item

 

유의할 점 : 깃허브 주소, 폴더 명

 

 

  • GitHub hook으로 develop 자동 빌드로 세팅
  • Execute shell : 빌드 시 실행할 쉘 스크립트 설정
# jenkins workspace로 이동
cd /var/jenkins_home/workspace
# 빌드 후 생성된 코드파일을 tar 파일로 생성
tar -cvf dev-test-server.tar dev-test-server
# tar 파일 위치 이동
mv dev-test-server.tar dev-test-server/dev-test-server.tar

 

 

 

방금 저장한 젠킨스 SSH Server 등록!

# 개발서버로 이동
cd /home/ec2-user/dev-test-server
# tar 파일 풀기
tar -xvf dev-test-server.tar
# start shell 스크립트 실행
./start.sh

 

 

 

  • 빌드 종료 후 실행할 shell 명령 설정
# tar 파일 삭제
rm /var/jenkins_home/workspace/dev-test-server/dev-test-server.tar

 

 

여기서부터는 젠킨스 서버 - 개발 서버 세팅!

 

 

1. 젠킨스 서버 접속

 

cd /jenkins/workspace/
sudo mkdir dev-test-server
# 여기서 폴더명은 아까 젠킨스에서 만들어줬던 폴더명과 동일하게 !!!!

 

2. 개발 서버 접속

# 소스코드 풀 폴더 생성
sudo mkdir dev-test-server && cd dev-test-server
sudo vi ecosystem.config.js

 

ecosystem.config.js 파일 생성

'use strict';

module.exports = {
    apps: [
        {
            name: "dev-test-server-API", // pm2로 실행한 프로세스 목록에서 이 애플리케이션의 이름으로 지정될 문자열
            namespace: "develop",
            script: "dev-test-server/dist/main.js", // pm2로 실행될 파일 경로
            watch: false, // 파일이 변경되면 자동으로 재실행 (true || false)
            ignore_watch : ["logs"],
            env: {
                "NODE_ENV": "development" // 개발환경시 적용될 설정 지정
            },
            env_production: {
                "NODE_ENV": "production" // 배포환경시 적용될 설정 지정
            }
        }
    ]
};

 

start.sh 쉘 스크립트 파일 생성

sudo vi start.sh
#!/bin/bash
cd /home/ec2-user/dev-test-server/dev-test-server
yarn install
npm run build
cd /home/ec2-user/dev-test-server
pm2 restart ecosystem.config.js

 

💡 너무너무 중요한 권한 설정!!!

 

sudo chown -R ec2-user:ec2-user dev-test-server
sudo chmod 775 dev-test-server
sudo chmod 755 start.sh

 

node, pm2, yarn 설치 (버전에 맞게 설치)

cd ~
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
. ~/.nvm/nvm.sh
nvm install 16
npm -v
npm install pm2 -g
npm install -g yarn

 

3. 빌드 테스트

코드 → develop 자동 빌드 테스트

 

 

pm2가 떠있으면 성공!

 

jenkins 다루면서 오류도 굉장히 많았는데 어떤 오류를 잡았었는지 다음에 하나씩 올리도록 하겠습니다

 

반응형
반응형

저번에는 SQS 송수신하는 코드를 구현해 보았는데요!
이번에는 이어서 SQS로 전송한 데이터를 Lambda로 받아서 알림톡으로 전송하는 서비스를 구현해 보겠습니다!
 
이전 글 참고 해주세요!
[AWS SQS] Nestjs로 SQS 전송, 수신 구현하기
 

AWS Lambda란?

Lambda는 서버를 따로 두지 않고도 코드를 실행할 수 있는 이벤트 중심의 서비스입니다.
작은 단위의 API를 만들고 싶은데 EC2 인스턴스를 생성하기에는 규모와 비용이 너무 커지기 때문에 간편하게 코드를 작성하고 업로드하면 API 사용이 가능합니다!
비용도 사용한 만큼만 지불하면 되기 때문에 너무 좋은 서비스라고 생각합니다.
 

1. IAM 역할 생성

Lambda를 호출할 수 있는 권한을 가진 IAM을 생성해 줍니다.
SQSFullAccess 권한과 LambdaBasicExecutionRole 권한을 넣어줍니다.

 

2. Lambda 함수 생성

이름과 함수를 어떤 언어로 작성할 것인지 고르고
실행 역할에는 기존 역할 사용을 클릭한 후 방금 생성해 준 역할을 선택해 줍니다.
kakao-messaging이라는 이름으로 생성해 볼게요!
 

3. Lambda 트리거 구성

Lambda에 SQS 트리거를 추가해 줍니다!
트리거에 추가된 SQS에 쌓일 때마다 Lambda가 실행됩니다.

트리거가 생겼습니다!
 

4. Lambda 환경변수 추가

이 부분은 자유이지만 저는 환경변수를 생성해서 코드를 작성해 보도록 하겠습니다!
구성 > 환경 변수 > 편집

 

4. Lambda 로그 스트림 확인

Lambda 로그는 CloudWatch에 쌓이고 있습니다.
로그 확인은 모니터링 > CloudWatch 로그 확인에서 확인할 수 있습니다.

 
카카오 알림톡 전송 코드는 다음 게시글에서 쓰겠습니다~ 

반응형
반응형

AWS SQS가 뭐지?

Amazon Simple Queue Service(SQS)는 쉽게 말해서 Queue입니다.
마이크로서비스, 분산 시스템 등에서 메시지 손실 걱정 없이 어떤 볼륨의 메시지든 전송, 저장 및 수신이 가능한 메시지 대기열입니다.
표준대기열, FIFO 대기열 유형이 있습니다.
 
 
그럼 SQS 송수신 구현을 해보도록 하겠습니다~

1. AWS SQS 대기열 생성

대기열 유형을 선택해야하는데, 각 장단점이 있습니다.
표준 대기열 : 무제한 처리량, 두 번 이상 메시지가 전달될 수 있음, 순서 보장이 안됨
FIFO 대기열 : 정확한 처리, 순서 보장
 
저는 FIFO 방식으로 선택하겠습니다.
FIFO 대기열은 이름 뒤에 반드시 .fifo를 붙여야 합니다.
 

저는 KAKAO_MESSAGE.fifo 라는 이름의 SQS를 만들어보겠습니다.
 

 

2. SQS 메시지 전송 test

SQS가 생성이 됐다면 메시지 송수신 테스트를 해볼 수 있습니다.
 

메시지 전송 테스트

메시지 수신 테스트

메시지 폴링 버튼을 누르면 수신 테스트 시작이고, 그 사이에 메시지가 들어온다면 하단의 메시지란에 새로운 메시지가 생성이 됩니다.
 

3. IAM 사용자 생성

이제 코드에서 SQS 송수신을 하기 위해서 IAM 사용자를 생성해야 합니다.
aws-sqs-group이라는 이름으로 생성해 보겠습니다.
 

생성했다면 생성한 IAM 사용자의 key id와 access key를 가지고 코드를 작성해 보도록 할게요.
 

4. 코드 작성

Nestjs로 작성해 보겠습니다.
저는 @ssut/nestjs-sqs 라이브러리를 사용해서 기능 구현 해봤습니다!
 
라이브러리 install

npm i --save @ssut/nestjs-sqs
yarn add @ssut/nestjs-sqs

 

test-sqs.module.ts

sqs producer 설정을 해주는 부분입니다.

import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from "@nestjs/config";
import { SqsModule } from "@ssut/nestjs-sqs";
import { SQSClient } from "@aws-sdk/client-sqs";

@Module({
  imports: [
    SqsModule.registerAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (configService: ConfigService) => {
        return {
          producers: [{
            name: configService.get('SQS_NAME'),
            queueUrl: configService.get('SQS_PRODUCER_QUEUE_URL'),
            sqs: new SQSClient({
              region: configService.get('AWS_REGION'),
              credentials: {
                accessKeyId: configService.get<string>('AWS_SQS_ACCESS_KEY_ID'),
                secretAccessKey: configService.get<string>('AWS_SQS_SECRET_ACCESS_KEY') ,
              }
            })
          }]
        };
      },
    })
  ],
  providers: [TestSqsService],
  exports: [TestSqsService]
})
export class TestSqsModule {}

 

test-sqs.service.ts

sqs 메시지 송신 기능 메소드 구현부입니다.

import { Inject, Injectable } from "@nestjs/common";
import { SqsService } from "@ssut/nestjs-sqs";
import { MessageDto } from "../common/dto/biz.msg.dto";
import { ConfigService } from "@nestjs/config";

@Injectable()
export class TestSqsService {
  constructor(
    private configService: ConfigService,
    private readonly sqsService: SqsService,
  ) {}

  /**
   * SQS Message 송신
   * @param message SQS 전송 메시지
   */
  async send(message: MessageDto[]) {
    try {
      const body = JSON.stringify(message);

      const payload = {
        id: uuid, // 중복 방지를 위해 uuid 사용
        body: body,
        groupId: uuid,
        deduplicationId: uuid
      }

      const response = await this.sqsService.send(
        this.configService.get('SQS_NAME'),
        payload
      );

      console.log(`[SQS] send successful : [${JSON.stringify(response)}]`);

      return response;
    } catch (error) {
      console.log(error);
    }
  }
}

 
sqs consumer 부분도 같은 라이브러리를 사용해서 만들 수 있습니다~
 

References

https://www.npmjs.com/package/@ssut/nestjs-sqs

반응형

+ Recent posts