Mac OSのGoをNGINX Unitで動かしてみる

NGINX Unit

NGINX UnitがアプリケーションサーバとしてOSSで登場しました。

www.nginx.com

9/8(金)の夜に Mac OSGo で試した作業ログと気付いた点などをまとめておきます。ぱっと調べたところ Mac OS で実際に動かした人の情報は無さそうですね。

ドキュメントは GitHub - nginx/unit: An official read-only mirror of http://hg.nginx.org/unit/ を参考にしてください。

Go から unit パッケージを利用するには、現状だとまだ go get で落としてくることは出来ないのでソースコードを落としてきてビルドする必要があります。 ちなみに余談ですが unit ではなく nginxunit など別のパッケージ名にした方が良かったのになぁと個人的には思いました。 それでは、実際に Go でアプリケーションを動作させるまでの手順を最低限記載しておきますので興味のある人は、本ブログのままコピペで動かすところまでやってみてください。

2017/09/09の時点では、 Mac OS 上で Go のアプリケーションを動作させることは出来ませんでした。但し Mac OS で行った同じ手順を ubuntu で行ったところ正常に動作したことを確認出来ました。以下の手順は Mac OSubuntu 共通です。特に問題なければビルドから実行まで10分あれば試せますので是非いろいろ触ってみては如何でしょうか。

install

インストールは、以下の通り。

$ git clone https://github.com/nginx/unit
$ cd unit
$ ./configure
$ ./configure go
$ make all
$ make go-install
$ make install

これで $GOPATH 配下に unit がインストールされ Gounit を利用する準備が整いました。

起動

Mac OS で起動するには make したカレンドディレクトリの sbin 配下の unitd を実行します。バージョンを確認してから起動しました。 ubuntu の場合も sbin 配下の unitd 起動でも確認とれましたし、 sudo service unitd start からでも起動から Go アプリの実行まで確認出来ています。

$ ./sbin/unitd --version
unit version: 0.1
configured as ./configure
$./sbin/unitd

起動するとdefaultでカレントディレクトリに control.unit.sock ファイルが生成されます。参照 https://github.com/nginx/unit#configuration

起動オプション

$ ./sbin/unitd --help

unit options:

  --version            print unit version and configure options

  --no-daemon          run unit in non-daemon mode

  --control ADDRESS    set address of control API socket
                       default: "unix:control.unit.sock"

  --pid FILE           set pid filename
                       default: "unit.pid"

  --log FILE           set log filename
                       default: "unit.log"

  --modules DIRECTORY  set modules directory name
                       default: "build"

  --user USER          set non-privileged processes to run as specified user
                       default: "nobody"

  --group GROUP        set non-privileged processes to run as specified group
                       default: user's primary group

登録確認

まず listenerapplication の確認を行います。まだ未登録だということがわかります。

$ curl --unix-socket /Users/yone098/nginx-unit-work/unit/control.unit.sock http://127.0.0.1
{
    "listeners": {},
    "applications": {}
}

Goアプリケーション作成

Go で簡単なアプリケーションを作成します。 http.ListenAndServeunit.ListenAndServe に変更するだけです。 公式ドキュメントの import{ } になっているのでそのままコピペすると動かないので ( ) に書き換えてください。

package main

import (
    "io"
    "net/http"
    "unit"
)

func HelloServer(w http.ResponseWriter, req *http.Request) {
    io.WriteString(w, "hello, unit!\n")
}

func main() {
    http.HandleFunc("/", HelloServer)
    // 以下を unit に変更する
    //http.ListenAndServe(":8000", nil)
    unit.ListenAndServe(":8000", nil)
}

go build してバイナリを作成します。 設定ファイルにて作成したバイナリを executable として指定します。

設定ファイル

{
  "listeners": {
    "*:8070": {
      "application": "golang"
    }
  },
  "applications": {
    "golang": {
      "type": "go",
      "workers": 1,
      "executable": "/Users/yone098/nginx-unit-work/gounit",
    }
  }
}

登録

$ curl -X PUT -d @/Users/yone098/nginx-unit-work/gounit.json --unix-socket /Users/yone098/nginx-unit-work/unit/control.unit.sock http://127.0.0.1/
{
    "success": "Reconfiguration done."
}

確認

$ curl --unix-socket /Users/yone098/nginx-unit-work/unit/control.unit.sock http://127.0.0.1/
{
    "listeners": {
        "*:8080": {
            "application": "golang"
        }
    },

    "applications": {
        "golang": {
            "type": "go",
            "workers": 1,
            "executable": "/home/ubuntu/gounit"
        }
    }
}

登録したあとに変更する場合は listener を一旦削除してから登録します。 以下のように削除したあとに確認すると listener が削除されていることが確認出来ます。

削除

$ curl -X DELETE --unix-socket /Users/yone098/nginx-unit-work/unit/control.unit.sock 'http://127.0.0.1/listeners/*:8080'
{
    "success": "Reconfiguration done."
}
$ curl --unix-socket /Users/yone098/nginx-unit-work/unit/control.unit.sock http://127.0.0.1/
{
    "listeners": {},
    "applications": {
        "golang": {
            "type": go",
          "workers": 1,
          "executable": "/tmp/gounit"
      }
  }
}

Mac OS でのエラー

Mac OSで確認

$ curl http://127.0.0.1:8080/
Read header timeout

エラーログ

2017/09/09 23:52:21 [info] 28656#1194422 "golang" application started
2017/09/09 23:52:21 [crit] 28329#1175827 process 28656 exited on signal 9
2017/09/09 23:52:26 [alert] 28335#1176038 *17 error 408: Read header timeout

ubuntu で実行

$ curl http://127.0.0.1:8080/
hello, unit!

Mac OS 上の Go で実行しようとした際に “Read header timeout” になる件は、 nxt_router.c3185 行あたり

static void
nxt_router_conn_timeout(nxt_task_t *task, void *obj, void *data)
{
    nxt_conn_t   *c;
    nxt_timer_t  *timer;

    timer = obj;

    nxt_debug(task, "router conn timeout");

    c = nxt_read_timer_conn(timer);

    if (c->read_state == &nxt_router_conn_read_header_state) {
        nxt_router_gen_error(task, c, 408, "Read header timeout");

    } else {
        nxt_router_gen_error(task, c, 408, "Read body timeout");
    }
}

ubuntu 上だと全く同じ手順(ビルド後の ./sbin/unitd 経由で起動した場合)で正常に Go のアプリケーションが稼働しているところをみると Mac OS 固有の問題なんだろうなと思う。しばらくしたら Mac OS でも正常に動作するようになるかなと期待します。

まとめ

まだ出たばかりなので、これからに期待といったところでしょうか。 ubuntu でアプリ書き換え後にホットリロードされるかと思ったのですが unitd の再起動後、再度設定し直す必要があり、このへんもこれからといったところだと思いました。 今後は、 https://github.com/nginx/unit#key-features Key Features を見るとこれから機能追加といったところでしょうか。

- Fully dynamic reconfiguration using RESTful JSON API
- Multiple application languages and versions can run simultaneously
- Dynamic application processes management (coming soon)
- TLS support (coming soon)
- TCP, HTTP, HTTPS, HTTP/2 routing and proxying (coming soon)

Node.js, Java, Ruby もサポートするようなので Java サポートされたらまた触ってみようと思います。

会社移転のお知らせと運命の3-6-18

株式会社Abby は先日移転しました。

旧住所は 東京都目黒区上目黒3-6-18 西村ビル7F

新住所

〒153-0051 東京都目黒区上目黒3-6-18 TYビル2F

弊社は、恵比寿の事務所の時も 〒150-0011 東京都渋谷区東3-6-18 でしたので、会社の住所が3回連続 3-6-18 ということで、この番地に運命を感じます。

f:id:yone098:20170808151241j:plain:w200

広さも以前に比べ倍以上なので皆で快適に作業しています😆

Access

中目黒駅に着いたら高架下沿いを歩いて2分ほどです。中目黒ラウンジ手前の入り口になります☕🍝

http://www.abby.co.jp/access/

これからも頑張りますので宜しくお願いします!

f:id:yone098:20170807165650j:plain:w200

弊社では引き続き社員募集しておりますので、気軽に遊びに来てください!!

社員募集

株式会社Abby エビイ では現在、社員を募集しています。

会社紹介

弊社は、少数で頑張っている会社です。 qiita.com

仕事内容としましては、箱庭ゲームの開発がメインです。海外向けのシステムの開発もやっていますので最近は海外出張が増えてきています。

今回の募集は箱庭ゲーム開発とシステム開発と両方になります。

www.abby.co.jp

募集要項

東京本社でプログラマを募集しています。 勤務地は中目黒になります。来月には引っ越しが決まっていますが、引越し先も中目黒です(駅から2分)

iOS向けアプリもJavaで開発しているのでJavaの開発経験がある人を特に必要としています。 とはいえ、Java は必須条件としていません。他に得意なプログラム言語があればそれで構いません。やる気重視です。

開発では、IntelliJAndroidStudioNetBeansEclipse またはエディタを使っており開発環境は各自自由に決めて下さい。 うちのCTOは、天邪鬼なもので EmacsJava 開発するために Emacs 用の開発環境を自作しています。完全にやり過ぎです。 github.com

Javaの開発基盤には libGDX を採用しており、UIに関わる部分はJava + libGDX で開発することになります。

Swiftvue.js での開発もあります。

今月からは Unity の勉強会を社内で始める予定ですので Unity に興味がある方も是非お願いします。

サーバ側の処理は全て Go で開発していますので、JavaGo を書きたい!という方は是非連絡してください。

開発のやり方としては、SlackSkype でやり取りしながら、Backlog というタスク管理サービスを利用してプロジェクトを進めます。

勤務時間に関して、定時を 10:00〜19:00 と定めていますが各自にスケジューリングは任せていますので、自宅作業だったり私用を済ませて午後から出社したり自由度はとても高いです。

服装については、特に決まりはありません。

打合せはオンラインにて Google HangoutSkype で完結しますし、もしお客様との対面での打ち合わせが必要になった場合は私が行きますのでスーツは不要です。

一緒に開発をしてみたい方は、info@abby.co.jp にメールするか TwitterFacebookで私(@yone098)までDMなどで連絡をしてください。

中目黒にフラっと立ち寄る感覚で会社に遊びに来てもらえるだけでも嬉しいです。

何卒よろしくお願い致します!