はじめに
https://qiita.com/YukiMiyatake/items/9cef90e2a18573e7bca3
ここで 年末休みにnodeを勉強した内容をまとめたが
その中身を細かく切り出す
目的
いま新人教育をしているが、その新人教育をオープンにする
私自身 出し惜しみはしない。むしろ もし私の知識で少しでも世の中が便利になるのならラッキーだ
また 間違った事は 公開すれば教えてくれるはず
検討
まずは新人教育のための題材を作ることからはじめた
制作物
スマホのソーシャルゲーム用のAPIサーバ
自分がゲームエンタメ業界が多いので、ソーシャルゲームのサーバは持っていて損はない
以前 JavaPlayframeworkで作っていたが そろそろ作り直したいと思っていた
言語
ソーシャルゲームのAPIサーバはほとんどがDBからReadしたりそのままWriteしたりCPU処理は少ない
マイクロサービス化も検討しているため、重い処理があればその部分は別の言語で動かすことも出来る
そのため 言語自体の速度はそこまで気にするシーンは無いはずである
最も重要なのは、クライアントからのコネクション時の起動やI/Oである
Perl、PHP、Python、Rubyなど
これらのスクリプト言語は基本的に非同期処理を行なう事が難しい
(非同期ライブラリもあるが 一般的ではないしパフォーマンスも出ない)
そのため、コネクションごとにプロセスを起動する事になるが 上記の理由で
プロセス起動コスト、タスク上限問題(C10K問題)のため、私の中では選択肢に入らない
却下
Haskell、Erlang、Elixir・・・
マイナー言語というと怒られるかもしれないがマイナー言語である
非同期処理は得意であるが、お客さんに納品しにくいので却下した
個人的には 嫌いじゃない言語だけどね
C#、Kotlin、Swift
C#は クロスプラットフォームになってきてるけど、まだベンダーロックインに分類した
ベンダーロックイン言語は使いたくない
C#はIL2CPPとか使えると面白くなるんだけどね
C#は言語的に優れてると思うんだけどね・・
今回とは別で C#サーバは勉強したいが 今回は却下
Scala
コンパイルの遅さが嫌い それ以外はとってもいい
いずれScalaサーバは勉強しますが今回は却下で
C++、Java、Go、node
非同期が得意でメジャー言語、特に欠点のない言語で この選択肢になった
C++は新人にはまだ難しく 言語の習得に時間がかかるので今回は却下した
Goは以前プロダクトに使ったが、文法が20年ほど古く これ以上使う気がおこらない
Javaは速度も速く、システム系では最も使われていて 仕事的に何も不自由ないので教えたいと思った
が、nodeを選んだ。
この2択は かなりどちらでも問題なかったが あえていうなら、AWS LambdaのようなFaaSサービスに使いやすいからだ
もちろんnodeには弱点がある
Javaに比べると遅いし、同時接続も非同期にしては弱い。
だが フロントエンドでもJavaScriptは使うので この際覚えてもらうには良いかと。
FW
nodeに決めたからにはフレームワークは node、Express、MongoDB に決めた
また APIキャッシュとしてRedisを使い、課金など重要なDBは MySQLの併用を検討している
Typescriptを必須にした。
このあたりは nodeではよくある構成と思う
実行環境
Docker(DockerCompose)を前提で作る
AWSを考えているが他のサービスでも可能
マイクロサービス化も当然考えている
開発はWindowsでもMacでもDocker使えば問題ない
ソース管理、タスク管理、スケジュール管理
ソース管理はGithubかGitlabか悩んだが 機能が多く全部つかいこなしてないGitlabの採用を決めた
理由は特にないが、機能豊富でサイトも軽いので不自由がないからだ
タスク管理も GitlabのIssueで管理することにした。かんばんがデフォルトでついてるのは良い
スケジュールは 建てないことにした。それよりは確実に勉強すること
DevOps
とりあえずSlackBotを導入して コミットやマージリクエスト、Issueを通知させることにした
設計
設計もGitlabのWikiで行った
DB,API
DBは基本的には user_idをキーとした1テーブルでほとんどカバー出来るが
フィールドが多いと R/Wが遅くなる、マイクロサービス化したときに同じテーブルだとコンフリクトする
ため、機能ごとにテーブルをわけた
細かいフィールドはゲームの内容で変わるのであとで考えるとして
Account、ダウンロードデータ、ステータス、カード、デッキ、アーチーブメント、ログボ、フレンド、ブロック、課金・・・
と詳細に分割した
また APIも使うDBに紐づけた
環境構築
Docker
AlpainLinuxをベースに、node、Mongo、Redis、MySQLのイメージを使う
dockerfile、docker-composeを設定して 難なく動かす
これで環境構築が終わる 素晴らしい世の中だ
version: '3'
services:
node:
build:
context: ./server/docker/construct_node # Dockerfile保存場所
image: sss-node # イメージ名
container_name: sss-node # コンテナ名
tty: true
ports: # ローカルとホストのポートを接続
- 3000:3000
volumes: # 現在のディレクトリをworkdir(/src)にマウント
- ./:/src
mysql:
build:
context: ./server/docker/construct_mysql # Dockerfile保存場所
image: sss-mysql # イメージ名
container_name: sss-mysql # コンテナ名
ports: # ローカルとホストのポートを接続
- 33060:3306
volumes: # databaseをホストと共有
- ./server/docker/construct_mysql/data:/var/lib/mysql
environment:
- "MYSQL_ROOT_PASSWORD=root" # ルートのパスワードは必須
mongo:
build:
context: ./server/docker/construct_mongo # Dockerfile保存場所
image: sss-mongo # イメージ名
container_name: sss-mongo # コンテナ名
ports: # ローカルとホストのポートを接続
- 27018:27017
volumes: # databaseをホストと共有
- ./server/docker/construct_mongo/data:/data/db
redis:
build:
context: ./server/docker/construct_redis # Dockerfile保存場所
image: sss-redis # イメージ名
container_name: sss-redis # コンテナ名
command: redis-server --appendonly yes # データをファイルに保存する形式に指定
ports: # ローカルとホストのポートを接続
- 16379:6379
volumes: # databaseをホストと共有
- ./server/docker/construct_redis/data:/data
さすが新人コメント多い
モジュール
npmでは色々インストールした
express、mongooseなど
Typescript
最初はWebpackを導入したが やはり消耗した・・
が最終的には package.jsonだけでなんとかなった!
concurrentlyを導入したが
"main": "src/app.ts",
"scripts": {
"start": "npm run serve",
"build": "npm run build-ts",
"serve": "node dist/app.js",
"watch-node": "nodemon dist/app.js",
"watch": "concurrently -k -p \"[{name}]\" -n \"TypeScript,Node\" -c \"yellow.bold,cyan.bold,green.bold\" \"npm run watch-ts\" \"npm run watch-node\"",
"test": "jest --forceExit --coverage --verbose",
"watch-test": "npm run test -- --watchAll",
"build-ts": "tsc",
"watch-ts": "tsc -w",
"tslint": "tslint -c tslint.json -p tsconfig.json",
"copy-static-assets": "ts-node copyStaticAssets.ts",
"debug": "npm run build && npm run watch-debug",
"serve-debug": "nodemon --inspect dist/server.js",
"watch-debug": "concurrently -k -p \"[{name}]\" -n \"Sass,TypeScript,Node\" -c \"yellow.bold,cyan.bold,green.bold\" \"npm run watch-sass\" \"npm run watch-ts\" \"npm run serve-debug\""
},
nodemonでファイルの変更を監視しJSファイルが変更されたらnode再起動
これで快適だ
HelloWorld
まずはJavaScriptでテストをしていく
var express = require('express');
var app = express();
app.get('/', function(req, res, next) {
res.send("Welcom to SSS");
});
app.listen(3000);
docker-composeでちゃんと動いたので
開発が可能になった