Seize the day

POST : Backend study

Deno api server by Nginx (Study log)

Test Api server를 우선 만들어보았다. 

"deno Restful api "로 검색했을때 가장 많이 사용된 라이브러리인 oak를 이용하기로 했다.  간단히 8080 port에 http 서버를 띄우고, 어떤 요청이 오더라도  아래 json 문자열을 응답한다. 

{"code":1,"message":"Service is maintenance mode."}

 

maintenance.ts

import { Application } from "https://deno.land/x/oak/mod.ts"

const app = new Application()

// 8080 port is maintenance service 
const port = 8080

// response body
const body =  {
  code: 1,
  message: "Service is maintenance mode."
}

app.use((context) => {
  context.response.body = body;
})

console.log("start server with maintenance mode, port=" +  port)
await app.listen({ port: port})

 

서버 실행

$ deno run --allow-net maintenance.ts &                                                                                                                                                 ✔  102  16:51:02
[1] 92626
start server with maintenance mode, port=8080

브라우저를 띄우고  http://localhost:8080 을 입력해서 동작을 확인한다. 

 

Application server를 만들어 보자.

지난번에 만들었던 test.ts에 웹 서버기능을 추가했다. 

server.ts

import { Application, Router, Context } from "https://deno.land/x/oak/mod.ts"
import { Bson, MongoClient } from "https://deno.land/x/mongo/mod.ts";

// Init mongo db
const client = new MongoClient();

//Connecting to a Local Database
await client.connect("mongodb://localhost:27017");

// Define collection
interface TSList {
    _id: { $oid: string };
    id: number
    name: string;
  }


const db = client.database("testdb");
const tslist = db.collection<TSList>("tslist");


// Http Handler
const getTSList = async ({ response }: { response: any }) => {
    const result = await tslist.find().toArray()
    response.body = {
        code: 0,
        result: result
    }
}

const errorHandler = async (ctx: Context, next: any) => {
    try {
      await next();
    } catch (err) {
      ctx.response.status = 500;
      ctx.response.body = { code: 500, message: err.message }
    }
  }

  const _404 = async (ctx: Context) => {
    ctx.response.status = 404;
    ctx.response.body = { code: 404, message: "404 Not Found!" }
  }

 // Init router
const router = new Router()
router.get("/tslist", getTSList)

// Init server
const app = new Application()
const port = 8000
app.use(errorHandler);
app.use(router.routes())
app.use(router.allowedMethods())
app.use(_404)

console.log("start server port=" + port);
await app.listen({ port: port });

 

서버 실행 

$ deno run --allow-net --unstable server.ts
Check file:///Users/user/djkim/test/server.ts
start server port=8000

 

웹 브라우저에 http://localhost:8000/tslist 를 입력하면 아래와 같이 응답한다.

{"code":0,"result":[{"_id":"6103b0bfcddd2d8fe3850ee6","id":1,"name":"user"}]}

 

Mac에 Nginx 설치하기

Nginx는 api 게이트웨이 서버이고, 여러 static 파일이나 zip 파일을 호스팅하는 용도이다.
간단히 설치하기

brew install nginx

 

서비스 Port 80으로 변경하기

vi /usr/local/etc/nginx/nginx.conf

 

서비스 시작하기

brew services start nginx

서버 동작 확인하기  http://localhost

webroot 확인

$ nginx -V
nginx version: nginx/1.21.1
built by clang 12.0.0 (clang-1200.0.32.29)
built with OpenSSL 1.1.1k  25 Mar 2021
TLS SNI support enabled
configure arguments: --prefix=/usr/local/Cellar/nginx/1.21.1

 

Deno 서버 여러개 띄우고 로드밸런싱해보기

더보기

upstream deno_server {

        server localhost:8000 weight=2;
        server localhost:8080 weight=1;
    }

    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            #root   html;
            #index  index.html index.htm;
            proxy_pass http://deno_server;
        }

http://nginx.org/en/docs/http/load_balancing.html 참고

서버 reload (restart와 다른가?)
$ brew services reload  nginx

브라우저에서 http://localhost/tslist 라고 입력하면 
1/3의 요청은 포트 8080으로 가고 , 나머지는 8000으로 간다.  서버가 버전업이 되었을 때 weight를 조정하여 5%의 사용자는 새로운 서버로 동작시켜서 문제가 없는지 확인한 후에 점진적으로 서버 배포가 가능하도록 할 수 있다. 

proxy_pass http://locahost:8080;
으로 변경한다면, 서버가 패치하는 동안 모든 요청을 유지 보수 모드로 서버 상태를 변경할 수 있다. 

아니면 nginx를 이용해서 처리도 가능하다.

# 유지보수일때 json을 그냥 리턴시킨다.
location / {
            #root   html;
            #index  index.html index.htm;
            #proxy_pass http://localhost.com:8000;
            return 200 "{\"code\":1, \"message\":\"service is on maintenance mode\"}";
            add_header Content-Type text/plain;
        }

 

location / {   이 부분을 적절히 변겨하면 포트마다 여러 서비스 서버를 띄우고 각각 다른 서버 인스턴스로 프락시 할 수 있다. 
localhost/blog
localhost/wiki
localhost/api

 

Nginx에 https 적용하기 #1

[Nginx] Nginx HTTPS 및 Let's Encryt SSL 인증서 적용⋆ JackerLab 를 참고했다. 
설치

$ brew install certbot

 

내 mac에 도메인 할당하기.  인증서에는 .(dot)이 최소 하나가 들어있는 도메인이 필요하다. 따라서 localhost.com 을 127.0.0.1로 지정한다. 

$ sudo vi /etc/hosts

127.0.0.1       localhost.com
을 추가한다.   추가하고나면  http://localhost.com/tslist 로 접속이 잘 된다. 

인증서 발급: 도메인은  임시로 localhost 로 지정한다. 하기 전에 nginx를 먼저 중지해야 한다. 

$ brew services stop  nginx
$ sudo certbot certonly --manual

몇 가지 확인을 해 본 결과 인증서 발급 서버에서 localhost.com으로 접속을 시도해서 정상적인 서버인지 확인하는 과정이 있는데 localhost.com은 정상적인 dns 서버에 등록된 도메인이 아니기 때문에 결국 연결 실패하게 된다.

[centos7] HTTPS 무료 인증설치방법(--manual 옵션 사용) (tistory.com) 참고 

 

Nginx에 https 적용하기 (OpenSSL) #2

파란크리스마스 :: Apache 2.4 : OpenSSL 테스트인증서 생성, https 설정 (tistory.com) 여기를 참고했다.

 server {
        listen       443 ssl;
        server_name  localhost.com;

        ssl_certificate      /var/www/letsencrypt/private.crt;
        ssl_certificate_key  /var/www/letsencrypt/private.key;

        ssl_protocols TLSv1.2;
        #ssl_session_cache    shared:SSL:1m;
        #ssl_session_timeout  5m;

        #ssl_ciphers  HIGH:!aNULL:!MD5;
        #ssl_prefer_server_ciphers  on;

        location / {
            #root   html;
            #index  index.html index.htm;
            proxy_pass http://deno_server;
        }
    }

이렇게 설정했고(letsencrypt는 이전 테스트에서 사용하던 디렉토리를 그대로 이용한 것), 브라우저에서 안전하지 않은 인증서라고 하면서 연결을 거부한다. 크롬에서 이제는 test 인증서는 연결을 거부하는 것 같다. 예전에는 됬을 수도 있다.  결국 공인 IP를 가진 서버가 필요하고 도메인 연결도 필요하다. 그런경우 certbot을 이용해서 가능할 듯 하다.

top

posted at

2021. 7. 31. 17:11


CONTENTS

Seize the day
BLOG main image
김대정의 앱 개발 노트와 사는 이야기
RSS 2.0Tattertools
공지
아카이브
최근 글 최근 댓글
카테고리 태그 구름사이트 링크