まだプログラマーですが何か?

プログラマーネタとアスリートネタ中心。たまに作成したウェブサービス関連の話も http://twitter.com/dotnsf

タグ:strongloop

Node.js サーバーのリバースプロキシとして、高性能な Nginx を利用する方法を紹介します。以下では CentOS 環境を前提とした方法を紹介します。

まずは Node.js + アプリケーションの環境を構築します。特に今回は Node.js 上で StrongLoop LoopBack アプリケーションを動かすという前提としてます(独自のアプリケーションでも構いません)。この環境を整えるための手順はこちらを参照ください:
CentOS に StrongLoop をインストールする

アプリケーションが準備できたら Node.js を起動しておきます。実際には forever を使って Node.js をデーモン化しておくと便利だと思います。この辺りの手順はこちらを参照ください:
Forever で Node.js をデーモン化する

(↓ 3000 番ポートで Node.js アプリが動いている様子)
2016061601



この環境にリバースプロキシとして利用する Nginx を導入します。Nginx の導入手順はここの内容を参考にしています:
CentOS に Nginx をインストールして PHP を使う
# rpm -ivh http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm
# yum install nginx

Nginx の設定ファイル(/etc/nginx/conf.d/default.conf)を以下のように編集します(青字が追加部分、赤字がコメントです):
# backend_node に LoopBack サーバー(localhost:3000)を追加
upstream backend_node { ip_hash; server 127.0.0.1:3000; } server { listen 80; server_name localhost; #charset koi8-r; #access_log /var/log/nginx/log/host.access.log main; location / { root /usr/share/nginx/html; index index.html index.htm;

# 存在するファイルパスが指定された場合はそのまま Nginx で処理 if ( -f $request_filename ) { break; }
# 存在しないファイルパスが指定された場合は backend_node で処理 if ( !-f $request_filename ) { proxy_pass http://backend_node; break; } } : :

これで準備完了です。この状態で Nginx を起動します:
# /etc/init.d/nginx start

改めて同サーバーにウェブブラウザでアクセスします。まずドキュメントルートにアクセスすると、これは Nginx が処理できるパスなので、Nginx のウェルカムページが表示されます:
2016061603


次に /explorer というパスを指定してアクセスしてみます。すると、このファイルやディレクトリは存在しないので Nginx は処理せず、backend_node で指定した 3000 番ポートのサーバー(つまり Node.js)に内部転送して、その結果が表示されます:
2016061602


これで 3000 番ポートを指定しなくても(Node.js 上で動いている)LoopBack サーバーにアクセスできるようになっただけでなく、HTML や画像、CSS、JavaScript といった静的ファイルは Node.js ではなく(高速な)Nginx に任せる、ということもできるようになります。


 

モデル定義だけで OpenAPI 対応の REST API を生成してくれる StrongLoop LoopBackIBM DB2 に対応していたので使ってみました。

基本的な考え方や手順は以前にこちらで紹介した MySQL 対応での手順と同様ですが、以下ではデータソースをDB2 とした場合の手順を紹介します:
StrongLoop アプリで MySQL を使う


まずは DB2 サーバーを用意します。自前で用意できる場合はその環境を使っていただいても構いませんが、IBM Bluemix ユーザーであれば SQL Database 等、DB2 サーバーのインスタンスを使っていただいても構いません。

では次のような DB2 サーバー環境が用意できているものとします:
ホスト名XX.XX.XX.XX
ポート番号50000
データベース名SQLDB
ユーザー名db2_username
パスワードdb2_password


この DB2 インスタンスに REST API で読み書きするモデルのテーブルを作成します。上記の MySQL での例と同様の item テーブルを用意します。ここで1点注意があります。DB2 の CREATE TABLE 文は普通に実行するとテーブル名や列名を全て大文字で作成します。普通に利用する際には大文字小文字を区別することなく利用できるのですが、LoopBack 環境では全て小文字で定義されている前提で API が発行されます。つまりデフォルトの大文字のままでテーブルを定義すると後で「テーブルが見つからない」といったエラーが発生してしまいます。それを避ける目的で create table 内のテーブル名や列名の部分は全てダブルクォーテーションで括り、明示的に小文字で作成する必要があります。この点に注意して作成してください:
> create table "item"("id" int primary key generated always as identity (start with 1 increment by 1),"name" varchar(50) not null,"code" varchar(50) not null,"price" int);

これで DB2 側の準備はできました。ではこの item テーブルのデータを読み書きする API を LoopBack で用意しましょう。以下 CentOS 環境を前提に紹介します。

まず、StrongLoop や LoopBack は npm を通じて提供され、Node.js 上で動きます。というわけで Node.js と npm を導入する必要があります:
# yum install epel-release
# yum install nodejs npm --enablerepo=epel

次に npm を使って LoopBack と StrongLoop を導入します:
# npm install -g loopback
# npm install -g strongloop

StrongLoop / LoopBack が導入できたら、これらを使って API を作成します。まずは作業用のディレクトリ(下の例では ~/tmp)を作って、そこに移動しておきます:
# cd
# mkdir tmp
# cd tmp

このディレクトリに LoopBack のアプリケーション環境を作成します。ここではアプリケーション名を db2app と指定しています:
# slc loopback db2app

アプリケーション名と、アプリケーションディレクトリを聞かれますが、いずれもデフォルトの db2app をそのまま指定します。またアプリケーションの種類を聞かれますが、これもデフォルトのまま api-server を選択します:
2016031401


すると db2app アプリケーションの基本部分のインストールが開始され、しばらく待つとこのような画面になり、導入が完了します(この時点で db2app ディレクトリが作られているはずです):
2016031402


上図の最後の部分にこの後の手順が記載されています。が、LoopBack の標準 DB ではなく、他の外部 DB を利用する場合の手順は少し異なります。まずはアプリケーションディレクトリに移動しておきます:
# cd db2app

次にこのプロジェクトのデータソースが DB2 になるようカスタマイズします。まずは DB2 コネクタをインストールします。このコマンドで DB2 ODBC CLI ドライバなどもダウンロード&インストールされます:
# npm install --save loopback-connector-db2

DB2 コネクタがインストールできたら、このコネクタを使ってデータソースを定義します。カスタムデータソースの名称は "mydb" としています:
# slc loopback:datasource mydb

そしてデータソース名はデフォルトのまま mydb を選択します。次のコネクターの選択肢において "IBM DB2" を選択します(ここが今回、新たに DB2 対応した機能です):
2016031403


続けて DB2 サーバーへの接続情報を指定します。上記表の内容通りにホスト名、ポート番号、ユーザー名、パスワード、そしてデータベース名を入力します:
2016031404


ちなみにここでの作業の内容は server/datasource.json ファイルに記載されます。直接編集する場合は同ファイルをテキストエディタで編集してください。


データソースの定義ができたら最後に item モデルを生成します:
# slc loopback:model item

モデル名はデフォルトのまま item を指定します。次にデータソースを聞かれるので上記で作成した mydb を指定します(これでデータソースは DB2 になります)。以下はこれまでと同様でベースクラスには PersistedModel、REST API 公開は Yes、カスタム plural form はなし(そのままリターン)、そして common モデルを指定します:
2016031405


そして各列の定義では上記表のように name 列は string 型で必須(Yes)、code 列も string 型で必須(Yes)、price 列は number 型で必須ではない(No)をそれぞれ指定します:
2016031406


最後に Property name を聞かれた所でそのまま Enter を入力して、列のカスタマイズを完了します。これでモデルの定義も完了しました。


モデルが出来たので、LoopBack で API が稼働し公開されるはずです。実際の動作を確かめてみましょう:
# node .

すると画面には API Explorer にアクセスするための URL (最後が /explorer になっている方)が表示されます:
2016031407


ウェブブラウザでこのページにアクセスすると、db2app アプリケーションと、その中に item モデルを読み書きする一連の API が生成されていることが確認できます:
2016031408


後はここで紹介したような方法で実際の API を実行して、この画面から動作確認することが可能です:
2016031409


ここでデータレコードを作成した場合、当然 DB2 サーバー内に格納されます。DB2 側のデータを参照して同じデータが保存されていることを確認できます:
2016031410


これまで LoopBack は Oracle や SQL Server には対応していましたが、ようやく "StrongLoop An IBM Company" っぽい連携ができるようになりました(笑)。
2016031411


StrongLoop の API プラットフォームにおける利用状況や接続先データソースをグラフィカルな UI で管理するツールが StrongLoop Arc です:
https://strongloop.com/node-js/arc/


StrongLoop (や LoopBack )の slc コマンドを導入済みの環境であればすぐに使うことができます。試しに LoopBack で API を作った時の環境を使って、StrongLoop Arc を利用してみます。LoopBack を導入する手順についてはこちらを参照ください:
CentOS に StrongLoop をインストールする


上記手順を行い、"myapp2" という名前で LoopBack アプリケーションが作られていると仮定します。この環境を使って、StrongLoop Arc を利用するには、アプリケーションフォルダに移動して、"slc arc" コマンドを実行します:
# cd myapp2
# slc arc

するとこんな感じで StrongLoop Arc が起動します。以下の例では 41241 番ポートで起動していますが、このポート番号は動的に変わるようです:

2016021810


ではこの環境にウェブブラウザでアクセスしてみましょう。なお、StrongLoop Arc はリモートアクセスを許可していないので、この StrongLoop 環境を導入したマシンそのものにログインしてからウェブブラウザで http://localhost:XXXXX/ にアクセスする必要があります:
2016021801


StrongLoop Arc を使うにはアカウントが必要です。まだお持ちでない場合は画面右上のハンバーガーメニューから "register" を選んで登録を行います:
2016021802


登録するユーザーのメールアドレスを指定して "Submit":
2016021803


指定アドレスに StrongLoop からメールが届いたら、メール内のリンクをクリック:
2016021804


で、ユーザー名やパスワードやら、残りの項目を登録します:
2016021805


最後に同意チェックを入れて Submit !これでアカウント登録完了です:
2016021806


改めてこの画面から登録ユーザー名(またはメールアドレス)とパスワードを指定してログインします:
2016021807


ログイン直後の画面がこちらです。コマンドラインの slc コマンドで行っていたような作業を GUI で行えるようになります:
2016021808


試しにデータソースを管理してみましょう。"Composer" をクリックすると、現在(LoopBack を使った時に登録した)データソースが確認でき、またここから新規にデータソースを定義することもできるようです:
2016021809


プロセスマネージャーを登録してトレーシング・・・ などもやってみたかったのですが、何故か上手く行かなかったのでそちらについてはまた別途、かな。


(2016/Dec/02 追記 このエントリ内で紹介しているページが消えてしまったため、具体的なサーバーを確認することができなくなってしまいました)


このブログでもたびたび紹介している Loopback などを提供している StrongLoop 社の技術者向けブログを見
ていて気付いたことがあります。

気付いたのはこのブログエントリ、LoopBack から MySQL データベースに接続するための手順を紹介しているガイドです:
Getting Started with the MySQL Connector for LoopBack

(2016/Dec/02 追記 ↑このリンク先ページが消えてしまいました)



ページの中ごろに差し掛かったあたりで・・・ ん!?
2016021801
 (↑実際にはモザイク無し)


LoopBack の MySQL コネクターを使ったデータソースを記述する手順を紹介している箇所で、StrongLoop がデモ用に公開している MySQL サーバーの接続情報が載っているではありませんか!?

まあデモ用なので、このユーザーでできる権限は問い合わせ(つまり SELECT)程度です。とはいえ、そんな MySQL が公開されているとな!

早速 Bluemix 上に phpMyAdmin 環境を構築してみました(笑)。その手順についてはこちらを参照ください:
Bluemix で phpMyAdmin を動かす


1つ注意点として、StrongLoop のデモ用 MySQL はバージョンが低いらしく(僕が確認した限りでは 5.1.73)、最新 phpMyAdmin の推奨環境に合わないためか、そのままだと「バージョンアップしろ」という内容のエラーが表示されました:
2016021800


このエラーを(無理やり)回避するには、phpMyAdmin 側のエラーチェック部分を変更する必要があります。phpMyAdmin の libraries/common.inc.php ファイルの下記該当部分を全てコメントアウトして保存します:
   :
:

# if (PMA_MYSQL_INT_VERSION < $cfg['MysqlMinVersion']['internal']) { # PMA_fatalError( # __('You should upgrade to %s %s or later.'), # array('MySQL', $cfg['MysqlMinVersion']['human']) # ); # }

:

その上で phpMyAdmin 一式を(Bluemix 環境に)デプロイして phpMyAdmin にアクセスし、上記ブログ内で公開されている ID とパスワードでログインすると、デモデータベースの中身にアクセスできました:
2016021802


定義や内容を変更することはできないのですが、動作確認用のサンプルデータベースとして MySQL データベースサーバーが必要な場合に重宝しそうです。


(参考)
http://stackoverflow.com/questions/26222244/phpmyadmin-error-you-should-upgrade-to-mysql-5-5-0-or-later


IBM Bluemix だけの環境を使って、Web API を作り、公開して、更に API Management 機能を使って管理/監視する、というシステムを作ってみます。

これまでこのブログでも個別の機能を個別に紹介したりしていましたが、全てまとめたシステムを Bluemix 提供サービスだけを使って(外部サービスに頼らずに)行う、という前提条件で紹介します。もちろん実際には外部との連携も可能です、データベースは既存のものを使う、とかも可能、という意味です。


システム概要としての完成図は下図のような感じを想定します。まず格納するデータのデータベース(MySQL)と、その管理ツールとして phpMyAdmin(PHP ランタイム)を用意します。次にデータベース内のモデルを API として公開する LoopBack(Node.js ランタイム)。ここまでで CRUD の REST API ができますが、このサーバーは直接公開しません。加えてこの API を管理するため、API Management サービスでラッピングし、カスタム API を作って、これを利用者向けに公開します。それぞれ Bluemix 上のサービスアイコンと併せてのシステム図になっています:
2016020701


ではそれぞれのパーツを順に Bluemix 上に作っていきます。全部で3段階あります:

(1) MySQL と phpMyAdmin でデータベース環境を準備
2016020801

Bluemix 環境内に MySQL のデータベースサーバーを用意し、この中に API として管理するデータのモデル(テーブル)を作成します。MySQL の選択肢として ClearDB を使うこともできる(その場合は外部の MySQL コマンドラインクライアントから直接参照できる)のですが、今回はオープンソース版を使うことにします。オープンソース版では外部の MySQL コマンドラインクライアントからは参照できないので、テーブル定義のために PHP ランタイムと、そこで実行する phpMyAdmin の環境を構築します。そして phpMyAdmin から create table の SQL を実行して、モデルを作成します。

この Bluemix 環境内に MySQL データベースサーバーと phpMyAdmin アプリケーション環境を構築する際の手順についてはこちらで詳しく紹介しているので参照ください:
Bluemix で phpMyAdmin を動かす


(2) StrongLoop LoopBack で REST API 化

2016020802

StrongLoop LoopBack インスタンスを作り、先程作成した MySQL データベースをバインドして、モデルを CRUD 可能な REST API 化します。

StrongLoop 環境の構築方法や Bluemix ランタイムへのプッシュ方法、そしてデータベースとして MySQL を指定する場合の手順などは以下を参照ください:


ただし、この REST API はこのまま公開はしません。あくまでプライベートな REST API として作成し、公開する時は参照系 API のみ(GET リクエストの API のみ)を公開するようにします。


(3) API Management で公開する API を絞り、カスタム API 化して管理
2016020701

LoopBack で作成した REST API の参照系 API のみをプロキシー URL とするようなカスタム API を API Management サービスを使って作成し、このカスタム API を Bluemix ユーザー向けに公開します。

API Management サービスでカスタム API を作って公開する手順はこちらを参照ください。(2) で作成した LoopBack の REST API を、ここで公開するカスタム API のプロキシーとして利用するための手順です:
IBM Bluemix の API Management サービス



と、こんな感じ。特別に目新しい情報ではないのですが、Bluemix のランタイムやサービスを組み合わせるだけで負荷に合わせてオートスケールする API を生成し、かつその API の制御管理を行う、という仕組みが構築できました。





 

このページのトップヘ