AWS API GATEWAY 사용량 계획 용어 정리

  • 자체 개발한 Rest API의 앞단에 AWS API Gateway를 붙여서 사용하려고 합니다.
  • AWS API Gateway를 이용하면, 인증과 관련된 구현을 따로 하지 않아도 되는 등의 장점이 있습니다.
  • 또한 사용량을 통제하는 시스템 역시 따로 구현하지 않아도 되는데요
  • API Gateway의 경우 API-KEY에 대응하는 사용량 계획을 설정할 수 있습니다. 이것을 이용해서 사용량을 통제할 수 있어요.
    • image
    • 그럼 용어에 대해 설명해보겠습니다.
    • 요율과 버스트 : 이 둘은 함께 고려해야 할 개념입니다.
      • 요율에 입력된 초 당, 버스트에 입력된 요청건을 받아들이겠다는 의미로 생각하면 됩니다.
      • 예를들어 요율에 10, 버스트에 50을 입력하면 10초당 50요청까지만 받겠다는 의미에요.
      • 만약에 그 양을 넘어가면 어떻게 될까요? 429 응답 코드와 함께 {“message”:”Too Many Requests”}가 전달됩니다.
      • 그리고 버스트의 경우 계정에 따른 한도가 있어요. 저 같은 경우에 5000건 이구요, 이 한도가 요율에 따라 달라지지는 않는것으로 보입니다.
    • 할당량 : 할당량은 선택한 기준기간 동안에 허용되는 요청건수를 의미합니다.
      • 일/주/월 단위로 설정할 수 있습니다.
      • 계획량을 넘어서면 역시 429 응답 코드와 함께 {“message”:”Limit Exceeded”}가 전달됩니다.
      • 버스트와 다르게 한도가 있지는 않는것 같습니다.
    • 버스트와 할당량의 계획량이 넘어서서 API가 먹통이 되었을 때, 그 값을 수정해주면 다시 정상동작 합니다.

이미지 파일에 대한 URL 라우팅 속도비교 Node vs Go vs Nginx

  • 평소에 궁금했던 사항인데요. 정적 이미지 파일을 URL로 나눠서 로딩하는데 걸리는 시간이 언어나 프레임워크 별로 얼마나 차이가 날까였어요.
  • 그래서 한 번 시도해 봤습니다. 먼저 Node 코드 입니다.
var express = require('express');
var app = express();
var fs = require('fs');

app.get("/image1", function (req, res) {
  var img = fs.readFileSync("./image1.jpg");
  res.set({'Content-Type': 'image/jpeg'});
  res.send(img);
});
app.get("/image2", function (req, res) {
  var img = fs.readFileSync("./image2.jpg");
  res.set({'Content-Type': 'image/jpeg'});
  res.send(img);
});

module.exports = app;
  • JMeter로 동접자 100으로 시도해 봤어요. 그러자 첫번째 파일의 LoadTime은 26ms, 두번째 파일은 8ms 가 나왔습니다.
  • 다음은 Go 코드 입니다.
package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
)

func main() {
	mux := http.NewServeMux()
	mux.HandleFunc("/image1", func(res http.ResponseWriter, req *http.Request) {
		buf, err := ioutil.ReadFile("image1.jpg")
		if err != nil {
			fmt.Printf("error: %s", err.Error())
		}
		res.Header().Set("Content-Type", "image/jpeg")
		res.Write(buf)
	})
	mux.HandleFunc("/image2", func(res http.ResponseWriter, req *http.Request) {
		buf, err := ioutil.ReadFile("image2.jpg")
		if err != nil {
			fmt.Printf("error: %s", err.Error())
		}
		res.Header().Set("Content-Type", "image/jpeg")
		res.Write(buf)
	})
	http.ListenAndServe(":3001", mux)
}
  • 첫번째 파일은 11ms, 두번째 파일은 6ms가 나왔습니다. 싱글쓰레드인 Node와 그렇지 않은 Go의 성능차이는 어느정도 추측되었는데요.
광고를 클릭해주시면 블로그운영에 큰 힘이 됩니다.
  • 그렇다면 Nginx에서 Alias를 이용해서 정적파일을 다른 URL 로딩하면 어떻게 될까요?

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    server {
        listen 80;
        location /image1/ {
            alias /images1/;
        }
        location /image2/ {
            alias /images2/;
        }
    }
}
  • 첫번째 파일이 35ms, 두번째 파일이 4ms가 나왔습니다. 단순비교상으로 Node > Nginx 인 경우가 있다니 좀 신선하네요.
  • 아무래도 캐시를 사용하면 결과가 달라질 수 있겠지만, 개인화된 이미지나 동영상을 처리해야 할 때는 캐시가 부적절 할 수 있죠.
  • 보너스로 Vue-Router를 이용하면 어떻게 될지 추측해봤습니다. 참고로 Vue는 SPA이고 가상URL을 사용하기 때문에 JMeter로 테스트하기가 어렵더라구요.
  • 단순히 이미지 로딩시간만 보면 첫번째 파일이 53ms, 두번째 파일이 45ms가 소요됩니다.
  • 다만 컴포넌트화 한 페이지 모두가 로딩되려면 각가 280ms, 150ms 정도가 필요하구요.

Flutter 에서 많은 이미지 로딩시 메모리 오버플로우 막는 방법

  • GroupGridView 를 이용해서 한 번에 여러개의 사진을 보여주고자 했습니다.
  • 그런데 이런상황에서 용량이 큰 사진을 한번에 로딩하면 메모리 문제가 발생합니다.
  • 이럴때는 아래와 같이 cacheWidth, cacheHeight 속성을 이용합니다.
      Image.file(File(filepath), 
        cacheWidth: newWidth, 
        cacheHeight: newHeight));
    
광고를 클릭해주시면 블로그운영에 큰 힘이 됩니다.
  • 실제 이미지의 크기와 다르게 위에서 지정한 값으로 로딩하여 레이아웃에 반영하기 때문에 사용하는 메모리를 현격하게 줄일 수 있습니다.
    • 이미지1