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을 이용해서 가능할 듯 하다.