astamuse Lab

astamuse Labとは、アスタミューゼのエンジニアとデザイナーのブログです。アスタミューゼの事業・サービスを支えている知識と舞台裏の今を発信しています。

続・NGINX Unitを試してみた話

こんにちは。開発部のtorigakiです。 今回はNGINX Unitを簡単に検証した話をさせていただければと思います。

タイトルに「続」がついている理由ですが、実は2年前に社内勉強会の発表ネタ(当時の発表資料はこちら)としてNGINX Unitを検証してみたことがありまして、当時のバージョンではNode.jsとJavaが未対応だったのですが、最新バージョンでは対応済みになっていたのでブログネタとして再び検証してみようと思った次第です。

NGINX Unitとは?

要約すると以下になります。

  • NGINX社製 軽量アプリケーションサーバ。
  • RESTful APIやJSON経由でサービス無停止でリアルタイムに設定変更がきる。
  • 1つのサーバに複数の言語の実行系や同一言語の複数バージョンの実行系を搭載できる。

インストール方法

今回は「Ubuntu 18.04.2 LTS」にインストールしてみました。

インストール方法は公式サイト通りにやってみました。

  1. 以下のコマンドを実行します。
# sudo curl -sL https://nginx.org/keys/nginx_signing.key | sudo apt-key add -
  1. 以下内容の「/etc/apt/sources.list.d/unit.list」を作成します。
deb https://packages.nginx.org/unit/ubuntu/ cosmic unit
deb-src https://packages.nginx.org/unit/ubuntu/ cosmic unit
  1. 以下コマンドを実行します。
# apt update
# apt install unit
# apt install unit-dev unit-go1.10 unit-jsc8 unit-jsc11 unit-perl \
      unit-php unit-python2.7 unit-python3.6 unit-python3.7 unit-ruby

起動・停止方法

以下コマンドで起動・停止できます。

# systemctl start unit
# systemctl stop unit

サーバー設定

NGINX UnitはJSON形式のファイルに設定内容を記述し、curlコマンドで反映させます。

以下はPHPの設定を反映させる場合の例です。

1.以下内容のPHPファイルを配置します。

  • 配置場所
/var/www/php/index.php
  • index.phpの内容
<?php echo "PHP Hello, Unit!"; ?>

2.以下内容のJSONファイルを作成します。

{
  "listeners": {
      "*:8080": {
          "pass": "applications/php_app"
      }
  },
  "applications": {
      "php_app": {
          "type": "php",
          "root": "/var/www/php/"
      }
  }
}

3.以下のcurlコマンドで反映させます。

curl -X PUT -d @php.json  --unix-socket /var/run/control.unit.sock  http://localhost/config

4.反映確認

以下のcurlコマンドで確認できます。

# curl http://localhost:8080/
PHP Hello, Unit!

ベンチマークとってみた

各言語ごとに性能差がどれくらいでるのか確認してみました。 ベンチマークにはこちらのサイトを参考にApache Benchを使用しました。

検証環境(物理PC)は以下になります。

OS:Ubuntu 18.04.2 LTS
CPU:4コア
メモリ:15GB

NGINX Unitバージョン:1.18.0-1

Apache Benchで実行したコマンドは以下になります。

ab -n <総リクエスト数> -c <同時リクエスト数><URL> 

実行したコマンド
ab -n 100000 -c 100 http://localhost:8080/ 

ベンチマーク結果で今回比較対象にする値は以下になります。

  • Requests per second(1秒で処理できるリクエスト数)(数値が高い方が好ましい)
  • Time per request(1リクエストの平均処理時間)(数値が低い方が好ましい)

各言語のアプリ設定は公式サイトのサンプル通りに設定しました。

検証方法は上記abコマンドで各言語のアプリに5回アクセスし、その平均値をとってみました。

各言語ごとのアプリ内容

  • Go
package main

import (
    "io";
    "net/http";
    "unit.nginx.org/go"
)

func main() {
    http.HandleFunc("/",func (w http.ResponseWriter, r *http.Request) {
        io.WriteString(w, "Hello, Unit!")
    })
    unit.ListenAndServe(":8080", nil)
}
  • Node.js
#!/usr/bin/env node

require("unit-http").createServer(function (req, res) {
    res.writeHead(200, {"Content-Type": "text/plain"});
    res.end("Hello, Unit!")
}).listen()
  • Java
<%@ page language="java" contentType="text/plain" %>
<%= "Hello, Unit!" %>
  • Perl
my $app = sub {
    return [
        "200",
        [ "Content-Type" => "text/plain" ],
        [ "Hello, Unit!" ],
    ];
};
  • PHP
<?php echo "Hello, Unit!"; ?>
  • Python
def application(environ, start_response):
    start_response("200 OK", [("Content-Type", "text/plain")])
    return (b"Hello, Unit!")
  • Ruby
app = Proc.new do |env|
    ["200", {
        "Content-Type" => "text/plain",
    }, ["Hello, Unit!"]]
end

run app

ベンチマーク結果

  • Requests per second
Go Node.js Java Perl PHP Python Ruby
2009.72 1809.132 1851.91 1981.946 1998.446 1945.988 1969.374

f:id:astamuse:20200609145145p:plain

  • Time per request
Go Node.js Java Perl PHP Python Ruby
0.5024 0.5552 0.543 0.5056 0.502 0.5148 0.5106

f:id:astamuse:20200609145207p:plain

今回は、「Hello, Unit!」の文字を表示するだけの簡単なアプリによる検証でしたので、このベンチマークの数値はアプリによっては変動するのではないかなと思われます。

まとめ

今回はNGINX UnitをUbuntuにインストールし、簡単なアプリを起動してベンチマークをとってみました。

本来であればphp-fpmやrailsなどとの比較検証もやるべきかと思うのですが、今回は時間がとれなかったため、また別の機会に検証できればと思っております。

弊社では引き続きエンジニア・デザイナーを募集中ですので、ご興味のある方は下からご応募いただければと思います。

scrollIntoView が便利だった話

f:id:astamuse:20200601151445j:plain

こんにちは、フロントエンドエンジニアの minamo です。

東京都でも緊急事態宣言が解除され、営業再開する施設が増えてきましたね。

今週はなんと2ヶ月ぶりに映画館に行きました(多い時は週3回は行っていたので、かなり久しぶり)!

公開延期作品が多い代わりに昔の名作が上映される映画館も多いので、2ヶ月通えなかったぶん、どんどん映画を見まくろうと思います。

2度目のブログはちょっとした内容ですが、 JavaScript で便利なメソッドがあったのでご紹介したいと思います。

scrollIntoView() メソッド

scrollIntoView() とは、対象の要素が ブラウザの表示範囲に入るまで スクロールする、というメソッドです。

developer.mozilla.org

事例紹介

これは私が scrollIntoView() メソッドを知るきっかけだったのですが、モーダルウィンドウの中でスクロール移動したい!というときに便利でした。

f:id:astamuse:20200601151456p:plain
元のページはスクロールしないよう固定しています(字が汚くてすみません)

最初は安直に scrollTo() で移動すればいいや〜と思ってたんですが、モーダルウィンドウ表示のように overflow-y: scroll; している中ではこの方法は使えなかったんですね。

f:id:astamuse:20200601151501p:plain
ウィンドウのスクロール位置は動かないわけですから、当然です。

そこで scrollIntoView() の出番です。

const element = document.querySelector(‘.title’); // 移動させたい要素を指定
element.scrollIntoView();

これで指定した要素が見える位置までスクロール移動してくれます!

オプション(引数)

alignToTop

デフォルトの true では表示させたい要素の上辺がブラウザの上辺に合わせて表示されますが

false を指定すると、表示させたい要素の下辺がブラウザの下辺に合わせて表示されます。

f:id:astamuse:20200601151507p:plain

element.scrollIntoView(false);

scrollIntoViewOptions

behavior: 'smooth' でスムーススクロールができます。

element.scrollIntoView({  
    behavior: 'smooth'  
});

オプションでやってくれるなんて気がきいてますね。

注意事項

一部ブラウザ (IE, Safari) では smooth オプションが有効にならないそうです。

caniuse.com

astamuse ではいつでもエンジニア&デザイナーを募集しています。

もちろんリモートでの面接にも対応していますので、お話だけでもお気軽にどうぞ!

Pipeline Jobから実行結果を簡単にSlackに通知する

こんにちは。宮崎からリモートしてます。開発部のyanagitaです。

新型コロナウィルスの影響の中、皆さんいかがお過ごしでしょうか。
全国的に緊急事態宣言が解除となりましたが、一足早く解除された宮崎では少しずつ緊急事態宣言前の生活に戻りつつあります。
先日、首都圏、北海道も解除宣言されてこともあり、一日も早く宣言前の生活に戻れることを願っております。

話を戻しまして、今回はすこし古いですがJenkinsのPileline JobからSlack通知について書きたいと思います。

今回確認したJenkinsとPluginのバージョン

  • Jenkins ver.2.222.3
  • Slack Notification Plugin v2.40

(問題)Pipelineプロジェクトでは、Slack Notificationsの設定項目がない

フリースタイル・プロジェクトやMavenプロジェクトでは、ビルド後の後処理に「Slack Notifications」が選択でき、ここでjobの実行結果に合わせてSlack通知の設定が可能になります。
しかし、Pipelineプロジェクトではビルド後の処理項目の表示がないので、Slack通知の設定はPipelineのScript内に記述する必要があります。

f:id:astamuse:20200527094635p:plain
フリースタイル・プロジェクトの例

ビルド後の後処理に「Slack Notifications」が選択が可能になっています。

f:id:astamuse:20200527094822p:plain
Pipelineプロジェクトの例

Pipelineプロジェクトではパイプラインの設定まででビルド後の処理が項目がないです。

Pipeline Script内にSlack通知を記述する

まず、Pipeline Scriptの記述は2つあって、pipeline記述にとnode記述が存在します。

  • Pipeline記述
pipeline {
    agent any
    stages {
        stage("code") {
            steps {
                echo "pipeline."
            }
        }
    }
}
  • Node記述
node {
    stage("code") {
        echo "node."
    }
}

両方とも同じ内容のJobになっていて、node構文のほうが記述量が少なく、プログラム形式に記述することができるので細かい制御が可能になりますが、ビルド失敗時のケアもプログラミング同様に記述する必要がでてきます。
複雑なJob実行を求められていないのであれば次で説明するpipeline記述のpost構文と組み合わせるとこで、Slack Notificationsの設定同様にビルド結果に合わせて通知内容を簡単に制御できます。

piepline記述のpost構文は、Jobの実行結果ごとに追加処理を記述することができるようになっています。

pipeline {
    agent any
    stages {
        // job処理
    }

    // ここからがpostの記述
    post {
        success { /* Job正常終了時 */ }
        failure { /* Job失敗時 */ }
    }
}

post直下のsuccess、failureがJob実行結果の条件になっており、該当する条件内の処理が実行されます。
success、failure以外はこちらをご確認ください。

post構文でビルド後の後処理と同様の設定が可能になったので、次に各実行結果の中でSlack通知を記述していきます。
Slack通知はSlack Notification Pluginに含まれるslackSendコマンドを利用します。

post {
    success {
        slackSend  color: 'good',
                           message: "build success."
        }
    }
    failure {
        slackSend  color: 'danger',
                           message: "build failure."
        }
    }
}

f:id:astamuse:20200527102717p:plain
Slack通知イメージ

slackSendは、メッセージ以外にチャンネルの指定やBot名も設定できます。(オプションはこちら)
指定しない場合は、Jenkinsの管理 > システムの設定 > Slack設定の内容がデフォルトの通知設定になります。
※ オフシャルのサイトではmessageオプションは省略可能になっていますが、私が環境ではmessageオプションを付けないとビルドエラーになってしまいJobの実行ができませんでした。
※ node記述でもslackSendは利用可能です。

以上、pipeline記述のpost構文とslackSendの組み合わせで、pipeline jobからSlack Notifications設定同様のSlack通知設定が簡単に行えるようになりました。

さいごに

アスタミューゼではたくさんのエンジニア&デザイナをまだまだまだ募集しています。 気になる方は下からご応募ください!新しい出会いをメンバー一同お待ちしてます!

Copyright © astamuse company, ltd. all rights reserved.