このエントリーをはてなブックマークに追加

2017年1月5日木曜日

Dockerと私。第1回

明けましておめでとうございます。
旧年中は色々とお世話になり誠にありがとうございました。
本年も何卒よろしくお願い致します。

最近このブログのテック度合いが半端ないなと感じておりますが、
重ねるかの様に「Docker」について話をしたく思います。

以前のドトール会で「Docker」の話をさせて頂いたのですが、
その時はDocker engineのインストールや、イメージPull、DockerRunさせて
コンテナの起動といった一連の流れを実践しながらやらせて頂きました。
ただ、上手く伝え切れなかった部分が多々あったというか、
結構な漏れがあったと思われましたので、
仮想環境の話やそもそも的なところからやり直そうと思った次第でございます。

  • コンテナ型・ハイパーバイザー型・ホスト型といった仮想化について
  • Dockerって?
  • Dockerの特徴(利点・欠点)

■コンテナ型・ハイパーバイザー型・ホストOS型といった仮想化について

この3つの違いは絵的なものを見てもピンと来ないかもしれませんので、
下記にて説明をします。

・コンテナ型仮想化(Docker、LXC、OpenVZ)

    ホストOSからは各コンテナがプロセスとして認識される。
    (コンテナ内では自コンテナのプロセスしか見えないが、ホスト側から各コンテナで動作する全プロセスが見える)
    他の仮想化と同様に、コンテナ毎にCPUやメモリなどのリソース制限ができる。

・ホスト型仮想化(VMware Player、VMware Fusion、VirtualBox)

    ホストOS上で仮想化ソフトを実行し、その上で仮想マシン、ゲストOSが稼働する。
    3種の仮想化の中では一番ホストマシンへの処理負荷が高い。
    ホストOS上で動作するアプリケーションと共存できるため、PC上など個人環境での利用が多い。   

・ハイパーバイザ型仮想化(ESXi、Hyper-V、Xen、KVM)

    ホストOSの代わりに仮想マシンを制御するプログラムのハイパーバイザが動作する。
    ホストサーバ全体を仮想化で利用する。
    ホストOSを経由しないため、ホストOS型よりレスポンスはよくなる。

ホスト型なんかはVirtualBoxを使ったりする方にはイメージし易いかもしれません。


■Dockerって?

 

Dockerはソフトウェアコンテナ内のアプリケーションのデプロイメントを自動化するオープンソースソフトウェア。
Linuxカーネルにおける「libcontainer」と呼ばれるLinuxコンテナ技術・namespace、aufs、cgroup等を利用してコンテナ型の仮想化を行う。
VMwareやKVM・Xenなどの完全仮想化を行うハイパーバイザー型と比べ
コンテナ型であるDockerは、ディスク使用量が少なく、
インスタンスの作成や起動は速く、性能劣化がほとんどないという利点を持っている。
Dockerfileと呼ばれる設定ファイルからコンテナイメージファイルの作成が可能という利便性を持つ一方で、
コンテナOSとしてはホストOSと同じLinuxカーネルしか動作しない。
(Docker Toolbox を使うことでMacやWindowsでの動作が可能)


■Dockerの特徴(利点・欠点)

Dockerの利点

ホスト側のカーネルを使うためオーバーヘッドが小さくて高速。
メモリなどのリソース消費を抑える事が出来る。
リソース消費が少ないので多くのコンテナを立ち上げる事が可能。
新たにカーネルを立ち上げる必要は無く、ハードウェアの初期化などの操作が不要であるためコンテナの起動が速い。

上記利点については、
以前携わっていた仕事で使っていたOSレベル仮想化ソフトウェアLXCも同様なのですが、
ただDockerが違うのは、コンテナを起動する際、
各コンテナ毎にDisk上にデータを持つのではなく、
イメージから複数のコンテナを作るという方式でコンテナを立ち上げたりします。
コンテナのイメージ(テンプレート的なもの)からコンテナを作れるので、
同一環境や構成を簡単に作る事が可能なのです。
開発からデプロイといった一連の作業が速く進むといった具合です。
   
LXCだとディスクをLVM等で管理してあげないと駄目だったり、
カーネルの持つケーパビリティの機能を使って
コンテナの特権を制御とか必要となったりするので、
ことソフトウエア開発に特化する場合においては
Dockerの便利さが際立っているのがわかると思います。

Dockerの欠点

Docker上のコンテナはホストのカーネルを利用する為、
カーネルを共有できるCentOSやUbuntuといったLinuxでは動作し共存も出来るのですが、
根本的にカーネルの異なるOS、例としてWindowsServerはホストとなるLinux上で動作は不可能です。

恐らく日々オープンソース云々とか言ってられる方にとっては、
Hyper-Vを使ってとかあんまり機会がないかもしれませんのでこの辺は多くを語らずに。

そんなMicrosoftさんですが、Microsoft Azureにてコンテナーベースのアプリケーションをデプロイおよび管理出来るそうですね。

そんな事は置いておいて、次回はDockerの利用方法について語ろうかと思います。

2017年1月4日水曜日

ネットワークインジケータとAlamofireNetworkActivityIndicator

 こんにちは、Hiroです。
 iOSアプリ開発において、API通信での通信中は、ステータスバーにネットワークインジケータを表示させると思いますが、API通信部分でAlamofireを利用している場合、AlamofireNetworkActivityIndicatorを使うと表示・非表示を勝手に制御してくれます。とても便利なので、今回はこちらをご紹介したいと思います。
注)AlamofireNetworkActivityIndicatorは、2016年12月24日時点で、最新バージョンの2.1.0を対象にしています。


CocoaPodsでインストール


まずは、Alamofireを利用中ということを前提としています。
Podfileに下記を記載して、インストールします。
  use_frameworks!

  pod 'Alamofire'
  pod 'AlamofireNetworkActivityIndicator'
$ pod install


swiftコード上での設定


CocoaPodsでのインストールが完了したら、AppDelegate.swiftでAlamofireNetworkActivityIndicatorの設定をします。
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    NetworkActivityIndicatorManager.shared.isEnabled = true
    NetworkActivityIndicatorManager.shared.startDelay = 0
    NetworkActivityIndicatorManager.shared.completionDelay = 0.2
    return true
}
以上で、Alamofire.requestで通信を開始するとステータスバーにネットワークインジケータが表示され、通信が終了すると非表示になります。


AlamofireNetworkActivityIndicator設定値の説明

NetworkActivityIndicatorManager.sharedManager.isEnabled

この設定を「true」にするだけで、基本的には設定完了となります。
残りの「startDelay」と「completionDelay」は、下記で説明しますが、基本的にはオプションでデフォルト値があります。

NetworkActivityIndicatorManager.sharedManager.startDelay

通信が開始されて、この設定値の秒数後にインジケータが表示されます。
デフォルト値は、1.0となっており、通信が早く完了すると表示されないこともあるため、0を設定することの方が多いです。

NetworkActivityIndicatorManager.sharedManager.completionDelay

通信が完了して、この設定値の秒数後にインジケータが非表示になります。
デフォルト値は、0.2となっています。


Alamofireを使わない場合(WebViewなど)


Alamofireを使わない場合は、本内容の設定をしてもステータスバーにネットワークインジケータが表示されることはりません。
その場合、自前で通信開始時と終了時に下記の設定を記述する必要があります。
通信開始時にネットワークインジケータの表示:
UIApplication.shared.isNetworkActivityIndicatorVisible = true
通信終了時にネットワークインジケータの非表示:
UIApplication.shared.isNetworkActivityIndicatorVisible = false

2017年1月3日火曜日

macOS Sierraでcapybara-webkitを使うためにやったこと

こんにちは、h_ono_222です。
今回はmacOS Sierra環境でcapybara-webkitを使うために行ったことをまとめます。

手順

  1. Qt 5.5のインストール
  2. default_pre.prfを書き換える
  3. gemをインストール

1. Qt 5.5のインストール

こちらのウェブサイトから「qt-opensource-mac-x64-clang-5.5.1.dmg」をダウンロードしてインストール(デフォルトの設定で良い)します。

2. default_pre.prfを書き換える

デフォルトの設定でインストールした場合、下記の場所にあります。
# default_pre.prf
~/Qt5.5.1/5.5/clang_64/mkspecs/features/mac/default_pre.prf

このファイルの15行目を下記のように変更します。
# before
isEmpty($$list($$system("/usr/bin/xcrun -find xcrun 2>/dev/null"))): \

# after
isEmpty($$list($$system("/usr/bin/xcrun -find xcodebuild 2>/dev/null"))): \

3. gemをインストール

最後に、capybara-webkitをインストールします。
# pathを指定してgem install
PATH=~/Qt5.5.1/5.5/clang_64/bin:$PATH gem install capybara-webkit

2017年1月2日月曜日

私たちのFactoryGirlとRspecの使用ルール その1

こんにちは、Taroです。
新年明けましておめでとうございます。

最近、私たちはRailsのテストにRspecを使用しております。
(テストレコードの作成にはFactoryGirlを使用しています。)
今回は私たちのグループ内における基本的な使用ルールについて記載したいと思います。

その1と題しておりますが、その2があるかは未定です。
使っている中で、ルールを更新した場合は、その2、その3としてブログを書いていきたいと思います。

そもそもなぜ基本ルールなどを作成しようとしたのか?
RspecにしろFactoryGirlにしろ、それに沿った使い方をしていれば問題ないのではないか?
当初は私たちもそう考えておりました。
しかし、あまりに優秀すぎるが故、以下の悩みが生じました。
  • 1. 学習コストが高い
    便利な用法が数多く存在するが、それ故に統一感がなくなる可能性がある。
  • 2. 思わぬところでエラーが発生する可能性がある
    特にFactoryGirlですが、Aさんが手の込んだテストモデルを作成し、Bさんがそれをまた改修した場合、Aさんが担当したテストに影響が出る可能性があります。
  • 3. テスト実行に時間がかかるようになる
    せっかくだからと、コールバックメソッドを呼び続けると、全体で見たときのテスト実行に時間をとられることになってしまいます。

このような問題への一つの解として、基本的なルールを設けることとしました。

Rspec編


1. describe、context、itの階層で使用する


Rspecには他にもspecifyやexampleも存在しますが、基本は上記の3つの階層でテストを分類します。
  • describe・・・テストしたい対象(ex. Item#add、items/index)
  • context・・・テストの条件(ex. ログインに成功したとき or ログインに失敗したとき)
  • it・・・リクエストパラメータの違いなどで生じる結果(ex. リクエストパラメータが◯○のときは△△)
また、どうしてもcontextとitの間に階層がほしい場合はspecifyの使用を許可しています。
(ただ、現状specifyを利用するといったテストはないので、そこまで必要ではないのかもしれません。)

describe 'Item#add' do
    context '同一の商品名がない場合' do
        it 'successが返る' do
           expect(Item.add('pokemon')).to eq('success')
        end
    end
    context '同一の商品名がある場合' do
         it 'falseが返る' do
           expect(Item.add('pokemon')).to eq('false')
         end
    end
end

2. 10個以上のテストレコードを作成したい場合は、トランザクションを張る


これはテスト実行速度を少しでもあげるための策です。
ApplicationRecord.transaction do
# テストレコードの作成 end

FactoryGirl編


FactoryGirlの方が特にパフォーマンスなどに影響を与えるため、試行錯誤しております。

1. デフォルトのモデルは初期値を与えるだけで、個別に値設定したい場合は、createメソッドの引数で指定する


デフォルトのモデルはきれいな状態で残しておきます。

2. traitにてパーツを量産しない


ただし、以下の条件の場合は作成できます。
これは、パーツの名前と継承したモデル名で、どんなモデルなのか判断しやすいためです。

2-1. enumで定義されているカラム

例えば、itemsテーブルにカテゴリを定義するcategoryカラムがあったとします。
1〜4までのカテゴリがあり、それぞれにenumでカテゴリ名が定義されているとします。このような場合は、traitとそれを継承したモデルを作成します。
trait :game do
    category 1
end
factory :item_game, traits: [:game], parent: :item

2-2. 過去、未来、現在で固定する

trait :past do
    started_at Time.now.yesterday.beginning_of_day
    ended_at Time.now.yesterday.end_of_day
end
factory :item_past, traits: [:past], parent: :item

2-3. 関連データを生成する場合

関連データを作成してくれることは非常に便利ですが、テストが遅くなる原因となります。
また、別に関連データ自体必要ない人もいるため、こちらもtraitでパーツにして必要な人のみ使用します。
# Item belongs_to Companyとします
trait create_company do
    company
end
factory :item_create_company, traits: [:create_company], parent: :item

現状まとめますと、以上になります。
今後もRSpec、FactoryGirlは使用していこうと思いますので、ルールを更新したら、その2、その3というかたちで記事を書いていきたいと思います。
また、このブログを読んだ方で、何かご意見などございましたらコメントをお待ちしております!

2017年1月1日日曜日

明けましておめでとうございます。2016年の人気ブログ ランキング

 明けまして、おめでとうございます。Hiroです。2016年は色々な方にお世話になり、学びの多い年となりました。本年もどうぞよろしくお願いします。
 さて、新年の最初の投稿は、2016年の当ブログ記事内でPV数の高かった上位5つのブログを発表します。ぜひ、再度お読みいただければと思います。

1位:さらば「rails migrate」、よろしく「ridgepole」


2位:Amazon RDS 一般クエリログとスロークエリログの削除


3位:MySQL 5.7 オプティマイザの改善(UNION ALL)


4位:ObjectクラスにBooleanへの変換メソッド「to_b」を追加する


5位:はじめの一歩 -Rails 時間・タイムゾーン編- その2


 今後も読者の方にとって、役立つ情報をブログにしていきたいと思っています。