3. Azure Storage 설정
728x90

Azure storage 세팅

Azure Storage Access Key

해당 부분 복사

Azure Storage Container 생성

Azure Storage 에 mp4 파일 업로드

해당 container 로 들어가서 업로드 클릭

Azure Storage Container 업로드 완료 후 화면

Azure Storage에서 데이터를 가져오는 프로젝트 생성

Azure Storage 라이브러리 설치

npm install azure-storage --save

환경변수

window 환경 변수 설정

set PORT=3000
set STORAGE_ACCOUNT_NAME=<1번>
set STORAGE_ACCESS_KEY=<2번>

src/index.js 수정

const express = require('express')
const azure = require('azure-storage')
const app = express();

const PORT = process.env.PORT
const STORAGE_ACCOUNT_NAME= process.env.STORAGE_ACCOUNT_NAME;
const STORAGE_ACCESS_KEY= process.env.STORAGE_ACCESS_KEY;

function createBlobService() {
    const blobService = azure.createBlobService(STORAGE_ACCOUNT_NAME,STORAGE_ACCESS_KEY);

    return blobService;
}

app.get("/video",(req,res) => {
    const videoPath=  req.query.path;
    const blobService = createBlobService();

    const containerName = "bdmd1"
    blobService.getBlobProperties(containerName,videoPath,(err,properties) => {
        if(err) {
            res.sendStatus(500);

            return;
        }
        res.writeHead(200, {
            "Context-Length" : properties.contentLength,
            "Content-Type" : "video/mp4"
        });

        blobService.getBlobToStream(containerName,videoPath,res,err => {
            if(err){
                console.log(err && err.stack || err);
                res.sendStatus(500);
                return;
            }
        })
    })
});

app.listen(PORT, () => {
    console.log(`Microservice online`)
})

video-streaming 프로젝트 src/index.js 수정

const express = require("express")
const http = require("http")

const app = express()

const PORT = process.env.PORT
const VIDEO_STORAGE_HOST = process.env.VIDE_STORAGE_HOST
const VIDEO_STORAGE_PORT = parseInt(process.env.VIDEO_STORAGE_PORT)

app.get("/video", (req,res) => {
  const forwardRequest = http.request(
    {
      host: VIDEO_STORAGE_HOST,
      port: VIDEO_STORAGE_PORT,
      path: "/video?path=1234.mp4",
      method: "GET",
      headers: req.headers
    },
    forwardResponse => {
      res.writeHeader(forwardResponse.statusCode, forwardResponse.headers);
      forwardResponse.pipe(res)
    }
  );

  req.pipe(forwardRequest)
})

app.listen(PORT, () => {
  console.log(`Microservice online`)
})

Dockerfile 생성

FROM node:12.18.1-alpine

WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install --only=production
COPY ./src ./src
CMD npm start

docker yaml

version: '3'
services:

  azure-storage:
    image: azure-storage
    build:
      context: ./azure-storage
      dockerfile: Dockerfile
    container_name: video-storage
    ports:
      - "4000:80"
    environment:
      - PORT=80
      - STORAGE_ACCOUNT_NAME=<insert account name>
      - STORAGE_ACCESS_KEY=<insert access key>
    restart: "no"  

  video-streaming:
    image: video-streaming
    build: 
      context: ./my-new-project
      dockerfile: Dockerfile
    container_name: video-streaming
    ports:
     - "4001:80"
    environment:
      - PORT=80
      - VIDEO_STORAGE_HOST=video-storage
      - VIDEO_STORAGE_PORT=80
    restart: "no"

docker-compose.yml 실행

docker-compose up --build

왜 azure-storage 가 아니라 video-storage 일까?

추상적 의미, 나중에 azure-storage 가 아니라 aws s3 등 다른 부분과 대체할 수 있도록 설계한 부분

DB 추가

 db:
    image: mongo:4.2.8
    container_name: db
    ports:
      - "4000:27017"
    restart: always

각 서비스 마다 DB 가 달려있다.

객체 지향 프로그래밍에서 객체 안에서 데이터를 캡슐화 하듯이 마이크로서비스 내에서 데이터를 캡슐화 하기를 원하기 때문이다.

각 마이크로서비스마다 데이터베이스를 공유하거나 통합해서 사용하면 설계와 확장성 문제가 있다.

video-streaming ./src/index.js 수정

DB를 추가했기 때문에 streaming 을 하는 곳에서 DB 에 있는 데이터를 들고 오도록 해야함

const express = require("express");
const fs = require("fs");
const path = require("path");
const mongodb = require("mongodb")
const http = require('http')
const app = express();

if (!process.env.PORT) {
    throw new Error("Please specify the port number for the HTTP server with the environment variable PORT.");
}

const PORT = process.env.PORT;
const VIDEO_STORAGE_HOST = process.env.VIDEO_STORAGE_PORT
const VIDEO_STORAGE_PORT = parseInt(process.env.VIDEO_STORAGE_PORT)
const DBHOST = process.env.DBHOST
const DBNAME = process.env.DBNAME


function main() {
    return mongodb.MongoClient.connect(DBHOST)
        .then(client => {
            const db = client.db(DBNAME);
            const videosCollection = db.collection("videos")
            app.get("/video", (req, res) => {
                const videoId = new mongodb.ObjectId(req.query.id);
                videosCollection.findOne({_id: videoId})
                    .then(videoRecord => {
                        if(!videoRecord) {
                            res.sendStatus(404);
                            return;
                        }

                        const forwardRequest = http.request({
                            host:VIDEO_STORAGE_HOST,
                            port: VIDEO_STORAGE_PORT,
                            path: `/video?path=${videoRecord.videoPath}`,
                            method: 'GET',
                            headers: req.headers
                        },
                        forwardResponse => {
                            res.writerHeader(forwardResponse.statusCode,forwardResponse.headers)
                            forwardResponse.pipe(res)
                        });
                        req.pipe(forwardRequest)
                    })
                    .catch(err => {
                        console.error("Database query failed");
                        console.error(err && err.stack || err);
                        res.sendStatus(500);
                    })
            });
            app.listen(PORT, () => {
                console.log(`Microservice online`)
            })
        })
}

main()
    .then(() => console.log("Microservice online"))
    .catch(err => {
        console.error("Microservice failed to start")
        console.error(err && err.stack || err);
    });

MongoDB 레코드 넣기

{
    "_id" : { "$oid": "5d9e690ad76fe06a3d7ae416" },
    "videoPath" : "SampleVideo_1280x720_1mb.mp4"
}

docker compose build

docker-compose up --build
728x90

'아키텍처 패턴 > 마이크로 서비스' 카테고리의 다른 글

2. 마이크로 서비스 준비  (0) 2023.08.15
1. 마이크로 서비스 란?  (0) 2023.07.30