2015年7月16日木曜日

yum で Redis をインストール

概要

yum で Redis の最新版をインストール
バイナリをダウンロードしてインストールする方法はこちら

環境

  • CentOS 6.6 64bit

インストール方法

rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
yum clean all
yum install redis --enablerepo=remi
chkconfig redis on

20150715 時点では3.0.2-1というバージョンがインストールできました

2015年7月15日水曜日

NewRelic にサーバのメトリックを送信してみた

概要

NewRelic で Server のメトリック (CPU, Memory, I/O, Network) を送信する方法を紹介します
過去に紹介したものはアプリ単位で監視する方法を紹介しました
NewRelic ではサーバのメトリック情報だけを送信することもできるのでその方法を紹介します

環境

  • CentOS 6.3 64bit
  • newrelic-sysmond 2.1.0
  • NewRelic 2015/07/14時点

メトリック送信用エージェントのインストール

今回は CentOS のサーバなので yumコマンドでインストール可能です

rpm -Uvh http://yum.newrelic.com/pub/newrelic/el5/x86_64/newrelic-repo-5-3.noarch.rpm
yum install newrelic-sysmond

License Key の設定

License Key は RewRelic の WebUI 上で確認することができます
Account settings に License Key の記載があるのでそれを設定ファイルに記載します

vim /etc/newrelic/nrsysmond.cfg

license_key=xxxxxxxx

エージェントの起動

service newrelic-sysmond start

で起動してしばらくすると NewRelic の Servers に対象のサーバのメトリックが表示されると思います

Tips

上手く監視できなかった場合は、NewRelic とサーバ間の Outgoing の ACL を確認してみましょう
通信するべきIPとポートの情報は以下を参考にしてみたください
wget できなければいけないドメインやIPが記載されています
https://docs.newrelic.com/docs/apm/new-relic-apm/getting-started/networks#availability

動作確認

NewRelic の UI で確認してみましょう
左上のメニュー一覧から「Servers」を選択します
newrelic_choice_servers.png

サーバの一覧が選択されます
newrelic_list_servers.png

メトリックの詳細を見たい場合は対象のサーバをクリックすると見れます
newrelic_detail_metric.png

最後に

前に試した記憶ではnewrelic-sysmondも自動でインストールされて起動されていた記憶があったのですが、今回新規のサーバを追加したらnewrelic-sysmondがインストールされていなかったので別途インストールしてみました
メトリックを見るためだけならNewRelicはめっちゃ簡単です

2015年7月8日水曜日

Java で kill のシグナルを受け取ってみた

概要

Javaで kill の -HUP のシグナルを受け取れるみたいなので検証してみました

環境

Mac OS X 10.10.4
Eclipse Luna 4.4
Java 1.8.0_31

シグナルを受け付けるコードを作成

package test;

import java.util.Scanner;

public class Test {

    @SuppressWarnings("resource")
    public static void main(String[] args) throws InterruptedException {
        Runtime.getRuntime().addShutdownHook(new Thread(() -> System.out.println("Run Shutdown Hook.")));
        System.out.println("Please send HUP signal.");
        while (true) {
            System.out.println("looping ...");
            Thread.sleep(5000);
        }
        // 以下のような入力を受け付ける処理でもOK
//      System.out.println("Please input.");
//      Scanner in = new Scanner(System.in);
//      String s = in.nextLine();
//      System.out.println(s);
    }
}

ポイントは1行で

Runtime.getRuntime().addShutdownHook(new Thread(() -> System.out.println("Run Shutdown Hook.")));

になります
上記の場合は HUP を受け取って終了する前にSystem.outを出力しています

動作を確認してみる

Eclipse 上で実行すると Eclipse の子プロセスとして実行されpidがわからないので java コマンドでターミナルから実行します
プロジェクトは普通の Java プロジェクトを想定しています

cd /path/to/project/bin
java test/Test

とすると無限ループがはじまります
この状態でpgrep javaでプロセス番号を調べてその番号を kill してみましょう

kill -HUP [process_number]

でこうすると無限ループが終了してSystem.outの内容が出力されます

$ java test/Test
Please send HUP signal.
looping ...
looping ...
Run Shutdown Hook.

とりあえずこれで Java 側でシグナルを受け取ることができました
addShutdownHookはメソッドもコールすることができるので別のメソッドをコールしてそっちの処理が終了するまでまた処理を続けることも可能です

最後に

これが何に使えるのかなというのを考えると

  • 無限ループに突入してしまった場合にHUP信号を外から送信して次の処理に進める
  • HUPしたタイミングで特定の処理(例えばロギング)を実行しその時の状況を把握する

とかとか
外部からシグナルを受け付けられる便利な機能なのでいろいろ考えられると思います

あと「java シグナル」とかで検索すると出てくる記事にsun.misc.Signalを使う方法が紹介されていますがどうやらsun.misc.Signalは非推奨もしくはなくなる可能性のあるクラスなので使わないほうがいいと思います

http://docs.oracle.com/javase/jp/6/api/java/lang/Runtime.html#addShutdownHook%28java.lang.Thread%29

2015年7月7日火曜日

Emacs で Mew を使って Gmail を受信してみた

概要

Emacs の mew というメールパッケージを使って Gmail を受信してみました
最新のMac (OS X) で試しています

環境

  • Mac OS X 10.10.4
  • stunnel 5.17
  • Emacs 24.4.1
  • Mew 6.6
  • Gmail 20150707時点

Mew のインストール

package.elを使ってインストールしました
package-list-packagesを起動して melpa の「mew 20150607.2316」を選択してインストールします
※20150707時点での最新の mew をインストールしているのでそれ以上のバージョンがあればそちらをインストールしてください

stunnel のインストール

stunnel は簡単に言えばSSL通信をするためのツールです
Homebrewを使ってインストールしました

brew install stunnel
/usr/local/bin/stunnel -version

証明書の設置

stunnel を使って Gmail と SSL 通信するのに利用します
stunnel のサイトで公開されている証明書をダウンロードして配置すればOKです

cd /var/tmp
wget http://www.mew.org/Release/certs-20110624.tar.gz
tar zvxf certs-20110624.tar.gz
mkdir ~/.certs
mv certs-20110624/* ~/.certs

GmailのIMAP設定

デフォルトではONになっています
ここの手順で確認することが可能です

Mewの設定を記載

.emacsでOKです
他の設定ファイルをloadしている場合はそのファイルでもOKです

; for configuration of mew
; Load stunnel
(setq mew-prog-ssl "/usr/local/bin/stunnel")
; User IMAP with Gmail for receiving a mail
(setq mew-proto "%")
(setq mew-imap-server "imap.gmail.com")
(setq mew-imap-ssl-port "993")
(setq mew-imap-user "your.account.name@gmail.com")
(setq mew-imap-auth  t)
(setq mew-imap-ssl t)
; User SMTP with Gmail for sending a mail
(setq mew-smtp-server "smtp.gmail.com")
(setq mew-smtp-ssl-port "465")
(setq mew-smtp-user "your.account.name@gmail.com")
(setq mew-smtp-auth t)
(setq mew-smtp-ssl t)

(setq mew-fcc "%Sent")
(setq mew-imap-trash-folder "%[Gmail]/ゴミ箱")
(setq mew-use-cached-passwd t)

変更する箇所は Gmail のアカウントを記載する部分です
「your.account.name」の部分を変更してください
その他が基本そのままでOKです
(setq mew-proto "%")とすることで mew を起動した際に受信フォルダに移動します
その他の値に関してここを検索するとどんな値なのかわかると思います

起動確認

emacs -e mew
とすると mew が立ち上がります
emacs を起動したあとでM-x mewでもOKです
立ち上がるとアカウントに対する認証が聞かれるのでGmailで使っているパスワードを入力します

問題なく認証が完了するとGmail上のメールデータが古い順に受信されます
初回起動時は全メールを取得するのでGmail上の受信メールが多い場合はダウンロードに時間がかかるかもしれません

デフォルトだと古い順に表示されるので新しい順に表示したい場合はバッファの最下部に移動してください

操作Tips

  • 終了方法
    Inbox内で「Q」とすることで終了させることができます
    メールの受信中に終了した場合は、mew 起動時に再度メールを受信してくれます

最後に

特にハマることなくできました
バージョンもだいぶ新しいのを使っているからでしょうか
ブラウザが使えない環境だと便利ですね
操作方法がわからなくなったら公式のマニュアルを読めばだいたいは解決すると思います

参考サイト

2015年7月6日月曜日

Heroku で Sinatra + Rack アプリを動かしてみた

概要

Sinatra で作成したアプリを Rack で動くようにして Heroku 上でも動作するようにしてみました
簡単にできたので紹介します
サンプルとして紹介するアプリはこちらです

環境

  • CentOS 6.6 64bit
  • Ruby 2.2.0p61
  • Sinatra 1.4.6
  • Rack 1.6.1
  • Heroku Toolbelt 3.39.1

Sinatra アプリの作成

何でもOKです
この辺を参考にすればあっさり作成できると思います
ruby app.rbで起動してポート4567でLISTENするアプリを作成できればOKです

Sinatra アプリを Rack で動作させる

config.ru の作成

config.rurackupという Rack のコマンドでアプリを起動させるために必要な起動ファイルです
以下のような感じで記載してください

require 'bundler'
Bundler.require

require './app'
run Sinatra::Application

requireしている./appの部分は作成した Sinatra アプリのファイル名を指定してください
これを作成したらrackupコマンドでアプリを起動できるようになります

rackup config.ru で起動できるはずです
またサンプルはbundlerでも動作するようになっています
bundler で動作させる場合はbundle exec rackup config.ruで起動できます

heroku へのデプロイ

herokuへのサービス登録は済ませておいてください
heroku-toolbeltのインストールがまだの場合は https://toolbelt.heroku.com/ を参考にインストールしてください
heroku-toolbeltがインストールできたらデプロイしていきます

デプロイは簡単です
作成した Rack アプリのディレクトリに移動して heroku にログインして push すればOKです

heroku login
heroku create
git push -u heroku master

とするだけでOKです
ログインは済んでいる場合は実行不要です

すでに登録済みのアプリに対してデプロイしたい場合はheroku createの代わりにgit remote add heroku https://git.heroku.com/APPNAME.gitとして heroku 上の git リポジトリを remote として追加します
APPNAMEの部分は既存のアプリ名を指定してください
heroku listで既存アプリ一覧を確認することができます

これで push に成功すれば rack アプリがデプロイされます

動作確認

push するとURLがターミナルに表示されると思うのでそこにアクセスしましょう
Mac等の環境でブラウザが使えるのであればheroku openでもOKです

サンプルを使っているのならばリクエスト情報をJsonでダンプしてくれるはずです

最後に

ポイントは config.ru で動作させるようにすることでした
Sinatra アプリとして動作する状況で push してもうまく動作しませんでした
heroku はどういうアプリなのかを自動で判断してアプリを起動します
Sinatra アプリの場合はそのままだと動作せず Rack アプリにすると動作するという話でした

2015年7月2日木曜日

Spring で MockMVC を使ったテストで Filter を使用する方法

概要

MockMvc のテストで Servlet の Filter を使用する方法を紹介します
MockMvc を使ったテスト環境の構築はこちらの記事を参考にして準備してください
また、Spring + Filter の使い方に関してはこちらを御覧ください

環境

  • Mac OS X 10.10.3
  • Eclipse Luna 4.4.1
  • Spring Framework 4.1.6
  • Spring Tool Suite 3.6.4
  • Java 1.8.0_31
  • Maven 3.2.1

Filter オブジェクトの作成

テスト用のクラスファイルに以下を追記します
@Autowiredを使ってクラスの作成と同時に Filter オブジェクトを生成します

@Autowired
private TestFilter testFilter;

フィルタの名前は自身の環境に合わせて適宜変更してください
また必要に合わせてimport文も定義してください

Beans として登録する

src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xmlに以下を追記します
@Autowiredで定義したフィルタオブジェクトをBeansの仕組みを使って生成するためです

<!-- for Filter -->
<beans:bean id="testFilter" class="com.sample.TestFilter">
</beans:bean>

MockMvc にフィルタを登録する

作成したフィルタをMockMvcのテスト時に使用するようにフィルタを追加します
MockMvc を WebApplicationContext から生成しているところで以下のようにフィルタを追加してください

this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).addFilter(this.testFilter, "/").build();

addFilterメソッドを呼び出します
第一引数でフィルタを指定して第二引数でフィルタを適用するURLマッピングを指定します

動作確認

mvn package等でテストを実行してフィルタの動作が実行されているか確認してください

最後に

web.xmlでアプリ的にフィルタを使うように定義していてもMockMvcでテストした際に有効にならないことに気が付き今回の対応を実施しました
web.xmlで定義していればテストでも通るようにしていいと思うんだけど、こうなっているのは MockMvc が Servlet の世界とは別世界のクラスだからなのだろうか
それとも親切心からなのだろうか

2015年7月1日水曜日

Spring で MockMVC を使ってテストしてみる

概要

Spring Framework には End to End の のテストを実現するためにMockMvcという仕組みが存在しています
簡単にいうとAPIをコールしてその結果を評価するという一連の流れをテストすることができます

環境

  • Mac OS X 10.10.3
  • Eclipse Luna 4.4.1
  • Spring Framework 4.1.6
  • Spring Tool Suite 3.6.4
  • Java 1.8.0_31
  • Maven 3.2.1

サンプルプロジェクト作成

過去の記事を参考に作成してください
Spring Framework のバージョンが最新でない場合は pom.xml 「org.springframework-version」のバージョン記載部分を最新のバージョンに変更してください

Spring-Test のライブラリを追加する

pom.xmlspring-testのライブラリを追加します

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-test</artifactId>
   <version>${org.springframework-version}</version>
</dependency>
<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>javax.servlet-api</artifactId>
  <version>3.1.0</version>
</dependency>

junitを定義するところが既にある場合でもバージョンが4.9未満である場合は4.9以上にしてください
javax.servletを読み込んでいますが、デフォルトだと読み込んでいるサーブレットのバージョンが2.5でこれだとCaused by: java.lang.ClassNotFoundException: javax.servlet.SessionCookieConfigと言われてテストが失敗するので 3.0 系のバージョンを読み込みます

テストコードの作成

src/test/java/test/sample/MockMvcSampleTest.javaにテストコードを作成していきます
STSでプロジェクトを作成するとテスト用のコードは何も作成されないので、適当にテスト用のクラスファイルを作成しましょう
作成したらMockMVCを使うための定義を記載します

package com.sample;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml"})
@WebAppConfiguration
public class MockMvcSampleTest {

    @Autowired
    private WebApplicationContext wac;

    protected MockMvc mockMvc;

    @Before
    public void setup() {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
    }

    @Test
    public void sampleTest() throws Exception {
        this.mockMvc.perform(get("/")).andExpect(status().isOk());
    }
}

いろいろ書いているので簡単にポイント説明します

クラスの定義の冒頭で3つのアノテーションを宣言しています

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml"})
@WebAppConfiguration

JUnit + MockMvc を使ってテストするために必要な記述です
詳細は正直自分もよくわかっていませんが

  • RunWithでランナーを選択して
  • ContextConfigurationでサーブレットの設定が記述されたコンテキストファイルを読み込んで
  • WebAppConfigurationでWebアプリをテストするための必要なコンテストに触れるようにしています

とにかく1つでも定義がかけるとエラーになるので必ず定義します

次にMockMvcのオブジェクトを定義する部分です

@Autowired
private WebApplicationContext wac;

protected MockMvc mockMvc;

MockMvcのオブジェクトを作成するのにWebApplicationContextが必要で、このオブジェクトは先程のアノテーション+@Autowiredすることで勝手に設定されるオブジェクトです
この2つのオブジェクトを使って、サンプルのsetupメソッドにあるようにbuildするとMockMvcのオブジェクトが生成されます

最後にテストの方法です

this.mockMvc.perform(get("/")).andExpect(status().isOk());

ポイントはgetstatusというメソッドをimport文でstaticに読み込んでいる部分です
こうすることでテストを書く際にメソッドの呼び出しを直感的に行えます
performでコールするAPIのパスとHTTPメソッドを指定して、その結果をandExpectで評価する感じです
今回のテストの場合はレスポンスコードが20X系であることを確認するテストになっています

Tips

他のHTTPメソッドでコールしたい場合は

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;

こんな感じでimportして

this.mockMvc.perform(post("/")).andExpect(status().isMethodNotAllowed());

こんな感じでテストできます

リクエストヘッダを指定したい場合はperformの後に.header("key", "value")で指定できます

リクエストパラメータを指定したい場合はperformの後に.param("key", "value")で指定できます

(POSTやPUTの場合に)リクエストボディを設定したい場合はperformの後に.content("body_value")で指定できます

実行

STSで作成していれば自動的にMavenプロジェクトになっているのでmvn packageなどで実行すればライフサイクルの中にテストが含まれるので自動でテストされます
テストだけ個別で実行したい場合はmvn test-compile testなどとすれば実行されます

最後に

Spring Framework にはデフォルトで end to end のテスト方法が含まれているのでAPIサーバを作る場合には割りと簡単にテストが書けそうです
MockMvc を使わないテストも記述することもできるので、メソッド個別でテストしたい場合には別のテストメソッドを作成してテストするといいと思います
JUnitが使えるのでJUnitAssert等も使うことができます

次回はテスト時に Filter を通してテストする方法を紹介したいと思います