13 분 소요

트래픽 최적화(이미지), 서버 비용 절감(AWS), 백엔드 서버 관리, 서버 통신(Js)

이미지 (트래픽 최적화)

이미지 압축

이미지 파일 형식은 JPEG, PNG, WebP(추천)을 사용하고, 이미지 품질을 줄이지 않으면서,

이미지 압축 도구를 사용하여 이미지 용량을 최소화 한다.

이미지 압축 도구에는 ImageMagick, TinyPNG, ImageOptim 등이 있다.

사용법을 잘 모른다면 아래 사이트를 이용해도 좋다.

ILoveImg [더보기]


레이지 로딩 (Lazy Loading)

이미지를 필요할 때만 로드하도록 하여 초기 페이지 로딩 시간을 줄인다.

레이지 로딩은 브라우저 뷰포트 내에 있는 이미지만 로드하며,

스크롤 시에 추가 이미지를 동적으로 로드한다.

레이지 로딩을 구현하려면 HTML 태그의 loading 속성을 사용하면 된다.

<img src="placeholder.jpg" data-src="actual-image.jpg" alt="Lazy Loaded Image" loading="lazy">
  • placeholder.jpg: 이미지가 로딩될 때 보이는 빈 이미지 또는 로딩 중 이미지를 나타낸다.
  • actual-image.jpg: 실제 이미지 파일의 경로이다.
  • loading="lazy": 레이지 로딩을 활성화한다.

스프라이트 시트 (Sprite Sheet)

이미지 스프라이트 시트를 사용하여 여러 개의 이미지를 하나의 이미지로 결합한다.

CSS로 특정 이미지의 위치를 지정하고, 요청을 줄이고 성능을 향상시킨다.

.icon {
	background-image: url(../sprites/icons.png);
	background-position: 0px -32px;
	width: 32px;
	height: 32px;
}

CDN (Content Delivery Network)

이미지를 호스팅하고 전송하는 데 CDN을 사용하여 이미지를 빠르게 전달한다.

CDN은 전 세계의 서버를 통해 콘텐츠를 캐시하고 전송하므로 지연 시간을 최소화한다.

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.2/dist/css/bootstrap.min.css">

이미지 크기 조정 (Image Resizing)

이미지가 표시되는 크기에 맞게 이미지 크기를 조절한다. (해상도)

불필요하게 큰 이미지는 작은 크기로 조절하여 용량을 줄인다.

ILoveImg [더보기]


이미지 캐싱 (Image Caching)

이미지를 브라우저 캐시에 저장하여 동일한 페이지에서 이미지를 다시 로드하지 않도록 한다.

캐싱은 이미지 다운로드를 최소화 한다.


반응형 이미지 (Responsive Images)

서로 다른 디바이스 및 화면 크기에 맞는 이미지를 제공하여

사용자 경험을 개선하고 불필요한 데이터 사용을 방지한다.

HTML

<!DOCTYPE html>
<html>
<head>
    <title>반응형 이미지 예시</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <h1>반응형 이미지 예시</h1>
    
    <!-- 이미지 태그에 여러 크기의 이미지를 설정합니다. -->
    <img srcset="small.jpg 480w, medium.jpg 800w, large.jpg 1200w" sizes="(max-width: 600px) 100vw, (max-width: 1000px) 50vw, 33vw" alt="반응형 이미지">
</body>
</html>

CSS

/* 화면 크기에 따라 이미지 크기 조절 */
img {
    max-width: 100%;
    height: auto;
}

이미지 서버 최적화 (Server-Side Optimization)

서버 측에서 이미지를 최적화하고,

필요에 따라 이미지를 생성하는 스크립트를 사용하여 용량을 줄인다.

Node.js, Sharp 라이브러리

const express = require('express');
const sharp = require('sharp');
const app = express();
const port = 3000;

// 이미지 리사이즈 및 형식 변경
app.get('/images/:filename', (req, res) => {
  const filename = req.params.filename;
  const width = parseInt(req.query.width) || 300; // 기본 너비 300px
  const format = req.query.format || 'webp'; // 기본 형식 WebP

  sharp(`images/${filename}`)
    .resize({ width: width })
    .toFormat(format)
    .toBuffer()
    .then(data => {
      res.set('Content-Type', `image/${format}`);
      res.send(data);
    })
    .catch(err => {
      console.error(err);
      res.status(500).send('이미지 처리 오류');
    });
});

app.listen(port, () => {
  console.log(`이미지 서버가 ${port} 포트에서 실행 중입니다.`);
});

위 코드는 이미지 파일을 요청하면 서버에서 해당 이미지를 리사이즈하고

WebP 형식으로 변경하여 클라이언트에 제공한다.

Spring Boot(Java), Thumbnails 라이브러리

import net.coobird.thumbnailator.Thumbnails;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

@RestController
public class ImageController {

    @GetMapping("/resize-image")
    public byte[] resizeImage(@RequestParam String imageUrl, @RequestParam int width, @RequestParam int height) {
        try {
            // 이미지 URL에서 이미지를 읽어옵니다.
            URL url = new URL(imageUrl);
            InputStream in = url.openStream();

            // 이미지를 리사이징하고 원하는 크기로 변경합니다.
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            Thumbnails.of(in)
                .size(width, height)
                .outputFormat("jpeg") // 원하는 이미지 형식으로 변경 (예: "webp")
                .toOutputStream(out);

            return out.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
            return new byte[0];
        }
    }
}

AWS 비용 절감

AWS DB 비용 절감을 위한 방법은 아래와 같다.

자원 크기 조정

DB 인스턴스의 CPU 및 메모리 리소스를 필요에 맞게 조정한다.

AWS 콘솔 또는 CLI를 사용하여 인스턴스 크기를 변경할 수 있다.

작업 부하가 낮은 기간에 자원을 줄이고 다시 늘리는 것이 효율적이다.

예약 인스턴스

DB 인스턴스의 예약 인스턴스를 구입하여 긴 시간 동안 사용하게 되면 할인을 받을 수 있다.

예약 인스턴스는 미리 지불하고 일정한 기간 동안 리소스를 예약하는 방식이다.

리소스 최적화

DB 인스턴스에서 특정 프로세스 또는 작업을 실행하는 대신 AWS Lambda와 같은

다른 서비스를 사용하여 작업을 실행하는 방식을 고려한다.

이렇게 하면 비용을 절감하면서 더 효율적인 방식으로 작업을 수행할 수 있다.

DB 엔진 선택

EB 엔진을 선택할 때 비용 측면에서 고려해야 한다.

예를 들어, Amazon RDS보다 Amazon Aurora가 더 비용 효율적인 경우가 있다.

DB 가용성 구성

다중 가용 영역(Multi-AZ) 설정은 가용성을 높이지만 비용을 증가 시킬 수 있다.

특별한 가용성 요구 사항이 없는 경우 단일 가용 영역 설정을 고려한다.

최적화된 스토리지 사용

DB 스토리지에 대해 최적화된 설정을 선택한다.

DB에서 미사용 데이터를 Amazon S3와 같은 저장소 서비스로 이동하여 스토리지 비용을 줄이는 것도 고려할 만한 방법이다.

클라우드 모니터링 및 경고 설정

AWS CloudWatch와 같은 모니터링 서비스를 사용하여 자원 사용량을 추적하고,

비용 초과 또는 미사용 리소스를 식별하기 위한 경고를 설정한다.

DB 최적화

쿼리 성능을 최적화하고 불필요한 인덱스 및 테이블을 제거하여 데이터 베이스 비용을 절감한다.

일괄 작업 최적화

일괄 처리 작업을 최적화하여 비용을 줄인다.

예를 들어, 큰 데이터베이스 작업을 저렴한 시간대로 예약하거나 병렬 처리를 사용한다.


RDS

사용하지 않는 DB는 자원을 낭비하므로 주기적으로 정리하고 삭제해야 한다.

그리고 CPU 사용률을 낮추거나 관리 포인트를 줄이기 위해 DB를 통합하는 것이 유용할 수 있다.

하지만 이것은 복잡한 프로세스이며 데이터 일관성을 유지하기 위한 동기화 메커니즘을 고려해야 한다.

CPU 사용량을 최적화하려면 DB의 성능을 평가하고 최적화해야 한다.

이는 인덱스, 쿼리 최적화 및 데이터베이스 서버 구성 변경을 포함할 수 있다.

DB 통합 또는 분리에 따라 보안 및 회복 전략도 조정되어야 한다.

종합적으로, DB 관리는 신중한 계획과 맞춤형 접근이 필요하며,

비즈니스 요구 사항에 따라 다양한 전략을 고려해야 한다.


ECS

ECS 비용 절감은 비교적 간단한 프로세스이다.

tomcat 등 서블릿 기반 스테이징 서버는 기본적으로 일정한 스펙을 요구한다.

하루에 접속하는 유저 수가 적은 서비스의 경우,

스테이징 서버를 필요에 따라 켜고 끄는 것이 좋다.

무중단 운영이 필요하지 않은 어드민 서버와 같은 서비스는 Spot Fargate로 전환하여 비용을 절감할 수 있다.

서비스에 더 이상 필요하지 않은 AWS 리소스 및 ALB와 같은 부가적인 리소스는 삭제하여 추가적인 비용 절감 효과를 얻을 수 있다.


EC2

EBS (Elastic Block Store)

  • EBS 스냅샷 관리
    • 더 이상 필요하지 않는 스냅샷을 정기적으로 검토하고 삭제하여 스토리지 비용을 절감한다.
  • Cold HDD 사용
    • 저렴한 Cold HDD 유형의 EBS 스토리지를 사용하는 것은 비용을 줄이는 좋은 방법이다.

EIP (Elastic IP)

EIP를 사용하지 않는 경우, 반드시 반환해야 한다.

사용하지 않는 EIP를 보유하면 추가 비용이 발생한다.

ELB (Elastic Load Balancer)

트래픽에 따라 EC2 인스턴스의 수를 자동으로 조절하는 Auto Scaling 그룹을 설정하여

트래픽 피크 시에만 인스턴스를 실행하고 비용을 절감할 수 있다.

NAT (Network Address Translation) Gateway

작은 규모의 환경에서는 NAT 인스턴스를 사용할 수 있으며,

필요에 따라 시작 및 중지하여 비용을 절감한다.

EC2 Instances

  • 예약 인스턴스 사용
    • 장기적으로 EC2 인스턴스를 운영하는 경우, 예약 인스턴스를 구매하여 할인된 비용으로 인스턴스를 실행할 수 있다.
  • 인스턴스 유형 최적화
    • 인스턴스 유형을 필요에 맞게 최적화하여 비용을 절감한다. 예를 들어,
      CPU 집중적인 작업을 수행하는 경우 CPU 최적화 인스턴스 유형을 선택할 수 있다.

스케일 아웃 및 인스턴스 중지

트래픽이 다양한 시간대에 다르게 발생하는 경우, 필요한 시간에만 인스턴스를 실행하고 중지한다.

모니터링 및 자동화

CloudWatch 및 AWS Lambda와 같은 서비스를 사용하여 리소스 사용률을 모니터링하고 자동 조절하도록 설정하여 비용을 절감한다.

소프트웨어 최적화

불필요한 소프트웨어 라이선스 비용을 절감하고 필요한 소프트웨어만 사용하도록 한다.

AWS 비용 탐색 도구 사용

AWS의 비용 탐색 도구를 사용하여 비용을 모니터링하고 비효율적인 부분을 식별하여 개선한다.

리젼 및 가용 영역 최적화

필요한 경우, 특정 리전 및 가용 영역을 선택하여 비용을 최적화한다.


S3

라이프 사이클 정책 설정

객체에 대한 라이프 사이클 정책을 설정하여,

객체가 특정 시간 또는 버전 이후에 자동으로 삭제되거나 다른 스토리지 클래스로 이동하도록 설정할 수 있다.

이를 통해 장기간 미사용된 객체를 더 저렴한 스토리지 클래스로 이전하거나 삭제하여 비용을 절감할 수 있다.

접근 권한 및 규칙 설정

S3 버킷 및 객체에 대한 접근 권한을 세밀하게 제어하고,

권한이 없는 사용자 또는 애플리케이션이 불필요한 다운로드 또는 업로드 작업을 수행하지 못하도록 설정한다.

S3 객체 전송 압축

S3에 업로드되는 객체를 압축하여 저장한다.

데이터 압축을 통해 스토리지 공간을 절약하고 데이터 전송 비용을 줄일 수 있다.

S3 객체 복제 관리

객체의 복제를 관리하고 중복 데이터를 줄인다.

중복 데이터가 있을 경우 비용을 불필요하게 사용하지 않도록 한다.

S3 스토리지 클래스 최적화

S3는 다양한 스토리지 클래스를 제공한다.

데이터의 엑세스 패턴과 중요도에 따라 스토리지 클래스를 최적화하여 사용한다.

자주 엑세스하는 데이터는 S3 Standard 또는 S3 Intelligent-Tiering으로 유지하고,

장기간 미사용 데이터는 S3 Glacier 또는 S3 Glacier Deep Archive로 이동하여 비용을 절감한다.

S3 데이터 전송 최적화

데이터 전송 시 대역폭 제한 및 데이터 캐싱과 같은 기술을 사용하여 데이터 전송 비용을 최적화한다.

S3 스토리지 클래스 변경

S3 객체를 다른 스토리지 클래스로 일괄적으로 변경할 수 있다.

장기 미사용 데이터를 저렴한 스토리지 클래스로 이동하여 비용을 절감한다.

비용 모니터링 및 경고 설정

AWS Cost Explorer 및 AWS Budgets를 사용하여 S3 비용을 모니터링하고 미리 경고를 설정하여 예산 초과를 방지한다.

사용자 지정 S3 스토리지 클래스 정책

사용자 지정 스토리지 클래스 정책을 정의하여 특정 객체 그룹을 저렴한 스토리지 클래스로 이동시킴으로써 비용을 절감한다.

백엔드 서버 관리 (Spring Boot)

백엔드에서 트래픽을 최소화하거나 서버 비용을 낮추는 방법

캐싱 사용

캐싱은 반복적으로 계산이나 데이터베이스 쿼리를 수행하지 않고

이전 결과를 사용하여 응답 속도를 향상시키는 데 도움이 된다.

Spring Boot에서는 EhCache, Redis 등 캐싱 라이브러리를 사용할 수 있다.

예를 들면 Spring Cache Abstraction을 사용하여 메서드 수준에서 결과를 캐싱할 수 있다.

import org.springframework.cache.annotation.Cacheable;

@Cacheable("myCache")
public MyData getDataById(Long id) {
    // 데이터를 가져오는 비용이 큰 연산
}

CDN 사용

정적 자원(이미지, 스타일 시트, Js 파일 등)을 CDN을 통해 제공하면 서버 부하를 줄이고 클라이언트 측 로딩 시간을 개선할 수 있다.

CDN 제공 방법은 아래와 같다.

  1. Amazon S3 버킷 생성

  2. 정적 자원 업로드

  3. S3 버킷 정책 설정 - 공개 읽기 권한을 설정한다.

  4. CloudFront 배포 설정
    • AWS Management Console에 로그인한 후, CloudFront 서비스로 이동합니다.
    • “배포” 탭에서 “배포 생성”을 선택합니다.
    • “웹” 옵션을 선택하고 원본 S3 버킷을 지정합니다.
    • “행동” 탭에서 경로 패턴과 캐싱 정책을 설정합니다.

  5. CloudFront 도메인 명 설정

예를 들어 CSS 파일을 사용하는 경우

<link rel="stylesheet" href="https://your-cloudfront-domain.com/css/styles.css">

Spring Boot 애플리케이션의 소스 코드에서 정적 자원 경로를 CDN 도메인으로 설정해야 한다.

application.properties 또는 application.yml 파일에서 설정할 수 있다.

application.properties

spring.resources.static-locations=https://your-cloudfront-domain.com/

application.yml

spring:
  resources:
    static-locations: https://your-cloudfront-domain.com/

API 응답 압축

클라이언트와 서버 간의 데이터 통신을 압축하여 대역폭을 줄이고 응답 시간을 단축할 수 있다.

Spring Boot에서는 GZIP 압축을 지원할 수 있다.

아래는 API 응답을 GZIP으로 압축하는 예시이다.

  1. 의존성 추가 - spring-boot-starter-web 의존성을 프로젝트에 포함시킨다.
  2. application.properties 또는 application.yml 설정 추가 - server.compression.enabled를 true로 설정한다.

application.properties

server.compression.enabled=true

application.yml

server:
  compression:
    enabled: true

압축 대상 설정

JSON 응답을 압축하려면 아래와 같이 설정한다.

server.compression.mime-types=application/json

API 컨트롤러

@RestController
public class MyController {
    @GetMapping("/api/data")
    public ResponseEntity<String> getCompressedData() {
        String data = "This is a sample API response that will be compressed.";
        return ResponseEntity.ok(data);
    }
}

비동기 처리

비동기 백그라운드 작업을 사용하여 서버 응답 시간을 단축할 수 있다.

Spring Boot에서는 @Async 어노테이션을 사용하여 비동기 메서드를 구현할 수 있다.

@Async
public CompletableFuture<Result> asyncMethod() {
    // 비동기 작업 수행
}

부하 분산 및 자동 확장

서버 부하를 분산시키고 서버 자동 확장을 설정하여 고유 트래픽을 처리할 수 있다.

이것은 대용량 트래픽에 대한 대처 방법 중 하나이다.

Spring Boot 애플리케이션을 클러스터링하고 로드 밸런서를 사용하여 부하를 분산시킬 수 있다.

  • AWS 계정 및 리소스 생성
    • EC2 인스턴스를 시작하고 애플리케이션을 실행할 인스턴스를 프로비저닝한다.
    • RDS 또는 Aurora와 같은 관계형 데이터베이스를 설정한다.
  • 로드 밸런서 생성
    • AWS Management Console에서 로드 밸런서 서비스로 이동한다
    • 로드 밸런서 생성을 선택하고 로드 밸런서를 생성한다.
    • 로드 밸런서에 대상 그룹을 설정하고 그룹에 애플리케이션 EC2 인스턴스를 추가한다.
  • Auto Scaling 그룹 설정
    • AWS Auto Scaling 그룹을 생성하여 EC2 인스턴스의 자동 확장을 설정한다.
    • Auto Scaling 그룹의 정책을 정의하고 확장/축소 규칙을 구성한다. 예를 들어, CPU 사용률이 특정 임계값을 넘으면 자동으로 새 인스턴스를 추가할 수 있다.
  • 애플리케이션 배포 및 설정
    • Spring Boot 애플리케이션을 EC2 인스턴스에 배포하고 필요한 구성을 설정한다.
    • 데이터베이스 연결 정보나 다른 구성 정보를 외부 설정으로 관리하고, 환경변수 또는 AWS 시스템 매개변수를 통해 사용한다.
  • 인스턴스에서 로드 밸런서를 통한 트래픽 수신

    애플리케이션 코드에서 로드 밸런서의 DNS 이름을 사용하여 트래픽을 수신하도록 구성한다.

    이것은 애플리케이션에서 직접 IP 주소를 사용하지 않고 로드 밸런서를 통해 트래픽을 분산시키는 데 도움이 된다.

아래 예시를 통해 로드 밸런싱과 자동 확장 설정을 구체화하겠다.

로드 밸런서 생성 및 Target Group 설정

  1. AWS Console에서 로드 밸런서 서비스로 이동하여 로드 밸런서를 생성한다.
  2. 로드 밸랜서를 생성한 후 대상 그룹을 설정한다. 이 그룹에 애플리케이션 서버 EC2 인스턴스를 추가한다.
  3. 대상 그룹 설정에서 상태 검사 등록을 통해 인스턴스의 건강 상태를 확인한다.

Auto Scaling 그룹 설정

  1. AWS Console에서 Auto Scaling 그룹 서비스로 이동하여 그룹을 생성한다.
  2. Auto Scaling 그룹에 EC2 인스턴스를 추가하고 시작 구성을 설정한다.
  3. 확장/축소 정책을 추가하여 CPU 사용률 또는 다른 지표를 기반으로 자동 확장/축소 동작을 정의한다.
  4. 부하가 높아지면 Auto Scaling 그룹이 새로운 인스턴스를 자동으로 시작하고 로드 밸랜서에 등록한다.

애플리케이션 구성

  1. Spring Boot 애플리케이션에서 외부 구성을 사용하여 데이터베이스 연결 정보를 관리한다.
    이 정보를 AWS SSM (Systems Manager) 매개변수 스토어 또는 환경 변수를 통해 주입할 수 있다.
  2. 애플리케이션 코드에서 로드 밸랜서 DNS 이름을 사용하여 트래픽을 수신하도록 설정한다.

스프링 프로파일 사용

서버의 환경을 구분할 수 있는 스프링 프로파일을 사용하여 설정을 조절하고 리소스를 관리한다.

예를 들어, 개발 환경과 프로덕션 환경에서 서로 다른 데이터베이스 연결 설정을 사용할 수 있다.

@Configuration
@Profile("dev")
public class DevelopmentConfig {
    // 개발 환경 설정
}

@Configuration
@Profile("prod")
public class ProductionConfig {
    // 프로덕션 환경 설정
}

보안 및 인증 최적화

불필요한 보안 체크나 인증 프로세스를 최소화하여 서버 부하를 줄인다.

데이터베이스 최적화

데이터베이스 쿼리를 튜닝하고 적절한 인덱스를 추가하여 데이터베이스 성능을 최적화한다.

마이크로서비스 아키텍처

서비스를 작은 마이크로서비스로 나누어 각 서비스가 독립적으로 확장 가능하도록 설계한다.

Cloud 서비스 이용

클라우드 서비스 (예: AWS, Azure, Google Cloud)를 사용하여 서버 비용을 최소화하고 필요할 때 서버를 확장할 수 있다.

Js에서 서버 통신 법

XMLHttpRequest

XMLHttpRequest 객체를 사용하여 비동기적으로 서버와 통신한다.

요청 및 응답 데이터를 처리하기 위해 이벤트 핸들러를 활용한다.

사용법이 복잡하며, 프로미스나 콜백 함수를 사용하여 비동기 코드를 관리해야 한다.

var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://example.com/api/data', true);
xhr.onload = function() {
    if (xhr.status >= 200 && xhr.status < 300) {
        var response = JSON.parse(xhr.responseText);
        // 서버 응답 처리
    }
};
xhr.send();
// GET 요청
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://jsonplaceholder.typicode.com/posts/1', true);

xhr.onload = function () {
  if (xhr.status >= 200 && xhr.status < 300) {
    const response = JSON.parse(xhr.responseText);
    console.log(response);
  } else {
    console.error('Error:', xhr.statusText);
  }
};

xhr.send();

Fetch API

XMLHttpRequest를 대체하기 위해 도입된 더 간단하고 더 강력한 API이다.

Promise를 기반으로 하며, 요청과 응답을 다루기 쉽게 만든다.

JSON 데이터를 읽거나 다룰 때 특히 유용하다.

fetch('https://example.com/api/data')
    .then(response => response.json())
    .then(data => {
        // 서버 응답 처리
    })
    .catch(error => {
        console.error('Error:', error);
    });
// GET 요청
fetch('https://jsonplaceholder.typicode.com/posts/1')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));

// POST 요청
const postData = {
  userId: 1,
  id: 101,
  title: 'foo',
  body: 'bar'
};

fetch('https://jsonplaceholder.typicode.com/posts', {
  method: 'POST',
  body: JSON.stringify(postData),
  headers: { 'Content-Type': 'application/json' }
})
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));

Axios

자주 사용되는 HTTP 클라이언트 라이브러리 중 하나이다.

XMLHttpRequest 및 Fetch API를 추상화하며, 프로미스 기반의 간편한 HTTP 요청을 지원한다.

주로 복잡한 웹 애플리케이션에서 사용된다.

axios.get('https://example.com/api/data')
    .then(response => {
        // 서버 응답 처리
    })
    .catch(error => {
        console.error('Error:', error);
    });
const axios = require('axios'); // 또는 스크립트에 직접 포함시키기

// GET 요청
axios.get('https://jsonplaceholder.typicode.com/posts/1')
  .then(response => console.log(response.data))
  .catch(error => console.error('Error:', error));

// POST 요청
const postData = {
  userId: 1,
  id: 101,
  title: 'foo',
  body: 'bar'
};

axios.post('https://jsonplaceholder.typicode.com/posts', postData)
  .then(response => console.log(response.data))
  .catch(error => console.error('Error:', error));

WebSocket

웹 소켓은 실시간 양방향 통신을 지원하는 프로토콜이며,

바닐라 자바스크립트에서 웹 소켓 API를 사용하여 서버와 실시간 통신을 구현할 수 있다.

var socket = new WebSocket('wss://example.com/socket');
socket.onopen = function() {
    // 연결 열림
};
socket.onmessage = function(event) {
    var data = JSON.parse(event.data);
    // 서버 메시지 처리
};

클라이언트

const socket = new WebSocket('ws://your-server-address');

socket.onopen = function (event) {
  socket.send('Hello, Server!');
};

socket.onmessage = function (event) {
  console.log('Server says:', event.data);
};

서버(Node.js ws 패키지)

const WebSocket = require('ws');
const server = new WebSocket.Server({ port: 8080 });

server.on('connection', function (socket) {
  socket.on('message', function (message) {
    console.log('Client says:', message);
    socket.send('Hello, Client!');
  });
});

Server-Sent Events (SSE)

서버에서 클라이언트로 단방향 실시간 이벤트 스트림을 제공하는 기술이다.

EventSource API를 사용하여 바닐라 자바스크립트로 서버와 실시간 통신할 수 있다.

var eventSource = new EventSource('https://example.com/sse');
eventSource.onmessage = function(event) {
    var data = JSON.parse(event.data);
    // 서버 이벤트 처리
};

클라이언트

const eventSource = new EventSource('https://your-server-address/events');

eventSource.onmessage = function (event) {
  console.log('Server says:', event.data);
};

eventSource.onerror = function (event) {
  console.error('Error:', event);
};

서버 (Node.js)

const http = require('http');

const server = http.createServer((req, res) => {
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');

  let count = 0;

  const sendEvent = () => {
    res.write(`data: Server message ${count}\n\n`);
    count++;
  };

  const intervalId = setInterval(sendEvent, 1000);

  req.on('close', () => {
    clearInterval(intervalId);
    res.end();
  });
});

server.listen(8080);

정리

위 통신 법들 중에서 가장 많이 사용되는 방법은 Fetch API와 Axios이다.

이들은 간결한 구문과 Promises를 사용하여 비동기 코드 작성이 더 쉽고 간편하게 만든다.

또한 이 두 라이브러리는 오류 처리 및 HTTP 요청 설정을 개선하는 추가 기능을 제공한다.

WebSocket은 실시간 양방향 통신이 필요한 경우 가장 적합하다.

Server-Sent Events (SSE)는 단방향 푸시 메시징에 유용하며 실시간 이벤트 스트림을 처리하는 데 적합하다.

XMLHttpRequest는 현재 더 이상 권장되지 않지만 구식 웹 애플리케이션에서 여전히 사용되고 있다.

이전 웹 애플리케이션을 유지 보수하거나 지원해야 하는 경우 사용될 수 있다.

XMLHttpRequest

  • 장점
    • 모든 주요 브라우저에서 지원.
    • 오래된 웹 애플리케이션에서 흔히 사용.
  • 단점
    • 비동기 요청 처리가 복잡하고 가독성이 낮음.
    • 콜백 지옥(callback hell) 발생 가능.

Fetch API

  • 장점
    • 더 간결한 문법.
    • Promises를 사용하여 비동기 코드 작성이 향상.
  • 단점
    • IE 및 구식 브라우저에서 지원하지 않음.
    • 요청/응답을 처리하는 방식이 다소 복잡함.

Axios

  • 장점
    • 모든 주요 브라우저에서 지원.
    • 취소, 인터셉터, 상세한 오류 처리 등 다양한 기능 제공.
  • 단점
    • 추가 라이브러리로 사용해야 하므로 번들 크기 증가 가능.

WebSocket

  • 장점
    • 실시간 양방향 통신 가능.
    • 가벼우며 저지연.
  • 단점
    • 서버와 클라이언트 모두 지원해야 함.

Server-Sent Events (SSE)

  • 장점
    • 서버에서 클라이언트로 단방향 푸시 메시지 제공.
    • 일반 HTTP 연결 사용.
  • 단점
    • 전이적인 양방향 통신을 지원하지 않음.

카테고리: ,

업데이트:

댓글남기기