웹사이트 검색

앱 플랫폼에서 MemCachier로 Express 애플리케이션을 배포하고 확장하는 방법


저자는 Write for DOnations 프로그램을 선택했습니다.

소개

memcached 개체 캐싱 시스템을 사용하지만 고가용성 클러스터를 사용한 더 나은 실패 시나리오와 같은 몇 가지 이점이 있습니다.

먼저 소수를 계산하고, 좋아요 버튼이 있고, 템플릿 엔진을 사용하는 Express 앱을 빌드합니다. 이러한 기능을 사용하면 나중에 여러 캐싱 전략을 구현할 수 있습니다. 그런 다음 앱의 코드를 GitHub에 푸시하고 앱 플랫폼에 배포합니다. 마지막으로 세 가지 개체 캐싱 기술을 구현하여 앱을 더 빠르고 확장 가능하게 만듭니다. 이 자습서를 마치면 리소스 집약적인 계산, 렌더링된 뷰 및 세션을 캐싱하는 기술을 구현하여 App Platform에 Express 애플리케이션을 배포할 수 있습니다.

전제 조건

  • 컴퓨터에 설치된 Node.js. Node.js를 설치하고 로컬 개발 환경을 만드는 방법으로 설정할 수 있습니다.
  • Node.js가 포함된 기본 Express 서버. Node.js 및 Express 시작 방법에 대한 자습서의 1-2단계를 따르십시오.
  • 설정을 위한 Git 설치 방법
  • 자세한 내용은 앱 플랫폼 가격입니다.
  • Chrome과 같은 웹 브라우저
  • Express 템플릿 엔진에 대한 이해
  • Express 미들웨어에 대한 이해. Express.js에서 사용자 지정 미들웨어를 만드는 방법 자습서에서 이 주제에 대해 자세히 알아볼 수 있습니다.

1단계 - 빠른 템플릿 렌더링 보기 설정

이 단계에서는 Express용 템플릿 엔진을 설치하고 앱의 홈 경로(GET /)에 대한 템플릿을 만들고 해당 템플릿을 사용하도록 경로를 업데이트합니다. 템플릿 엔진을 사용하면 나중에 렌더링된 뷰를 캐시하여 요청 처리 속도를 높이고 리소스 사용을 줄일 수 있습니다.

시작하려면 아직 열려 있지 않은 경우 편집기를 사용하여 Express 서버의 프로젝트 디렉토리로 이동하십시오. Node.js 및 Express를 시작하는 방법에 대한 필수 자습서로 돌아가서 프로젝트 파일을 저장한 위치를 식별할 수 있습니다.

애플리케이션에서 정적 템플릿 파일을 사용하기 위해 Express용 템플릿 엔진을 설치합니다. 템플릿 엔진은 템플릿 파일의 변수를 값으로 바꾸고 템플릿을 요청에 대한 응답으로 전송되는 HTML 파일로 변환합니다. 템플릿을 사용하면 HTML 작업이 더 쉬워집니다.

Mustache, Pug 또는 Nunjucks와 같이 Express에서 지원하는 템플릿 엔진을 설치합니다.

  1. npm install ejs

이제 ejs가 설치되었으므로 이를 사용하도록 Express 앱을 구성합니다.

편집기에서 server.js 파일을 엽니다. 그런 다음 강조 표시된 줄을 추가합니다.

const express = require('express');

const app = express();

app.set('view engine', 'ejs');

app.get('/', (req, res) => {
  res.send('Successful response.');
});

...

이 줄은 응용 프로그램 설정 속성 view engineejs로 설정합니다.

파일을 저장합니다.

참고: 이 자습서에서는 뷰 엔진 설정을 사용하지만 다른 유용한 설정은 입니다. views 설정은 템플릿 파일을 찾을 위치를 Express 앱에 알려줍니다. 기본값은 ./views입니다.

다음으로 views 디렉토리를 생성합니다. 그런 다음 views/index.ejs 파일을 만들고 편집기에서 엽니다.

해당 파일에 시작 템플릿 마크업을 추가합니다.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Find the largest prime number</title>
  </head>
  <body>
    <h1>Find the largest prime number</h1>

    <p>
      For any number N, find the largest prime number less than or equal to N.
    </p>
  </body>
</html>

파일을 저장합니다.

템플릿이 생성되면 이를 사용하도록 경로를 업데이트합니다.

server.js 파일을 열고 강조 표시된 코드를 업데이트합니다.

...

app.get('/', (req, res) => {
  res.render('index');
});

...

응답 render 메서드는 템플릿의 이름을 첫 번째 매개변수로 사용합니다. 이 경우 indexviews/index.ejs 파일과 일치합니다.

변경 사항을 로드하려면 앱을 다시 시작하세요. 실행 중인 경우 터미널에서 CTRL+C를 눌러 서버를 중지합니다. 그런 다음 서버를 다시 시작합니다.

  1. node server.js

이제 웹 브라우저에서 localhost:3000을 방문하면 템플릿의 내용이 표시됩니다.

이제 앱에 템플릿 렌더링 보기가 있지만 아직 아무 작업도 수행하지 않습니다. 다음에 소수를 찾는 기능을 추가할 것입니다.

2단계 - Express 앱에 기능 추가

이 단계에서는 좋아요 버튼을 사용하여 소수를 찾고 숫자를 좋아하는 기능을 추가합니다. 4단계에서 앱 플랫폼에 배포한 후 이러한 기능을 사용하여 앱과 상호 작용하게 됩니다.

소수 찾기

이 섹션에서는 N보다 작거나 같은 가장 큰 소수를 찾는 함수를 앱에 추가합니다. 여기서 N은 모든 숫자를 나타냅니다.

N은 홈 경로(/)에 대한 GET 메서드가 있는 양식을 통해 제출되며 N이 추가됩니다. 쿼리 매개변수: localhost:3000/?n=10(여기서 10은 샘플 쿼리임). 홈 경로에는 각각 개별적으로 캐시될 수 있는 렌더링된 보기를 생성하는 여러 URL이 있을 수 있습니다.

views/index.ejs에서 N을 입력하기 위한 입력 요소가 있는 양식을 추가합니다.

...

<p>
  For any number N, find the largest prime number less than or equal to N.
</p>

<form action="/" method="get">
  <label>
    N
    <input type="number" name="n" placeholder="e.g. 10" required>
  </label>
  <button>Find Prime</button>
</form>

...

양식의 작업은 server.js의 홈 경로 app.get(/ ...)에 의해 처리되는 /에 제출됩니다. 양식의 메소드가 get으로 설정되어 있으므로 n 데이터가 쿼리 매개변수로 작업 URL에 추가됩니다.

파일을 저장합니다.

다음으로 n의 쿼리 매개변수로 요청이 이루어지면 해당 데이터를 템플릿에 전달합니다.

server.js에서 강조 표시된 코드를 추가합니다.

...

app.get('/', (req, res) => {
  const n = req.query.n;
  
  if (!n) {
    res.render('index');
    return;
  }
  
  const locals = { n };
  res.render('index', locals);
});

...

이 줄은 요청에 n이라는 쿼리 매개변수가 있는지 확인합니다. 그렇다면 index 보기를 렌더링하고 n 값을 전달합니다. 그렇지 않으면 데이터 없이 인덱스 보기를 생성합니다.

참고: 사용자 입력을 항상 신뢰할 수 있는 것은 아니므로 프로덕션 준비 앱에 대한 모범 사례는 Joi와 같은 라이브러리로 입력을 검증하는 것입니다.

render 메서드에는 두 번째 선택적 매개 변수인 locals가 있습니다. 이 매개변수는 뷰를 렌더링하기 위해 템플릿에 전달되는 로컬 변수를 정의합니다. 속기 속성 이름은 locals 개체의 n 속성을 정의합니다. 변수가 할당되는 개체 속성과 동일한 이름을 가진 경우 변수 이름을 생략할 수 있습니다. 따라서 { n: n }{ n }로 쓸 수 있습니다.

파일을 저장합니다.

이제 템플릿에 일부 데이터가 있으므로 표시할 수 있습니다.

views/index.ejs에서 강조 표시된 줄을 추가하여 N 값을 표시합니다.

...

<form action="/" method="get">
  <label>
    N
    <input type="number" name="n" placeholder="e.g. 10" required>
  </label>
  <button>Find Prime</button>
</form>

<% if (locals.n) { %>
  <p>N: <%= n %></p>
<% } %>

...

이 보기에 대한 로컬 변수 n이 있는 경우 이를 표시하도록 앱에 지시합니다.

파일을 저장한 다음 서버를 다시 시작하여 앱을 새로 고칩니다. 이제 양식이 프라임 찾기 버튼과 함께 로드됩니다. 앱은 사용자 입력을 수락하고 양식 아래에 표시할 수 있습니다.

양식에 번호를 제출하십시오. 양식을 제출하면 URL이 n 쿼리 매개변수(예: http://localhost:3000/?n=40)를 포함하도록 변경됩니다. 40을 넣으면. 제출한 값도 N: 40 형식으로 로드됩니다.

이제 N에 대한 값을 제출하고 표시할 수 있으므로 N보다 작거나 같은 가장 큰 소수를 찾는 함수를 추가합니다. 그런 다음 해당 결과를 보기에 표시합니다.

utils 디렉토리를 생성합니다. 그런 다음 utils/findPrime.js 파일을 만듭니다.

편집기에서 findPrime.js를 열고 소수 찾기 기능을 추가합니다.

/**
 * Find the largest prime number less than or equal to `n`
 * @param {number} n A positive integer greater than the smallest prime number, 2
 * @returns {number}
 */
module.exports = function (n) {
  let prime = 2; // initialize with the smallest prime number
  for (let i = n; i > 1; i--) {
    let isPrime = true;
    for (let j = 2; j < i; j++) {
      if (i % j == 0) {
        isPrime = false;
        break;
      }
    }
    if (isPrime) {
      prime = i;
      break;
    }
  }
  return prime;
};

JSDoc 주석은 기능을 문서화합니다. 알고리즘은 첫 번째 소수(2)로 시작한 다음 n에서 시작하여 각 루프에서 숫자를 1씩 감소시키면서 숫자를 반복합니다. . 이 함수는 숫자가 가장 작은 소수인 2가 될 때까지 루프를 계속 돌면서 소수를 검색합니다.

각 루프는 현재 숫자가 소수라고 가정한 다음 해당 가정을 테스트합니다. 현재 숫자에 1 이외의 요소가 있는지 확인합니다. 현재 숫자를 나머지 없이 1보다 크고 자체보다 작은 숫자로 나눌 수 있으면 소수가 아닙니다. 그러면 함수는 다음 숫자를 시도합니다.

파일을 저장합니다.

다음으로 find prime 함수를 server.js로 가져옵니다.

const express = require('express');
const findPrime = require('./utils/findPrime');

...

홈 경로 컨트롤러를 업데이트하여 소수를 찾고 해당 값을 템플릿에 전달합니다. 여전히 server.js에서 강조 표시된 코드를 추가합니다.

...

app.get('/', (req, res) => {
  const n = req.query.n;

  if (!n) {
    res.render('index');
    return;
  }
  
  const prime = findPrime(n);

  const locals = { n, prime };
  res.render('index', locals);
});

...

파일을 저장합니다.

이제 템플릿에 결과를 표시하는 코드를 추가합니다. views/index.ejs에서 N 값을 표시합니다.

...

<form action="/" method="get">
  <label>
    N
    <input type="number" name="n" placeholder="e.g. 10" required>
  </label>
  <button>Find Prime</button>
</form>

<% if (locals.n && locals.prime) { %>
  <p>
    The largest prime number less than or equal to <%= n %> is <strong><%= prime %></strong>.
  </p>
<% } %>
...

파일을 저장합니다.

이제 서버를 다시 시작하십시오.

기능을 테스트하려면 번호를 제출하십시오. 예를 들어 이 자습서에서는 10을 사용합니다. 숫자 10을 제출하면 10보다 작거나 같은 가장 큰 소수는 < 마크>7..

이제 앱에서 숫자를 받은 다음 소수를 찾아서 표시할 수 있습니다. 다음으로 좋아요 버튼을 추가합니다.

좋아요 버튼 추가

현재 앱은 제출된 각 숫자 N에 따라 다른 보기를 생성할 수 있습니다. 텍스트를 업데이트하는 것 외에도 이러한 보기의 콘텐츠는 동일하게 유지될 수 있습니다. 이 섹션에서 추가할 좋아요 버튼은 보기의 콘텐츠를 업데이트하는 방법을 제공합니다. 이 버튼은 컨텐츠가 변경될 때 캐시된 보기를 무효화해야 하는 필요성을 보여줍니다. 이는 튜토리얼 후반부에서 렌더링된 보기를 캐시할 때 유용할 것입니다.

좋아요 버튼을 사용하면 앱에서 좋아요 데이터를 저장할 위치가 필요합니다. 영구 저장소가 이상적이지만 데이터베이스 구현은 이 자습서의 범위를 벗어나므로 좋아요를 메모리에 저장합니다. 따라서 데이터는 일시적이므로 서버가 중지되면 모든 데이터가 손실됩니다.

server.js를 열어 다음 변수를 추가합니다.

...

app.set('view engine', 'ejs');

/**
 * Key is `n`
 * Value is the number of 'likes' for `n`
 */
const likesMap = {};

...

likesMap 개체는 요청된 모든 숫자에 대한 좋아요를 저장하는 맵으로 사용됩니다. 키는 n이고 그 값은 n에 대한 좋아요 수입니다.

숫자에 대한 좋아요는 숫자가 제출될 때 초기화되어야 합니다. 여전히 server.js에서 강조 표시된 줄을 추가하여 N에 대한 좋아요를 초기화합니다.

...

  const prime = findPrime(n);

  // Initialize likes for this number when necessary
  if (!likesMap[n]) likesMap[n] = 0;

  const locals = { n, prime };
  res.render('index', locals);

...

if 문은 현재 번호에 대한 좋아요가 있는지 확인합니다. 좋아요가 없으면 likesMaps 번호가 0으로 초기화됩니다.

다음으로 보기에 대한 로컬 변수로 좋아요를 추가합니다.

...

  const prime = findPrime(n);

  // Initialize likes for this number when necessary
  if (!likesMap[n]) likesMap[n] = 0;

  const locals = { n, prime, likes: likesMap[n] };
  res.render('index', locals);

...

파일을 저장합니다.

보기에 좋아요에 대한 데이터가 있으므로 해당 값을 표시하고 좋아요 버튼을 추가할 수 있습니다.

views/index.ejs에서 Like 버튼 마크업을 추가합니다.

...

<% if (locals.n && locals.prime) { %>
  <p>
    The largest prime number less than or equal to <%= n %> is <strong><%= prime %></strong>.
  </p>

  <form action="/like" method="get">
    <input type="hidden" name="n" value="<%= n %>">
    <input type="submit" value="Like"> <%= likes %>
  </form>
<% } %>
...

완성된 파일은 이제 다음과 일치해야 합니다.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Find the largest prime number</title>
  </head>
  <body>
    <h1>Find the largest prime number</h1>

    <p>
      For any number N, find the largest prime number less than or equal to N.
    </p>

    <form action="/" method="get">
      <label>
        N
        <input type="number" name="n" placeholder="e.g. 10" required>
      </label>
      <button>Find Prime</button>
    </form>

    <% if (locals.n && locals.prime) { %>
      <p>
        The largest prime number less than or equal to <%= n %> is <strong><%= prime %></strong>.
      </p>
      <form action="/like" method="get">
        <input type="hidden" name="n" value="<%= n %>">
        <input type="submit" value="Like"> <%= likes %>
      </form>
    <% } %>
  </body>
</html>

파일을 저장합니다.

서버를 다시 시작한 다음 번호를 제출하십시오. 좋아요 버튼은 좋아요 수가 0인 소수 결과 뒤에 나타납니다.

좋아요 버튼을 클릭하면 GET 요청이 /like로 전송되며, 현재 값 N은 숨겨진 입력을 통해 쿼리 매개변수로 사용됩니다. 지금은 앱에 아직 해당 경로가 없기 때문에 Cannot GET /like와 함께 404 오류가 표시됩니다.

이제 요청을 처리할 경로를 추가합니다.

server.js로 돌아가서 다음 경로를 추가합니다.

...

app.get('/', (req, res) => {
  ...
});

app.get('/like', (req, res) => {
  const n = req.query.n;

  if (!n) {
    res.redirect('/');
    return;
  }

  likesMap[n]++;

  res.redirect(`/?n=${n}`);
});

...

이 새 경로는 n이 존재하는지 확인합니다. 그렇지 않은 경우 홈으로 리디렉션됩니다. 그렇지 않으면 이 숫자에 대한 좋아요가 증가합니다. 마지막으로 좋아요 버튼을 클릭한 보기로 리디렉션됩니다.

완성된 파일은 이제 다음과 일치해야 합니다.

const express = require('express');
const findPrime = require('./utils/findPrime');

const app = express();

app.set('view engine', 'ejs');

/**
 * Key is `n`
 * Value is the number of 'likes' for `n`
 */
const likesMap = {};

app.get('/', (req, res) => {
  const n = req.query.n;
  
  if (!n) {
    res.render('index');
    return;
  }
  
  const prime = findPrime(n);

  // Initialize likes for this number when necessary
  if (!likesMap[n]) likesMap[n] = 0;

  const locals = { n, prime, likes: likesMap[n] };
  res.render('index', locals);
});

app.get('/like', (req, res) => {
  const n = req.query.n;

  if (!n) {
    res.redirect('/');
    return;
  }

  likesMap[n]++;

  res.redirect(`/?n=${n}`);
});

const port = process.env.PORT || 3000;
app.listen(port, () =>
  console.log(`Example app is listening on port ${port}.`)
);

파일을 저장합니다.

앱을 다시 시작하고 좋아요 버튼을 다시 테스트합니다. 좋아요 수는 클릭할 때마다 증가합니다.

참고: 이 경로에 대해 GET 대신 POST 메서드를 사용할 수도 있습니다. 리소스에 대한 업데이트가 이루어지기 때문에 더 RESTful합니다. 이 자습서에서는 양식 POST 요청 본문 처리를 도입하는 대신 GET를 사용하므로 이제는 친숙한 요청 쿼리 매개변수로 작업할 수 있습니다.

이제 앱이 완벽하게 작동하는 기능을 갖추고 있으므로 App Platform에 배포할 준비를 할 수 있습니다. 다음 단계에서는 git로 앱의 코드를 커밋하고 해당 코드를 GitHub에 푸시합니다.

3단계 - 코드 리포지토리 생성

이 단계에서는 배포를 위한 모든 파일을 보관할 코드 리포지토리를 생성합니다. 먼저 코드를 git에 커밋한 다음 GitHub 리포지토리에 푸시합니다. 이 리포지토리를 사용하여 App Platform으로 배포합니다.

코드를 Git에 커밋

이 섹션에서는 코드를 git에 커밋하여 GitHub에 푸시할 준비가 되었습니다.

참고: 사용자 이름으로 설정을 구성하지 않은 경우 Git을 설정하고 SSH로 GitHub 계정을 인증해야 합니다.

먼저 git 저장소를 초기화합니다.

  1. git init

다음으로 앱의 종속성을 제외하도록 Git에 지시합니다. .gitignore라는 새 파일을 만들고 다음을 추가합니다.

node_modules

# macOS file
.DS_Store

참고: .DS_Store 줄은 macOS에만 해당되며 다른 운영 체제에는 존재할 필요가 없습니다.

파일을 저장하고 닫습니다.

이제 모든 파일을 git에 추가합니다.

  1. git add .

마지막으로 다음 명령을 사용하여 변경 사항을 커밋합니다.

  1. git commit -m "Initial commit"

-m 옵션은 원하는 메시지로 업데이트할 수 있는 커밋 메시지를 지정하는 데 사용됩니다.

코드를 커밋하면 다음과 같은 출력이 표시됩니다.

Output
[main (root-commit) deab84e] Initial commit 6 files changed, 1259 insertions(+) create mode 100644 .gitignore create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 server.js create mode 100644 utils/findPrime.js create mode 100644 views/index.ejs

코드를 git에 커밋했습니다. 다음으로 GitHub에 푸시합니다.

코드를 GitHub 리포지토리로 푸시

이제 앱의 코드가 git에 커밋되었으므로 GitHub에 푸시할 준비가 되었습니다. 그런 다음 코드를 DigitalOcean App Platform과 연결하고 배포할 수 있습니다.

먼저 브라우저에서 새 리포지토리 생성에 대한 GitHub 및 GitHub 설명서에 로그인합니다.

터미널로 돌아가서 새로 만든 리포지토리를 원격 원본으로 추가하고 사용자 이름을 업데이트합니다.

  1. git remote add origin https://github.com/your_username/express-memcache.git

이 명령은 코드를 푸시할 위치를 Git에 알려줍니다.

다음으로 기본 브랜치 main의 이름을 바꿉니다.

  1. git branch -M main

마지막으로 코드를 리포지토리에 푸시합니다.

  1. git push -u origin main

메시지가 표시되면 자격 증명을 입력합니다.

다음과 유사한 출력이 표시됩니다.

Output
Enumerating objects: 10, done. Counting objects: 100% (10/10), done. Delta compression using up to 8 threads Compressing objects: 100% (7/7), done. Writing objects: 100% (10/10), 9.50 KiB | 9.50 MiB/s, done. Total 10 (delta 0), reused 0 (delta 0), pack-reused 0 To https://github.com/your_username/express-memcache.git * [new branch] main -> main Branch 'main' set up to track remote branch 'main' from 'origin'.

이제 앱 코드가 GitHub에 있으며 App Platform에서 배포할 준비가 되었습니다.

4단계 - 앱 플랫폼에 배포

이 단계에서는 Express 앱을 DigitalOcean 앱 플랫폼에 배포합니다. App Platform 앱을 만들고 GitHub 리포지토리에 액세스하도록 허용한 다음 배포합니다.

PORT 환경 레이블에서 구성을 읽을 수 있도록 환경 설정을 업데이트하는 것부터 시작합니다.

앱의 환경 설정 업데이트

이 섹션에서는 환경 변수에서 앱의 포트 구성을 읽을 수 있도록 Express 서버를 확장합니다. 배포 간에 구성이 변경될 수 있으므로 이 업데이트를 통해 앱이 앱 플랫폼 환경에서 포트를 읽을 수 있습니다.

편집기에서 server.js 파일을 엽니다. 그런 다음 파일 맨 아래에서 강조 표시된 코드를 업데이트하여 기존 app.listen 줄을 바꾸고 새 const port 줄을 추가합니다.

...

const port = process.env.PORT || 3000;
app.listen(port, () =>
  console.log(`Example app is listening on port ${port}.`)
);

이 코드는 환경 변수가 있는 경우 PORT 환경 변수를 사용하고 그렇지 않은 경우 기본적으로 포트 3000을 사용하도록 나타냅니다.

이제 앱이 앱을 배포할 앱 플랫폼 환경에서 포트를 읽을 수 있습니다.

앱 플랫폼에서 앱 생성 및 배포

이제 App Platform으로 앱을 설정할 수 있습니다.

앱 플랫폼에서 이 앱을 실행하면 요금이 부과되며 웹 서비스는 초 단위로 청구됩니다(최소 1분부터 시작). 검토 화면에 가격이 표시됩니다. 자세한 내용은 앱 플랫폼 가격 책정을 참조하세요.

먼저 DigitalOcean 계정에 로그인합니다. 앱 플랫폼에서 앱을 만드는 방법에 대한 제품 설명서에서 가져왔습니다.

소스 코드에서 리소스 만들기 화면에서 GitHub를 서비스 공급자로 선택합니다. 그런 다음 저장소에 액세스할 수 있는 DigitalOcean 권한을 부여합니다. 가장 좋은 방법은 배포하려는 리포지토리만 선택하는 것입니다. 아직 설치하지 않은 경우 DigitalOcean GitHub 앱을 설치하라는 메시지가 표시됩니다. 목록에서 리포지토리를 선택하고 다음을 클릭합니다.

자원 화면에서 계획 편집을 클릭하여 계획 크기를 선택하십시오. 이 자습서에서는 express-memcache 리소스에 대해 가장 작은 크기의 웹 서비스(512MB RAM | 1 vCPU)가 포함된 기본 계획을 사용합니다. 기본 계획 및 가장 작은 웹 서비스는 이 샘플 Express 앱에 충분한 리소스를 제공합니다. 계획을 설정했으면 뒤로를 클릭합니다.

그런 다음 왼쪽 탐색 모음에서 정보 탭을 클릭하고 앱이 있는 지역을 기록해 둡니다. 다음 단계에서 MemCachier용 DigitalOcean Marketplace 추가 기능을 추가할 때 이 정보가 필요합니다.

마지막으로 검토 탭을 클릭한 다음 리소스 만들기 버튼을 클릭하여 앱을 빌드하고 배포합니다. 빌드가 실행되는 데 약간의 시간이 걸립니다. 완료되면 배포된 앱에 대한 링크가 포함된 성공 메시지를 받게 됩니다.

지금까지 소수를 찾고 좋아요 버튼이 있는 Express 앱을 만들었습니다. 앱의 코드를 Git에 커밋하고 GitHub에 푸시한 다음 App Platform에 앱을 배포했습니다.

Express 앱을 더 빠르고 확장 가능하게 만들기 위해 세 가지 개체 캐싱 전략을 구현합니다. 다음 단계에서 만들 캐시가 필요합니다.

5단계 - MemCachier로 개체 캐시 구성

이 단계에서는 개체 캐시를 만들고 구성합니다. DigitalOcean Marketplace의 모든 MemCachier 애드온. MemCachier 캐시는 메모리 내 키-값 저장소입니다.

먼저 DigitalOcean Marketplace에서 MemCachier 애드온을 추가합니다. MemCachier 추가 기능 페이지를 방문하여 MemCachier 추가를 클릭합니다. 다음 화면에서 앞에서 기록한 App Platform 앱이 있는 지역을 선택합니다. 대기 시간이 가능한 한 낮아지도록 앱과 캐시가 동일한 지역에 있어야 합니다. 지역을 다시 찾아야 하는 경우 앱 플랫폼 앱의 설정을 볼 수 있습니다. 선택적으로 계획을 선택할 수 있습니다. 그런 다음 MemCachier 추가를 클릭하여 캐시를 프로비저닝합니다.

지역 이름-슬러그 매핑을 파악하려면 DigitalOcean의 사용 가능한 데이터 센터를 참조하십시오. 예를 들어 San Francisco 지역은 sfo3에 매핑됩니다.

다음으로 캐시를 사용하도록 Express 앱을 구성합니다. 추가 기능 대시보드를 방문한 다음 MemCachier 추가 기능의 이름을 클릭하여 해당 대시보드를 여십시오. MemCachier 추가 기능 대시보드에서 구성 변수에 대한 표시 버튼을 클릭하여 MEMCACHIER_USERNAME, MEMCACHIER_PASSWORDMEMCACHIER_SERVERS에 대한 값이 있는 디스플레이를 로드합니다. . 다음에 필요하므로 이 값을 기록해 두십시오.

이제 MemCachier 구성 변수를 앱의 환경 변수로 저장합니다. App Platform 앱의 대시보드로 돌아가 설정을 클릭합니다. 그런 다음 구성 요소에서 express-memc…를 클릭합니다. 환경 변수 섹션으로 스크롤하고 편집을 클릭한 다음 세 개의 키(MEMCACHIER_USERNAME, MEMCACHIER_PASSWORDMEMCACHIER_SERVERS)를 사용하여 MemCachier 구성 변수를 추가하고 MemCachier 대시보드에서 얻은 해당 값. MEMCACHIER_PASSWORD의 경우 값이 비밀번호이므로 암호화를 선택합니다. 저장을 클릭하여 앱을 업데이트합니다.

이제 앱이 캐시와 통신할 수 있도록 방금 저장한 환경 변수를 사용하여 Express 앱에서 Memcache 클라이언트를 구성합니다.

터미널에서 memjs 라이브러리를 설치합니다.

  1. npm install memjs

다음으로 services 디렉터리를 만듭니다. 그런 다음 services/memcache.js 파일을 만들고 편집기에서 엽니다. 파일 상단에서 memjs를 가져오고 캐시 클라이언트를 구성합니다.

const { Client } = require('memjs');

module.exports = Client.create(process.env.MEMCACHIER_SERVERS, {
  failover: true,
  timeout: 1,
  keepAlive: true,
});

파일을 저장합니다.

이 코드는 MemCachier 캐시 클라이언트를 생성합니다. 옵션의 경우 failovertrue로 설정되어 MemCachier의 고가용성 클러스터를 사용합니다. 서버에 오류가 발생하면 해당 서버에 저장된 모든 키에 대한 명령이 자동으로 다음 사용 가능한 서버로 전달됩니다. 1초의 timeout이 기본 0.5초보다 배포된 앱에 더 좋습니다. keepAlive: true는 유휴 상태일 때도 캐시에 대한 연결을 열어 둡니다. 이는 연결이 느리고 캐시가 효과적이려면 빨라야 하기 때문에 바람직합니다.

이 단계에서는 DigitalOcean Marketplace의 MemCachier 추가 기능을 사용하여 캐시를 프로비저닝했습니다. 그런 다음 캐시의 구성 설정을 앱 플랫폼 환경 변수로 추가하여 Express 앱이 캐시와 통신할 수 있도록 memjs를 사용하여 클라이언트를 구성할 수 있습니다.

Express에서 캐싱 구현을 시작할 모든 준비가 완료되었으며 다음에 수행할 작업입니다.

6단계 - MemCachier를 사용하여 Express에서 캐싱 구현

Express 앱이 배포되고 MemCachier 추가 기능이 프로비저닝되면 이제 객체 캐시를 사용할 수 있습니다. 이 단계에서는 세 가지 개체 캐싱 기술을 구현합니다. 사용 속도와 효율성을 개선하기 위해 리소스 집약적인 계산을 캐싱하는 것부터 시작합니다. 그런 다음 사용자 입력 후 렌더링된 뷰를 캐시하는 기술을 구현하여 요청 처리를 개선하고 이 튜토리얼 이후로 앱 확장을 예상하여 단기 세션을 캐시합니다.

높은 리소스 계산 캐싱

이 섹션에서는 리소스를 많이 사용하는 계산을 캐시하여 앱 속도를 높이고 결과적으로 CPU를 더 효율적으로 사용합니다. findPrime 함수는 충분한 숫자가 제출될 때 리소스를 많이 사용하는 계산입니다. 계산을 반복하는 대신 가능한 경우 결과를 캐시하고 캐시된 값을 제공합니다.

먼저 server.js를 열어 memcache 클라이언트를 추가합니다.

const express = require('express');
const findPrime = require('./utils/findPrime');
const memcache = require('./services/memcache');

...

그런 다음 계산된 소수를 캐시에 저장합니다.

...

  const prime = findPrime(n);

  const key = 'prime_' + n;

  memcache.set(key, prime.toString(), { expires: 0 }, (err) => {
    if (err) console.log(err);
  });

...

파일을 저장합니다.

set 메소드는 첫 번째 매개변수로 키를 사용하고 두 번째로 문자열 값을 사용하므로 prime 숫자를 문자열로 변환합니다. 세 번째 options 인수는 저장된 항목이 만료되지 않도록 합니다. 네 번째이자 마지막 매개변수는 선택적 콜백으로, 존재하는 경우 오류가 발생합니다.

참고: 가장 좋은 방법은 캐시 오류를 적절하게 처리하는 것입니다. 캐시는 향상된 기능이며 일반적으로 실패 시 앱이 충돌하지 않아야 합니다. 앱은 캐시 없이도 더 느리지만 완벽하게 잘 작동할 수 있습니다.

참고: 이 시점에서 앱은 캐싱 없이 계속 로컬에서 작동합니다. memcache.set이 호출되면 캐시 서버를 찾을 수 없기 때문에 오류가 출력됩니다.

Output
MemJS: Server <localhost:11211> failed after (2) retries with error - connect ECONNREFUSED 127.0.0.1:11211 Error: No servers available ...

이 자습서의 나머지 부분에서는 로컬 캐싱이 필요하지 않습니다. 작동하게 하려면 memjs 기본값인 localhost:11211에서 memcached를 실행할 수 있습니다.

다음으로 변경 사항을 준비하고 커밋합니다.

  1. git add . && git commit -m "Add memjs client and cache prime number"

그런 다음 이러한 변경 사항을 GitHub에 푸시하면 App Platform에 자동으로 배포됩니다.

  1. git push

앱 플랫폼 대시보드는 배포됨 메시지에서 앱이 빌드되고 있음을 나타내는 메시지로 전환됩니다. 빌드가 완료되면 브라우저에서 앱을 열고 숫자를 제출하여 가장 큰 소수를 찾습니다.

참고: 대시보드에 서비스 대기 중 메시지가 표시될 수 있습니다. 해당 메시지는 일반적으로 저절로 해결됩니다. 오래 지속되면 앱을 새로고침하여 빌드가 배포되었는지 확인하세요.

그런 다음 애드온 대시보드로 돌아가 명명된 서비스에 대한 MemCachier 보기 옵션을 클릭하여 캐시의 분석 대시보드를 봅니다.

이 대시보드에서 All Time Stats 보드의 Set Cmds 옵션과 Storage 보드의 항목 통계가 모두 1씩 증가했습니다. 숫자를 제출할 때마다 Set Cmds와 Items가 모두 증가합니다. 새 통계를 로드하려면 새로고침 버튼을 눌러야 합니다.

참고: 앱 플랫폼에서 앱의 로그를 확인하는 것은 디버깅에 유용할 수 있습니다. 앱의 대시보드에서 런타임 로그를 클릭하여 확인합니다.

캐시에 저장된 항목을 사용하여 사용할 수 있습니다. 이제 항목이 캐시되었는지 확인하고 캐시된 경우 캐시에서 제공합니다. 그렇지 않으면 이전과 같이 소수를 찾을 수 있습니다.

server.js로 돌아가 강조 표시된 줄로 파일을 업데이트합니다. 기존 줄을 수정하고 캐시에 새 줄을 추가합니다.

...

app.get('/', (req, res) => {
  const n = req.query.n;

  if (!n) {
    res.render('index');
    return;
  }

  let prime;

  const key = 'prime_' + n;

  memcache.get(key, (err, val) => {
    if (err) console.log(err);

    if (val !== null) {
      // Use the value from the cache
      // Convert Buffer string before converting to number
      prime = parseInt(val.toString());
    } else {
      // No cached value available, find it
      prime = findPrime(n);

      memcache.set(key, prime.toString(), { expires: 0 }, (err) => {
        if (err) console.log(err);
      });
    }

    // Initialize likes for this number when necessary
    if (!likesMap[n]) likesMap[n] = 0;

    const locals = { n, prime, likes: likesMap[n] };
    res.render('index', locals);
  });
});

...

파일을 저장합니다.

이 코드는 이제 값이 재할당되므로 let 키워드를 사용하여 값 없이 prime을 초기화합니다. 그런 다음 memcache.get은 캐시된 소수를 검색하려고 시도합니다. 요청을 처리하는 방법을 결정하는 데 결과가 필요하기 때문에 대부분의 컨트롤러 코드는 이제 memcache.get 콜백에 상주합니다. 캐시된 값을 사용할 수 있으면 사용하십시오. 그렇지 않으면 계산을 수행하여 소수를 찾고 이전과 같이 결과를 캐시에 저장합니다.

memcache.get 콜백에서 반환된 값은 Buffer이므로 prime을 다시 숫자로 변환하기 전에 문자열로 변환합니다.

변경 사항을 커밋하고 GitHub에 푸시하여 배포합니다.

  1. git add . && git commit -m "Check cache for prime number" && git push

앱에 아직 캐시되지 않은 숫자를 제출하면 MemCachier 대시보드의 Set Cmds, Items 및 get misses 통계가 1씩 증가합니다. 항목을 설정하기 전에 캐시에서 항목을 가져오려고 하기 때문에 누락이 발생합니다. 항목이 캐시에 없으므로 미스가 발생하고 그 후에 항목이 저장됩니다. 캐시된 숫자를 제출하면 적중 횟수가 증가합니다.

이제 리소스 집약적인 계산을 캐싱하고 있습니다. 다음으로 앱의 렌더링된 보기를 캐시합니다.

렌더링된 뷰 캐싱

이 섹션에서는 미들웨어를 사용하여 Express 앱에서 렌더링한 보기를 캐시합니다. 이전에는 ejs를 템플릿 엔진으로 설정하고 제출된 각 N 번호에 대한 보기를 렌더링하는 템플릿을 만들었습니다. 렌더링된 뷰는 만드는 데 리소스를 많이 사용할 수 있으므로 캐싱하면 요청 처리 속도를 높이고 리소스를 더 적게 사용할 수 있습니다.

시작하려면 middleware 디렉터리를 만듭니다. 그런 다음 middleware/cacheView.js 파일을 만들고 편집기에서 엽니다. cacheView.js에서 미들웨어 기능에 대해 다음 줄을 추가합니다.

const memcache = require('../services/memcache');

/**
 * Express middleware to cache views and serve cached views
 */
module.exports = function (req, res, next) {
  const key = `view_${req.url}`;

  memcache.get(key, (err, val) => {
    if (err) console.log(err);

    if (val !== null) {
      // Convert Buffer string to send as the response body
      res.send(val.toString());
      return;
    }
  });
};

먼저 memcache 클라이언트를 가져옵니다. 그런 다음 view_/?n=100과 같은 키를 선언합니다. 다음으로 memcache.get을 사용하여 해당 키에 대한 뷰가 캐시에 있는지 확인합니다. 오류가 없고 해당 키에 대한 값이 존재하는 경우 더 이상 수행할 작업이 없으므로 클라이언트에 보기를 다시 전송하여 요청이 완료됩니다.

다음으로 보기가 캐시되지 않은 경우 캐시하려고 합니다. 이렇게 하려면 강조 표시된 줄을 추가하여 res.send 메서드를 재정의합니다.

...

module.exports = function (req, res, next) {
  const key = `view_${req.url}`;

  memcache.get(key, (err, val) => {
    if (err) console.log(err);

    if (val !== null) {
      // Convert Buffer to UTF-8 string to send as the response body
      res.send(val.toString());
      return;
    }

    const originalSend = res.send;
    res.send = function (body) {
      memcache.set(key, body, { expires: 0 }, (err) => {
        if (err) console.log(err);
      });

      originalSend.call(this, body);
    };
  });
};

평소와 같이 원래 send 함수를 호출하기 전에 캐시에 보기를 저장하는 함수로 res.send 메서드를 재정의합니다. call을 사용하여 원래 send 함수를 호출하면 this 컨텍스트를 재정의하지 않은 경우의 내용으로 설정합니다. 화살표 기능을 사용해야 함) 올바른 값이 지정됩니다.

그런 다음 강조 표시된 줄을 추가하여 다음 미들웨어로 제어를 전달합니다.

...

/**
 * Express middleware to cache views and serve cached views
 */
module.exports = function (req, res, next) {
  const key = `view_${req.url}`;

  memcache.get(key, (err, val) => {
    if (err) console.log(err);

    if (val !== null) {
      // Convert Buffer to UTF-8 string to send as the response body
      res.send(val.toString());
      return;
    }

    const originalSend = res.send;
    res.send = function (body) {
      memcache.set(key, body, { expires: 0 }, (err) => {
        if (err) console.log(err);
      });

      originalSend.call(this, body);
    };

    next();
  });
};

...

next를 호출하면 앱에서 next 미들웨어 기능이 호출됩니다. 귀하의 경우에는 다른 미들웨어가 없으므로 컨트롤러가 호출됩니다. Express용 res.render 메서드는 보기를 렌더링한 다음 해당 렌더링된 보기를 사용하여 내부적으로 res.send를 호출합니다. 이제 홈 경로의 컨트롤러에서 res.render가 호출될 때 재정의 함수가 호출되어 원래 send 함수를 최종적으로 호출하기 전에 캐시에 뷰를 저장합니다. 응답을 완료합니다.

파일을 저장합니다.

참고: 컨트롤러의 render 메서드에 콜백을 전달할 수도 있지만 캐시되는 각 경로에 대해 컨트롤러의 뷰 캐싱 코드를 복제해야 합니다.

이제 보기 캐싱 미들웨어를 server.js로 가져옵니다.

const express = require('express');
const findPrime = require('./utils/findPrime');
const memcache = require('./services/memcache');
const cacheView = require('./middleware/cacheView');

...

강조 표시된 코드를 추가하여 GET / 홈 경로와 함께 사용합니다.

...

app.get('/', cacheView, (req, res) => {
  ...
});

...

파일을 저장합니다.

그런 다음 변경 사항을 커밋하고 GitHub에 푸시하여 배포합니다.

  1. git add . && git commit -m "Add view caching" && git push

앱에서 번호를 제출하면 모든 것이 정상적으로 작동합니다. 새 숫자를 제출하면 Set Cmds, Items 및 get misses에 대한 MemCachier 대시보드 통계가 모두 2씩 증가합니다. 한 번은 소수 계산용이고 다른 한 번은 보기용입니다. 동일한 번호로 앱을 새로고침하면 MemCachier 대시보드에 단일 히트가 추가된 것을 볼 수 있습니다. 보기는 캐시에서 성공적으로 검색되었으므로 소수 결과를 가져올 필요가 없습니다.

참고: Express 애플리케이션 설정 캐시 보기는 프로덕션 환경에서 기본적으로 활성화되어 있습니다. 이 보기 캐시는 템플릿 출력의 내용을 캐시하지 않고 기본 템플릿 자체만 캐시합니다. 캐시가 켜져 있는 경우에도 요청이 있을 때마다 보기가 다시 렌더링됩니다. 따라서 구현한 렌더링된 뷰 캐싱과 다르지만 상호 보완적입니다.

뷰를 캐싱하고 있으므로 좋아요 버튼이 더 이상 작동하지 않는 것을 알 수 있습니다. likes 값을 기록하면 값이 실제로 변경됩니다. 그러나 좋아요 수가 변경되면 캐시된 보기를 업데이트해야 합니다. 보기가 변경되면 캐시된 보기를 무효화해야 합니다.

다음으로 좋아요가 변경되면 캐시에서 삭제하여 캐시된 보기를 무효화합니다. server.js로 돌아가서 redirect 함수를 업데이트하고 강조 표시된 줄을 추가합니다.

...

app.get('/like', (req, res) => {
  const n = req.query.n;

  if (!n) {
    res.redirect('/');
    return;
  }

  likesMap[n]++;

  // The URL of the page being 'liked'
  const url = `/?n=${n}`;

  res.redirect(url);
});

...

이 보기의 좋아요 수가 변경되었으므로 캐시된 버전이 유효하지 않습니다. 좋아요가 변경될 때 캐시에서 좋아요 수를 삭제하려면 강조 표시된 줄을 추가하세요.

...
  const url = `/?n=${n}`;

  // The view for this URL has changed, so the cached version is no longer valid, delete it from the cache.
  const key = `view_${url}`;
  memcache.delete(key, (err) => {
    if (err) console.log(err);
  });

  res.redirect(url);
...

이제 server.js 파일이 다음과 일치해야 합니다.

const express = require('express');
const findPrime = require('./utils/findPrime');
const memcache = require('./services/memcache');
const cacheView = require('./middleware/cacheView');

const app = express();

app.set('view engine', 'ejs');

/**
 * Key is `n`
 * Value is the number of 'likes' for `n`
 */
const likesMap = {};

app.get('/', cacheView, (req, res) => {
  const n = req.query.n;

  if (!n) {
    res.render('index');
    return;
  }

  let prime;

  const key = 'prime_' + n;

  memcache.get(key, (err, val) => {
    if (err) console.log(err);

    if (val !== null) {
      // Use the value from the cache
      // Convert Buffer string before converting to number
      prime = parseInt(val.toString());
    } else {
      // No cached value available, find it
      prime = findPrime(n);

      memcache.set(key, prime.toString(), { expires: 0 }, (err) => {
        if (err) console.log(err);
      });
    }

    // Initialize likes for this number when necessary
    if (!likesMap[n]) likesMap[n] = 0;

    const locals = { n, prime, likes: likesMap[n] };
    res.render('index', locals);
  });
});

app.get('/like', (req, res) => {
  const n = req.query.n;

  if (!n) {
    res.redirect('/');
    return;
  }

  likesMap[n]++;

  // The URL of the page being 'liked'
  const url = `/?n=${n}`;

  // The view for this URL has changed, so the cached version is no longer valid, delete it from the cache.
  const key = `view_${url}`;
  memcache.delete(key, (err) => {
    if (err) console.log(err);
  });

  res.redirect(url);
});

const port = process.env.PORT || 3000;
app.listen(port, () =>
  console.log(`Example app is listening on port ${port}.`)
);

파일을 저장합니다.

배포할 변경 사항을 커밋하고 푸시합니다.

  1. git add . && git commit -m "Delete invalid cached view" && git push

이제 앱의 좋아요 버튼이 작동합니다. 뷰가 좋아요를 누르면 MemCachier 대시보드에서 다음 통계가 변경됩니다.

  • 보기가 삭제됨에 따라 적중 항목 삭제가 증가합니다.
  • 보기가 삭제되었고 캐시에 없기 때문에 놓친 횟수가 증가합니다.
  • 캐시에서 소수가 발견되었기 때문에 적중 횟수가 증가합니다.
  • 업데이트된 보기가 캐시에 추가되기 때문에 Set Cmds가 증가합니다.
  • 보기가 삭제되고 다시 추가되더라도 항목은 동일하게 유지됩니다.

렌더링된 뷰 캐싱을 구현하고 캐시된 뷰가 변경될 때 무효화했습니다. 구현할 최종 전략은 세션 캐싱입니다.

캐싱 세션

이 섹션에서는 Express 앱에 세션을 추가하고 캐시하여 캐시를 세션 저장소로 만듭니다. 세션의 일반적인 사용 사례는 사용자 로그인이므로 세션 캐싱에 대한 이 섹션을 향후 사용자 로그인 시스템을 구현하기 위한 예비 단계로 고려할 수 있습니다(사용자 로그인 시스템은 이 자습서의 범위를 벗어남). 단기 세션을 캐시에 저장하면 많은 데이터베이스에 저장하는 것보다 더 빠르고 확장 가능합니다.

참고: 캐시는 시간 초과된 단기 세션을 저장하는 데 적합합니다. 그러나 캐시는 영구적이지 않습니다. 수명이 긴 세션은 데이터베이스와 같은 영구 스토리지 솔루션에 더 적합합니다.

MemCachier 캐시를 세션 저장소로 사용할 수 있도록 connect-memjs를 설치합니다.

  1. npm install express-session connect-memjs

server.js에서 express-sessionconnect-memjs를 가져옵니다.

const express = require('express');
const findPrime = require('./utils/findPrime');
const memcache = require('./services/memcache');
const cacheView = require('./middleware/cacheView');
const session = require('express-session');
const MemcacheStore = require('connect-memjs')(session);

...

파일을 저장합니다.

세션 미들웨어는 connect memcached 모듈로 전달되어 express.session.Store에서 상속할 수 있습니다.

여전히 server.js에서 캐시를 저장소로 사용하도록 세션 미들웨어를 구성합니다. 강조 표시된 줄을 추가합니다.

...

app.set('view engine', 'ejs');

app.use(
  session({
    secret: 'your-session-secret',
    resave: false,
    saveUninitialized: true,
    store: new MemcacheStore({
      servers: [process.env.MEMCACHIER_SERVERS],
      prefix: 'session_',
    }),
  })
);

...

비밀은 세션 쿠키에 서명하는 데 사용됩니다. 고유한 문자열로 your-session-secret을 업데이트해야 합니다.

참고: 프로덕션 설정을 위한 암호를 설정하려면 환경 변수를 사용해야 합니다. 이를 위해 secret으로 비밀을 설정할 수 있습니다. process.env.SESSION_SECRET || your-session-secret, 앱 플랫폼 대시보드에서 환경 변수도 설정해야 합니다.

resave는 요청 중에 수정되지 않은 경우 세션을 강제로 다시 저장합니다. 캐시에 항목을 불필요하게 다시 저장하지 않으려면 false로 설정합니다.

saveUninitialized: false는 인증 후 사용자 속성이 세션에 추가될 수 있는 로그인 세션의 경우와 같이 수정된 세션만 저장하려는 경우에 유용합니다. 이 경우 모든 세션을 무차별적으로 저장하게 되므로 true로 설정합니다.

마지막으로 store를 캐시로 설정하고 세션 캐시 키의 접두어를 session_로 설정합니다. 즉, 캐시에 있는 세션 항목의 키는 session_와 같습니다.

다음으로, 실행 중인 캐시된 세션을 식별하는 데 도움이 되는 강조 표시된 행과 함께 일부 앱 수준 디버깅 미들웨어를 추가합니다.

...

app.use(
  session({
    ...
  })
);

/**
 * Session sanity check middleware
 */
app.use(function (req, res, next) {
  console.log('Session ID:', req.session.id);

  // Get the item from the cache
  memcache.get(`session_${req.session.id}`, (err, val) => {
    if (err) console.log(err);

    if (val !== null) {
      console.log('Session from cache:', val.toString());
    }
  });

  next();
});

...

해당 미들웨어는 각 요청에 대한 세션 ID를 기록합니다. 그런 다음 캐시에서 해당 ID에 대한 세션을 가져오고 해당 내용을 기록합니다. 이 접근 방식은 세션이 작동하고 캐시되고 있음을 보여줍니다.

파일을 저장한 다음 커밋하고 변경 사항을 배포에 푸시합니다.

  1. git add . && git commit -m "Add session caching" && git push

앱에서 숫자를 제출한 다음 앱 플랫폼 대시보드에서 런타임 로그를 확인하여 디버깅 메시지에 액세스하십시오. 기록된 세션 ID와 값을 찾아 세션이 작동하고 캐시되고 있음을 보여줍니다.

MemCachier 대시보드에서 뷰와 세션이 캐시되면 페이지를 새로 고칠 때마다 3의 조회수가 표시됩니다. 뷰의 경우 1, 1는 세션용이고 1은 디버깅 미들웨어에서 세션을 가져오기 위한 것입니다.

이제 세션 캐싱을 구현했습니다. 여기에서 중지하거나 선택적 마지막 단계에서 앱을 정리할 수 있습니다.

(선택 사항) 7단계 - 리소스 정리

이 튜토리얼에서 배포한 앱에는 요금이 부과되므로 관련 작업을 마치면 앱과 MemCachier 추가 기능을 선택적으로 제거할 수 있습니다.

앱의 대시보드에서 작업을 클릭한 다음 앱 삭제를 클릭합니다.

MemCachier 추가 기능을 정리하려면 추가 기능을 클릭한 다음 MemCachier 추가 기능의 이름을 클릭하십시오. 그런 다음 설정 및 파괴를 클릭하십시오. 무료 MemCachier 캐시는 30일 동안 사용하지 않으면 비활성화되지만 도구를 정리하는 것이 좋습니다.

결론

이 자습서에서는 좋아요 버튼으로 소수를 찾는 Express 앱을 만들었습니다. 그런 다음 해당 앱을 GitHub에 푸시하고 DigitalOcean App Platform에 배포했습니다. 마지막으로 리소스 집약적인 계산, 렌더링된 보기 및 세션을 캐싱하기 위해 MemCachier 추가 기능으로 세 가지 객체 캐싱 기술을 구현하여 Express 앱을 더 빠르고 확장 가능하게 만들었습니다. DigitalOcean Community 저장소에서 이 튜토리얼의 모든 파일을 검토할 수 있습니다.

구현한 각 캐싱 전략에서 키에는 prime_, view_session_ 접두사가 있습니다. 네임스페이스 이점 외에도 접두사는 캐시 성능을 프로파일링할 수 있는 추가 이점을 제공합니다. 이 자습서에서는 MemCachier 개발자 플랜을 사용했지만 설명서를 검토할 수도 있습니다.

DigitalOcean 앱 플랫폼으로 계속 구축하려면 앱 플랫폼 설명서를 사용해 보십시오.