Ubuntuにgrpcをnpm insstallした

grpcを使ってみたかったので、npm installできるところまでのメモ。

前提:Ubuntuの用意

$ vagrant box add ubuntu-14.04 https://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box
$ vagrant init ubuntu-14.04
$ vagrant up
$ vagrant ssh

依存するライブラリのインストール

grpcをインストールするためにはprotobufのv3.0.0以上が必要で、2015/03/27時点ではソースからコンパイルする必要がある。

$ sudo apt-get install build-essential autoconf libtool unzip git
$ git clone git@github.com:google/protobuf.git
$ cd protobuf
$ git checkout v3.0.0-alpha-2
$ ./autogen.sh
$ ./configure
$ make
$ make check
$ sudo make install
$ vi ~/.bashrc //ここらへんはご自由に
$ tail ~/.bashrc
...
PATH=/usr/local/bin:$PATH
$ source ~/.bashrc
$ protoc --version
libprotoc 3.0.0


次にgrpcのインストールをする。

$ git clone https://github.com/grpc/grpc.git
$ cd grpc
$ git submodule update --init
$ make
$ sudo make install

npm installする

$ curl -sL https://deb.nodesource.com/setup_0.12 | sudo bash -
$ sudo apt-get install nodejs npm
$ npm install grpc


できた!!!


ちなみに最初はMacでインストールしようとしたけれど、素直に入らなかったのでUbuntuでやりました。

負荷テストの学び(4)

(1)~(3)では負荷試験について、負荷をかける方法を学びました。
今回は負荷をかけられたサーバの状態を知る方法についてです。

Ganglia

GangliaはRRDtoolのフロントエンドだと思えばいいみたいです。
監視したいサーバ内で、gmondのようなGangliaのプロセスを立ち上げて、監視するプロセスとマルチキャストで通信します。

以下、KLabのスライドから持ってきました。

主に利用するのは以下の3つのようです。
1. gmond
監視対象のサーバで動くデーモンです。
2. gmetad
管理サーバで動くデーモンです。gmondと通信を行い、データをRRDに保存します。
3. ganglia-web
RRDのデータを見やすく表示します

使ってみる

CentOSyum search ganglia したところいくつかあったので、とりあえずいくつか入れておきます。

ganglia.i686 : Ganglia Distributed Monitoring System
ganglia.x86_64 : Ganglia Distributed Monitoring System
ganglia-devel.i686 : Ganglia Library
ganglia-devel.x86_64 : Ganglia Library
ganglia-gmetad.x86_64 : Ganglia Metadata collection daemon
ganglia-gmond.x86_64 : Ganglia Monitoring daemon
ganglia-gmond-python.x86_64 : Ganglia Monitor daemon python DSO and metric
                            : modules
ganglia-web.x86_64 : Ganglia Web Frontend
libnodeupdown-backend-ganglia.x86_64 : Ganglia backend for libnodeupdown
yum install ganglia ganglia-devel ganglia-gmond ganglia-gmetad ganglia-web

次にデフォルトの設定で起動してみます。

service gmond start
service gmetad start

正しく動いていたら、/var/lib/ganglia の下にファイルができていると思います。

次にganglia-webで可視化します。

cd /var/www/html
mkdir ganglia

そしたら、localhost/ganglia にアクセスします。
私の場合は、error_logに以下が出ていたので、/etc/httpd/conf.d/ganglia.confを編集しました。

 client denied by server configuration: /usr/share/ganglia

具体的には、アクセスするクライアントのIPアドレスだけAllowにしました。

  Alias /ganglia /usr/share/ganglia

  <Location /ganglia>
    Order deny,allow
    Deny from all
    Allow from 126.213.x.xx
#    Allow from 127.0.0.1
#    Allow from ::1
    # Allow from .example.com
  </Location>

実際にアクセスする可視化出来てました。

デフォルトではCPUとメモリの状態しか出ませんが、あとは自分が知りたい指標に合わせてカスタマイズしましょうってことで。


これで、負荷試験からレスポンスタイムの計測、サーバの状態の可視化などが一通りできるようにりました。
あとは実践あるのみ!

負荷テストの学び(3)

今回は、jmeterからMySQLに負荷をかけてみます。

準備

jmeterがあるフォルダのlib以下に、mysql-connector-java-5.1.29-bin.jar を配置します。
このjarファイルはOracleのページからダウンロードできます。

次に、テスト計画を作成します。
JDBC RequestとJDBC Connection Configurationを設定します。
もしリモートサーバのMySQLにアクセスしたい場合は、利用するMySQLユーザに事前に権限を付与しておく必要があります。

今回はInnoDBへのINSERT性能を試してみます。

CREATE TABLE `jmeter` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `detail` text COLLATE utf8_unicode_ci,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
INSERT INTO jmeter (detail) VALUES ('test')

実行する

結果はこのようになりました。

だいたい一定時間でINSERTできています。
きっとINDEXが大きくなってメモリに載りきらなくなるまではこんな感じじゃないかなと思っています。

負荷テストの学び(2)

実際に Apache JMeter を利用して負荷テスト(性能テスト)をやってみました。

JMeterの設定をする

コマンドラインからjmeterを起動します。

上の画像のようにスレッドグループを作りました。
とりあえず、自分が作ったサイトのトップページとその後遷移するページにアクセスするスレッドを作りました。
ここで、スレッドのプロパティは、以下のようにしました。
スレッド数: 10
Ramp-Up 期間: 360
ループ回数: 100

ここでは、36秒(360 / 10)ごとに1個のスレッド(ユーザー)を立ち上げて、最大10個のスレッドが立ち上がり、それを100回繰り返すように設定しています。合計で、1000(10*100)セットのリクエストが送信されます。

結果を見るために、グラフ表示も追加しました。

結果を見る

結果は以下のようになっていました。

色別に分かれていて、 「現在のレスポンス時間(黒)」、「平均のレスポンス時間(青)」、「標準偏差(赤)」、「現在のスループット(緑)」だそうです。

サンプル数: 20
最新のサンプル: 160
平均: 133
偏差: 50
スループット: 342.33/分
中央値: 128

このサイトは1秒間に6リクエストくらい捌けることになります。
スループットがブチブチ切れてるのはなぜなんだろう…)

次に、スレッド数を50にして負荷をあげてみました。

だんだんグラフが上に張り付きつつあるのがわかります。


次回はもっと細かい機能まで使ってみたいと思います。
DBとか、メモリの状態を確認する方法はあるのだろうか。

passengerと組み合わせてnginxを使う

passengerからnginxを使うのは簡単です。

passengerをインストールしていれば、passenger-install-nginx-moduleが一緒にインストールされているので、これを実行します。

いくつか1問1答形式で答えていくと、勝手にコンパイルしてnginxをインストールしてくれます。
インストールできたら、/opt/nginx/conf/nginx.confを編集します。

    server {
        listen       3000;  //好きなポート番号で
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   /path/to/railsapp/public; //変更する
            passenger_enabled on;            //追加する
            index  index.html index.htm;
        }

あとは起動させるだけです。

/opt/nginx/conf

終わり。

MySQLのmaster/slave環境を作る

1つのサーバーでmaster/slave環境を作ります。
ここではmyqsld_multiを利用します。

複数のmysqldをたてる

まず、既に /var/lib/mysql のような場所で1つ動いていると仮定します(こいつがマスターになります
元の環境を汚したくないので、/usr/local/var/の下にmysql2とmysql3を作ることにします。

mkdir /usr/local/var/mysql2
mkdir /usr/local/var/mysql3
mysql_install_db --datadir=/usr/local/var/mysql2
mysql_install_db --datadir=/usr/local/var/mysql3

次に、mysqlのconfファイルであるmy.cnfを編集します。
ここでも既存の環境を汚したくないので、my_multi.cnfを用意します。

[mysqld]
user=mysql
symbolic-links=0
character-set-server = utf8

[mysqld_multi]
mysqld=/usr/bin/mysqld_safe
mysqladmin=/usr/bin/mysqladmin

[mysqld2]
datadir=/usr/local/var/mysql2
socket=/usr/local/var/mysql2/mysql.sock
pid-file=/usr/local/var/mysql2/hostname.pid2
port=3307
server-id=2

[mysqld3]
datadir=/usr/local/var/mysql3
socket=/usr/local/var/mysql3/mysql.sock
pid-file=/usr/local/var/mysql3/hostname.pid3
port=3308
server-id=3

masterとslaveを設定する

もともとあったmysqlデータベースをmasterにするために、一部、my.cnfを編集します。
log-binとserver-id=1を加えました。

[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
symbolic-links=0
character-set-server = utf8
log-bin
server-id=1

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

mysqlを再起動します。
その後、レプリケーション用のユーザーを作成します。

mysql> GRANT REPLICATION SLAVE ON *.* TO repl@localhost IDENTIFIED BY 'mysql';

次に、現在のクエリログの位置を調べるために、以下のコマンドを打ちます。

mysql> show master status;
+-------------------+----------+--------------+------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-------------------+----------+--------------+------------------+
| mysqld-bin.000002 |   961659 |              |                  |
+-------------------+----------+--------------+------------------+
1 row in set (0.00 sec)

あと、既にデータベースがある場合は、mysqldumpでデータをコピーします。
ちなみにこの間は、テーブルに変更が加えられない前提です。

mysqldump -u root -hlocalhost -p hoge > ~/dump.sql

これをslaveに教えてあげます。
まずmysqlを起動します。

mysqld_multi --defaults-file=/etc/my_multi.cnf start
mysqladmin -u root password 'mysql' --socket=/usr/local/var/mysql2/mysql.sock
mysqladmin -u root password 'mysql' --socket=/usr/local/var/mysql3/mysql.sock

次に、mysqldumpした結果を取り込みます。

mysql -uroot -pmysql -hlocalhost --socket=/usr/local/var/mysql3/mysql.sock hoge < ~/dump.sql
mysql -uroot -pmysql -hlocalhost --socket=/usr/local/var/mysql3/mysql.sock hoge < ~/dump.sql

最後に、マスターの登録をします。これをそれぞれのデータベースで行います。

mysql> CHANGE MASTER TO MASTER_HOST='localhost', MASTER_USER='repl', MASTER_PASSWORD='mysql', MASTER_LOG_FILE='mysqld-bin.000002', MASTER_LOG_POS=961659;


これでおしまいです。
masterでINSERTするとslaveにも反映されてると思います。

slaveでshow slave statusを打ったときに、
Got fatal error 1236 from master when reading data ... と出ていたら何かが間違っているので見なおしてみましょう。

jenkinsのgit-plugin 2.0.2にバグあり

2014/02/20にgit-pluginの2.0.2が出ましたが、バグがあったようです。
2014/02/21にバグが修正された2.0.3がリリースされていますので、あれって思った人はアップデートしましょう!

バグがあると、こんなエラーが起きます。

  • 過去のビルドが見れない
  • 以下のようなエラーがでる

FATAL: hudson/tasks/Mailer$UserProperty
java.lang.NoClassDefFoundError: hudson/tasks/Mailer$UserProperty


以下、参照
https://issues.jenkins-ci.org/browse/JENKINS-19345
https://wiki.jenkins-ci.org/display/JENKINS/Git+Plugin#GitPlugin-Bugs