まるまるこふこふ

数々の次元が崩壊し、全ての生命が塵と化すのを見てきた。私ほどの闇の心の持ち主でも、そこには何の喜びも無かった。

【前編】Bootstrap テーマ Honoka を fork してみる

この記事は Bootstrap Advent Calendar 2015 の6日目の記事です。

Bootstrap テーマ「Honoka」

Bootstrap テーマに Honoka というのがあります。
「日本語も美しく表示できる」という謳い文句に加え、
アニメキャラにインスパイアされた配色設定が好みで、
社内ツールや個人のWebサイトなどでよく使わせて頂いてます。

そんな Honoka ですが、色違いのForkテーマとして
UmiNico などが存在します。

これは僕も Honoka を fork するしかないですね!

準備

Honoka をイジるにあたって、必要な技術知識は下記です。
ふわっとだけ調べて、概要を把握しておきます。

Node.js
Grunt
Bower
Ruby
Bundler
Sass

Build してみる

Honoka は Sass を使って書かれています。
build することで、 Sass -> cssコンパイルされるわけですね。

まずは Build を試してみます。

Build 方法は公式のWikiに既にまとまってます。

Wikiのとおりに各種 npm モジュールや bundle モジュールを入れましたら、
build を実行します。build手順はgruntによって定義されているので、私がしなくちゃいけないのは下記コマンド一発です。

$ grunt build

build された cssdist/css/ 以下に保存されます。git clone した段階で
既に build された css が存在します。build されたことを確認したいので、
一旦削除します。

$ rm ./dist/css/bootstrap.css
$ rm ./dist/css/bootstrap.min.css

dist/bootstrap-ja.html を表示してみましょう。bootstrap.css を削除しちゃったので、
見るに耐えないページが表示されたことだと思います。では build します。

$ grunt build
Running "clean:build" (clean) task
>> 7 paths cleaned.

Running "bower:install" (bower) task
>> Installed bower packages
>> Copied packages to /Users/hogehoge/Desktop/Honoka/dist

Running "setAutoPrefixerConfig" task

Running "scsslint:bootstrap" (scsslint) task
Running scss-lint on bootstrap
>> 5 files are lint free

Running "scsslint:assets" (scsslint) task
Running scss-lint on assets
>> 1 file is lint free

Running "sass:bootstrap" (sass) task

Running "sass:assets" (sass) task

Running "autoprefixer:bootstrap" (autoprefixer) task
>> 1 autoprefixed stylesheet created.

Running "autoprefixer:assets" (autoprefixer) task
>> 1 autoprefixed stylesheet created.

Running "csscomb:bootstrap" (csscomb) task
>> Using custom config file "bower_components/bootstrap/less/.csscomb.json"...
>> Sorting file "dist/css/bootstrap.css"...

Running "csscomb:assets" (csscomb) task
>> Using custom config file "bower_components/bootstrap/less/.csscomb.json"...
>> Sorting file "dist/assets/css/example.css"...

Running "cssmin:minify" (cssmin) task
>> 1 file created. 165.35 kB → 134.81 kB

Running "replace:banner" (replace) task

Done, without errors.

成功しました。./dist/cssbootstrap.cssbootstrap.min.css ができていることだと思います。
先ほど開いた dist/bootstrap-ja.html をリロードするとキレイなページに戻りましたね。

ちょっと加工してみる

honoka の背景色は灰色っぽい色ですが、これを白 #fff に変更したいと思います。

build される前の scss は ./scss にあります。

背景色が定義されているのは ./scss/honoka/_variables.scss です。
35行目付近に下記の記述があるので #f9f9f9 -> #fff に書き換えます。

//** Background color for `<body>`.
$body-bg:               #f9f9f9 !default;

再度 build

$ grunt build

dist/bootstrap-ja.html をリロードすると、背景が白くなりました!

次回

長くなったので後編に続きます。

【後編】Bootstrap テーマ Honoka を fork してみる - まるまるこふこふ

ログ出力ライブラリ node-bunyan

この記事はNode.js Advent Calendar その2 の5日目の記事です。

express のアプリケーションログ

express でアプリケーションログを出力したい。

express-generator などで express アプリを作ると、最初から morgan
使われていますが、これはアクセスログを保存するもので、
アプリケーションログを出力するものではありません。

有名ドコロを探ってみたところ、log4jsbunyan があるみたいなので、 bunyan 使います。

バニヤンと読むみたいです。ぶーにゃんって読んでました。ぶーにゃんかわいいよぶーにゃん。

インストール

npm install bunyan

インストールしましょう。インストールすると bunyan コマンドという
ログをいい感じに見やすくするツールもついてきます。これは後述します。

Introduction

$ cat hi.js
var bunyan = require('bunyan');
var log = bunyan.createLogger({name: 'myapp'});
log.info('hi');
log.warn({lang: 'fr'}, 'au revoir');

こんな感じのスクリプトを書いて実行します。 name にはアプリの名前をお好きに書いてあげてください。

$ node hi.js
{"name":"myapp","hostname":"banana.local","pid":40161,"level":30,"msg":"hi","time":"2013-01-04T18:46:23.851Z","v":0}
{"name":"myapp","hostname":"banana.local","pid":40161,"level":40,"lang":"fr","msg":"au revoir","time":"2013-01-04T18:46:23.853Z","v":0}

実行するとこんな感じのログが標準出力されます。bunyan は
JSONフォーマットでログ出力してくれるので
fluentd などでログを扱いやすいのが特徴です。

level というのはエラーレベルのことですね。bunyan には下記6つのAPIでログを出力することが
でき、それぞれ危険度に応じて level が設定されており、それが出力されております。

var bunyan = require('bunyan');
var log = bunyan.createLogger({name: 'myapp'});

log.trace('trace log'); // level 10
log.debug('debug log'); // level 20
log.info('info log'); // level 30
log.warn('warn log'); // level 40
log.error('error log'); // level 50
log.fatal('fatal log'); // level 60

bunyan コマンド

JSONフォーマットはコンピュータには扱いやすいですが、人間が読むことには適していません。 先ほどご紹介した bunyan コマンドを使うと、見やすい形に整形してくれます。

$ node hi.js | ./bin/bunyan
[2013-01-04T19:01:18.241Z]  INFO: myapp/40208 on banana.local: hi
[2013-01-04T19:01:18.242Z]  WARN: myapp/40208 on banana.local: au revoir (lang=fr)

標準出力からJSONフォーマットのログの内容を受けて、標準出力に整形後のログを
吐き出します。

※実際にはカラーリングされてて、より読みやすいです。

ログの出力設定

bunyan はデフォルトでは info 以上のログを標準出力に吐くようになってます。

// デフォルトの設定
var log = bunyan.createLogger({
    name: 'myapp',
    stream: process.stdout,
    level: 'info'
});

こんな感じで出力先をファイルにすることができます。

var log = bunyan.createLogger({
  name: 'myapp',
  streams: [
    {
      level: 'error',
      path: '/var/tmp/myapp-error.log'
    }
  ]
});

配列になってることからも分かる通り、出力先を複数設定することも可能です。

// info以上 -> 標準出力
// error以上 -> myapp-error.logに出力
var log = bunyan.createLogger({
  name: 'myapp',
  streams: [
    {
      level: 'info',
      stream: process.stdout
    },
    {
      level: 'error',
      path: '/var/tmp/myapp-error.log'
    }
  ]
});

ログファイルのローテーション

ログ・ファイルのローテーションはLinux の logratate を使っても良いのですが、
bunyan は自前でログローテション機能も持ってます。

var log = bunyan.createLogger({
    name: 'foo',
    streams: [{
        type: 'rotating-file',
        path: '/var/log/foo.log',
        period: '1d',
        count: 3
    }]
});

これで

/var/log/foo.log # 今日のログ
/var/log/foo.log.0 # 前日のログ
/var/log/foo.log.1 # 前々日のログ
/var/log/foo.log.2 # 前々々日のログ

と 1日ごとに 3つのログをローテーションしてくれます(それ以降の数のログは削除されます)

src

var log = bunyan.createLogger({src: true, ...});

createLogger 時に src: trueを設定すると、

{
  "name": "src-example",
  "hostname": "banana.local",
  "pid": 123,
  "component": "wuzzle",
  "level": 4,
  "msg": "This wuzzle is woosey.",
  "time": "2012-02-06T04:19:35.605Z",
  "src": {
    "file": "/Users/trentm/tm/node-bunyan/examples/src.js",
    "line": 20,
    "func": "Wuzzle.woos"
  },
  "v": 0
}

とより詳細な情報を吐いてくれます。開発環境で実行する時は true にしておくといいかも。

終わり

GithubREADME にもっとたくさんいいこと書いてあるよ!

IDCFクラウドを使った個人Webサービス構築

さいです。先日、東方Project の二次創作同人誌の感想を投稿・共有できる 香霖堂書店というのをリリースしました。(※ 2019/03/29 閉鎖しました)
現状、ユーザー数約50名、PV/1day 約200程度で
運営させていただいてます。

個人でWebサービスを作ることについては後日またお話させていただく
として、今回はサーバ構成についての話をさせていただきたいと思います。

サーバ構成

プロキシサーバー
Nginx です。sai-chan.com ドメイン香霖堂書店と一緒に
自分のポートフォリオサイトも運営しているため、
ユーザーのアクセスは、バーチャルホスト機能で、
www.sai-chan.com を ひまわり鎮痛剤 サーバーに、
korindo.sai-chan.com を 香霖堂書店に振り分けています。

個人ポートフォリオサイトAPサーバー
自分の自己紹介サイトです。⇛ ひまわり鎮痛剤
Apacheです。香霖堂書店とはまた別のサイトとして、
静的ファイルだけで構成されています。

香霖堂書店APサーバー
Node.js で動くアプリケーションサーバーです。
香霖堂書店に関わる動的ファイル、静的ファイル両方を配信しています。
またユーザーがアップロードした画像はAPサーバーに保存されています。

香霖堂書店DBサーバー
MySQL, Redis, ElasticSearch が同居して稼働しています。
データは基本的にMySQLに保存し、場合に応じて
キャッシュをRedisに、全文検索に必要なデータをElasticSearch に、
二重に保存しています。

開発用サーバー
開発は全てsshでこの開発用サーバーに入ってやってます。
本番環境と同じ環境を構築してるので、動作確認などが容易です。

クラウドサービス

全てのサーバーは IDCFクラウド のS1で構成されています。
個人Webサービスにおいて、レンタルサーバーや VPS、herokuのような IaaS を使わず、
クラウドサービスを利用する利点は、スケールアウトが容易なことだと思います。

クラウドサービスはサーバーの追加・削除が容易なので、Webサイトの負荷が増えたときに、
サーバのスペックを上げる方法だけでなく、サーバーを増やすことでも対応することができます。

IDCFクラウドはサーバーの追加・削除ができるAPIも公開してますので、
コマンド1つでAPサーバーの追加、あるいはアクセス数を監視して自動で
APサーバーの追加・削除を行う仕組みなんかも作れます。

IDCF クラウド

クラウドサービスだと有名ドコロに AWS や さくらクラウドなどあると思いますが、
IDCF クラウドを選択した理由は3点あって、

・日本語
・料金体系が明確

です。管理画面、マニュアルやドキュメントが全て日本語なので、
英語の苦手な私でも容易に触れます。

また最小スペックのS1だと料金が月々最大500円とおそらく類似のクラウドサービスの中で
一番安く また最大500円と謳っているのはクラウド初心者の私にとって

「サーバーをつけっぱなしにするとどれだけお金をとられるのかわからない」

みたいな不安がなく安心でした。

IDCFクラウドのS1で構築する際のポイント

先程も書きましたが、全てのサーバーはIDCFクラウドの中で一番安いS1(1台辺り月500円)で
構成されています。 S1のスペックは CPU1コア、メモリ1GB、ディスク15GBと最低辺です。

ネックになるのはCPUとメモリです。CPUやメモリ不足でサービスがダウンしないよう、
香霖堂書店ではキャッシュ処理やNodeによる非同期処理を避けて、レスポンスが遅くても
確実にページを返すようにしています。

一応、今のところそのような問題は起きてなく、一番処理の重そうなElasticSearchによる
全文検索処理でも 約0.025 秒 でレスポンスを返せてます。

またディスクについては15GBと割りと容量が余るので、ユーザーのアップロードした画像は、
各サイズのサムネイルを作ってディスクに保存し、リクエストのたびにサムネイルを作ることを
避けています。

その他IDCFクラウドの便利な点

新規サーバー作成がだいたい30秒もあれば終わります。サーバーのテンプレート機能もあるので、
ミドルウェアの性能検証なんかでサーバーを作ったり潰したりすることが多いので助かってます。

あとサーバー監視に Mackerel のFreeプランを使ってますが、IDCFクラウドのユーザーは
監視できるホスト数が無限だったり、グラフを1週間分表示できたりするので良いです。

終わり

というわけでみなさま、よいクラウドライフを。

Node.js の ActiveRecord ライブラリ Knex.jsを使う

今日の知見です〜。

Node.js からActiveRecordを用いてRDBMSにアクセスするに辺り、 knex.jsが便利でした。

var knex = require('knex')({
  client: 'mysql',
  connection: {
    host     : '127.0.0.1',
    user     : 'your_database_user',
    password : 'your_database_password',
    database : 'myapp_test'
  },
  pool: {
    min: 0,
    max: 7
  }
});

knex
.select('*')
.from('test')
.where('id', id)
.then(function(rows) {
  console.log(rows);
})
.catch(function(err) {
  console.log(err);
});

雑にサンプル書いたけど、コネクションプーリングをknex側でやってくれるのが良い。 インターフェイスはcallbackでもPromiseでも選べる(上のサンプルはPromiseで書いてる)

selectを2回発行するときとか

javascriptの非同期に慣れていないとよくやってしまう失敗だが、 1回目のselect の結果を受けて2回目のselect を発行するとき、

var user_id;
knex
.select('user_id')
.from('user')
.where('id', id)
.then(function(rows) {
  user_id = rows[0].user_id;
})
.catch(function(err) {
  console.log(err);
});

knex
.select('*')
.from('detail')
.where('user_id', user_id)
.then(function(rows) {
  console.log(rows);
})
.catch(function(err) {
  console.log(err);
});

user_id を取得してdetail テーブルからデータを引くコードだが、上記のコードはうまく動かない。 2つのselect 文が非同期に実行されるので、user_id を取得してから detail に select される保証はない。

次のように1つめのselect文のコールバックの中で2つめのselect文を呼べば select文の発行順番が保証される。

var user_id;
knex
.select('user_id')
.from('user')
.where('id', id)
.then(function(rows) {
  user_id = rows[0].user_id;
  knex
  .select('*')
  .from('detail')
  .where('user_id', user_id)
  .then(function(rows) {
    console.log(rows);
  })
  .catch(function(err) {
    console.log(err);
  });
})
.catch(function(err) {
  console.log(err);
});

コールバックがネストするので非常にコードが読みにくい。select文を発行するたびに ネストしないといけないのか?Promise はこうした callback地獄を解決するための手段だ。

var user_id;
knex
.select('user_id')
.from('user')
.where('id', id)
.then(function(rows) {
  user_id = rows[0].user_id;
  return knex
  .select('*')
  .from('detail')
  .where('user_id', user_id)
})
.then(function(rows) {
  console.log(rows);
})
.catch(function(err) {
  console.log(err);
});

1つめのthen で user テーブルへのselectが実行され、2つめのthen で detail テーブルへのselect が実行される。 両者のselect 文のどちらかでエラーが発生すれば最後のcatch でエラーが拾われる。 わかりやすい。

DBへの接続をシングルトンで保持する。

複数のライブラリからknexを呼ぶ場合、各ライブラリでknexを初期化すると その文だけDBへのコネクションが増えるので、knex インスタンスを1つに保持しつつ、 複数のライブラリからknex を使用したい。 そのような場合、シングルトンなクラスを作る必要がある。

Node.js の require の仕組みはシングルトンを非常に作りやすい。

// knex-singleton.js
var knex = require('knex')({
  client: 'mysql',
  connection: {
    host     : '127.0.0.1',
    user     : 'your_database_user',
    password : 'your_database_password',
    database : 'myapp_test'
  },
  pool: {
    min: 0,
    max: 7
  }
});
module.exports = knex;

このようなモジュールを作っておき、各ライブラリから

var knex = require('./knex-singleton');

knex.select('*').from('user').then(function(rows){ console.log(rows); });

こんな感じで使える。knex-singleton が何回呼び出されようが、knex インスタンスは常に1つになる。

swap領域を設定する

サーバ代節約のため、hubot サーバと開発環境サーバをまとめたら、 mysqld がOOM killer に殺されることがちょくちょく増えたので swap 領域を設定します。

OOM killed されたのを確認

CentOS

$ sudo cat /var/log/messages | grep Killed
Oct 11 18:22:25 kaihatsu kernel: Killed process 29702, UID 27, (mysqld) total-vm:1456776kB, anon-rss:491796kB, file-rss:64kB

優先順位を上げる

/proc/PID/oom_adjに(優先度低)-16から+15(優先度高)の値を設定することで優先度を設定できる。 -17を設定するとOOM Killerの対象外になる。

$ sudo cat /proc/[Process ID]/oom_score 
2000

$ sudo echo -17 > /proc/[Process ID]/oom_adj

$ sudo cat /proc/[Process ID]/oom_score
0

swap領域の確認

$ sudo grep Swap /proc/meminfo
SwapCached:            0 kB
SwapTotal:             0 kB
SwapFree:              0 kB

swap 領域の作成

# 2GBのswap領域を作成
dd if=/dev/zero of=/swapfile1 bs=1M count=2048

# パーミッションの変更
chmod 600 /swapfile1

# swap領域用にフォーマット
mkswap /swapfile1

# swap領域を有効化
swapon /swapfile1

# reboot時にswap有効化
echo "/swapfile1 swap swap defaults 0 0" >> /etc/fstab

Fluentdでログをさくらクラウドのオブジェクトストレージに保存する

さくらクラウドのオブジェクトストレージはS3互換のAPIなので

GitHub - fluent/fluent-plugin-s3: Amazon S3 input and output plugin for Fluentd

を使えばFluentd を使ってログを保存できる。

さくらクラウドのオブジェクトストレージに登録

さくらクラウドAPI経由でバケットの作成・削除ができないので

コントロールパネルであらかじめ作っておきます。

INPUT

Fluentd の設定をします。Fluentd の仕組みやインストールについては

色々なところで解説されてるので省略します。

柔軟なログ収集を可能にする「fluentd」入門 | さくらのナレッジ

今回はnginx のログを収集したいのでINPUT側はこんな設定にしました。

<source>
  type tail
  format nginx
  time_format %d/%b/%Y:%H:%M:%S %z
  path /var/log/nginx/access.log
  pos_file /var/log/td-agent/nginx.access.log.pos
  tag s3.nginx.access
</source>

ログのパーミッション設定をtd-agentユーザーがアクセスできる設定にするのを忘れずに。

OUTPUT

ログの保存先をさくらクラウドのオブジェクトストレージにします。

先ほどのfluent-plugin-s3 をインストールしておきます。

sudo /usr/lib64/fluent/ruby/bin/fluent-gem install fluent-plugin-s3

fluentd の設定はこんな感じ

<match s3.*.*>
  type s3
  aws_key_id アクセスキーID
  aws_sec_key シークレットアクセスキー
  s3_bucket バケット名
  s3_endpoint b.sakurastorage.jp
  path log_
  buffer_path /var/log/td-agent/s3
  time_slice_format %Y%m%d%H
  time_slice_wait 10m
  utc
  buffer_chunk_limit 256m
  use_ssl no
  check_apikey_on_start false
</match>

さくらクラウドのオブジェクトストレージのバケット作成時に得た

「アクセスキーID」「シークレットアクセスキー」をaws_key_id aws_sec_key に設定します。

バケット名も設定します。

本来のAWS S3ならばここでリージョン設定をするのですが、

さくらクラウドはそんなものないので省略。代わりにs3_endpoint で

エンドポイントをAWSでなく、さくらクラウドのエンドポイントに設定します。

エンドポイント≠さくらクラウドのコントロールパネルに表示されてるURLなことに注意

URLに表示されてるのは既にバケット名に紐付いたエンドポイントなので

バケット名部分を削除してます。

https://sai-chan.b.sakurastorage.jp/ 

というURLがコントロールパネルに表示されていれば、エンドポイントは

b.sakurastorage.jp

ということですね。

あと通常のAWS S3の設定と異なり、下記の設定を追加してます。

  use_ssl no
  check_apikey_on_start false

さくらクラウドのオブジェクトストレージだとSSLAPIチェックに対応してない?

っぽくてエラーになっていたのでその辺無視するようにしてます。

この辺 AWS S3と異なっていてつまづくところかなと思います。

終わり

これでこんな感じでFluentd から さくらオブジェクトストレージに保存できました。

LTで二次元嫁botについて語った - YAPC 2015

さいです。YAPC 2015に行ってきました。 適当に発表まとめようかなと思います。

前夜祭

PHP帝国の逆襲!

yapcasia.org

・次のPHPは5.6から一気に7にバージョンアップされます
・PSR-7 がきまるよ! PSRとはPHPer有志による設計のベストプラクティス的な仕様
・メルカリはサーバサイドはPHP! SlackもサーバサイドはPHP!
・HHVM ⇛ PHP7に速度で並ばれちゃった。
・Hack という言語を初めて知った。

Perlワンライナー入門

yapcasia.org

スライド Untitled - Swipe

perl ワンライナーに便利なコマンドラインオプション

-n オプション

while(<>) {
  [PerlScript]
}

-l オプション
標準入力の行を事前にchompしてくれる

-M オプション
モジュールをuseしてくれる

perl ワンライナーが向いてること

1.テキストデータの中から
2.正規表現で文字列を抽出して
3.抽出したデータを関数、クラスに渡す

perl の出自はそもそもsedawk あたりなわけで。
perl の謎言語仕様($_, <>, 謎変数, 頭のおかしい正規表現)はワンライナーのためにあるわけで。
いつの間にか web アプリケーションを記述する言語となったわけで。
perl の機能のうち、web アプリケーションに向いた部分だけ抽出したのが近年のLL言語なわけで。
Web アプリケーション用言語って視点から perl を語ることの視野の狭さを感じたわけでした。

入力と出力に真摯に向きあえば、perl ワンライナーを効率的に活用することができる。

技術ブログを書くことについて語るときに僕の語ること

yapcasia.org

・みんなが興味を持ちそうなワードをタイトルに入れる
・投稿時刻は平日の朝が無難

「Q.承認欲求ドリブンでブログを書くと、ブログ初期のブクマが伸びない時期とか辛くないですか?」

「A.積極的に技術情報はブログに書いていくべきというエンジニア文化とか
そういう周囲の声もあってブログを書くことに辛さは感じなかった」

というやり取りがあって、「おぉ……(弊社ではそんな声聞いたことないぞ)」って思って、
そういう空気感とか文化的なところを弊社でも作っていきたいと思った。

個人の技術ブログは、当人にとっても活動が他人から明確にわかりやすくなるだけでなく、
所属を明らかにブログを書いてれば、その会社にとっても、採用活動等にメリットがあるってエライ人が言ってた。

1日目

メリークリスマス!

yapcasia.org

Perl6 が 2015年クリスマスに!!!!

Larry Wall がやたら指輪物語に絡めてPerlの話をしてくるのを聞きながら
「あー海外のナードってハリーポッター指輪物語に熱狂的な人多いよなー。
日本のナードがアニメ好きな人多いのと一緒で、コンピュータ触ってると
現実世界に可能性見出さない人多いのかしら」
とか思ってた。

世界展開する大規模ウェブサービスのデプロイを支える技術

yapcasia.org

MiiverseHTML5+CSS+ perl(!) のいわゆるオーソドックスなWeb技術で出来てるそうです。

Git pull でデプロイ ⇛ Gitレポジトリが一台 ⇛ 本番サーバーのリージョンが世界のあちこちにある
⇛ 海を跨いでGit pull ⇛ ヤバイ!

Gitレポジトリをmaster/slave に分けて、同期サーバーが片方からpull 片方へpush で
両方のHEADをあわせるとかやってて面白かった。

Consul の話も出てきた。

Consulと自作OSSを活用した100台規模のWebサービス運用

yapcasia.org

Consulの話。YAPC, Consulの話この後他の発表でも死ぬほど出てきて、
こりゃ〜トレンドについていかないといけませんな〜ってなった。

Perlの上にも三年 〜 ずっとイケてるサービスを作り続ける技術 〜

yapcasia.org

ソフトウェア開発だ……って思いながら聞いてた。

技術的負債ができるのは仕方ないからどんどん返していこうねってのは
既に当たり前のように思ってることだけれど、具体的にどう返していくのかってイメージ湧いた。

古いアーキテクチャ、クラス設計の部分はそのままに、新しく作る箇所、修正を加える箇所については
積極的に新しいアーキテクチャに置き換えていく。

発表で紹介された本 hitode909.hatenablog.com

実践ドメイン駆動設計はちょっと気になってたので読みたい。

esa.io - 趣味から育てたWebサービスで生きていく

yapcasia.org

スライド esa.io - 趣味から育てたWebサービスで生きていく // Speaker Deck

esa.io ⇛ Markdown によるチーム内ドキュメント共有サービス
・もともと趣味で作ってたサービスを事業化&会社化
・仕事が終わってから毎日ハッカソン状態
・知人の会社が使ってくれることに
・楽しさやモチベーションは直接コントロールできない
・やれることを、やる
 ⇛楽しさやモチベーションを生み出す可能性のある行動をする
・毎日 Bundle Update
 ⇛ Botが毎日使用中のライブラリのバージョンを上げてPull Requestを上げてくる
・Bug fix タイムアタック
・開発スケジュールを決めない
 ⇛モチベーションの赴くままにやるのが最終的に効率が良い
 ⇛ユーザーからたくさん要望が来る⇛モチベーションが上がる⇛対応する

かの有名な小飼弾さんも言ってましたが
「アウトプットしない限りこの世にお前は存在しないのと一緒だ」
なのでエンジニアとして本を読んで勉強するのも大切ですが、
アウトプットしようという気になった。

趣味開発は、1. 何を、2. どう作って、3. どう使ってもらうかってとこが
だいたいみんな問題意識あるっぽいので、そのうち自分の拙い仮説をまとめたい。

LT

Slack + Hubot でお前の一番好きな二次元嫁キャラと一緒に仕事をする

www.slideshare.net

発表しました。

僕「二次元嫁botと2人でチームを作ります!!!」
会場「ざわざわ……」

僕「(二次元美少女は)クール」
会場「ざわざわ……」

僕「(二次元美少女は)最高」
会場「ざわざわ……」

稚拙なトーク内容でしたが、聞いてくださった方達、
ありがとうございました!

2日目

ISUCONの勝ち方

yapcasia.org

・コミュニケーション大事
・決まったことはメモで残す
・最初の1時間は課題の理解、プロファイリング
・最後の30分は再起動テストに残す
・事前に用意しとくと良いもの
プライベートなgitレポジトリ
wiki
メンバのSSH公開鍵
チャットルーム
技術選択についての簡単な打ち合わせ
過去問を解く

・まずブラウザで課題となるサイトへアクセスする。とりあえずベンチマークを動かす。
・見るべき点
プロファイリング
アクセスログ
MYSQL Slow Query
アプリケーションのプロファイリング
サーバ負荷の確認

アクセスログ解析
ベンチマークツールがアクセスしてる先を知る
ツール
 analyze apache logs
 kataribe
MySQL SlowLog 解析
 クエリの実行回数と頻度の両方を見る
 ⇛ N+1 のようなSlowではないが発行回数が多いSQLを特定する
 ⇛ SlowLog=0 で全てのログを出力する
 pt-query-digest ってツールが便利

・アプリケーションのプロファイリング
 strace
 tcpdump

・サーバの負荷
 top 全体の負荷
 iftop ネットワーク
 iotop ディスクI/O
 dstat

・参照を減らす
・通信を減らす
・プロセス・スレッドの数を減らす

・チューニングのヒント
 Apache vs Nginx ⇛Nginx 有利
 Nginx vs h2o ⇛h2oの方がスレッド型なのでh2oの方が有利か

 外部プロセスの起動
 HTMLテンプレート処理
 テキスト/画像変換処理
 RDBMS/Cacheの起動
 N+1

・変更を都度記録し、壊れる前の状態に戻せるようにする

我々はどのように冗長化を失敗したのか

yapcasia.org

またConsulの話でてきた

MySQLで2億件のシリアルデータと格闘したチューニングの話

yapcasia.org

シーケンシャルな値でテストデータ作ると、本番時にランダムな値だった場合に
インデックスの再構築の負荷を見逃す。

実践nginxモジュール開発〜CとLua

yapcasia.org

nginxはモジュール指向アーキテクチャである
ビルド時に3rd partyモジュールも導入できる

nginx_http_hello_world くらいなら実装できそうだし実装してみよかな〜ッて思ったが
ぶっちゃけ、ngx-Luaやngx-mruby 触った方が楽しそう。

OpenRestyというのを初めて知った qiita.com

 ソーシャルゲームにおける AWS 移行事例

yapcasia.org

辛いことをやめる!から始まる業務改善とInfrastructure as Code

yapcasia.org

技術寄りの話かと思ったら、人間の話かつ身に覚えのある話だったので
胸をキリキリさせながら聞いてた。

www.slideshare.net

組織の中で業務改善を進めていくには〜ってお話。

・スタッフには「メリットがあることを伝える」
・上長には「工数を減らせることを伝える」
・みんななかよく。⇛変革は敵を作ってはダメ。人を尊重する
・CTOの承認を得よう
 ⇛これは会社全体としてやるということをみんなに周知する
・トラブルはすぐ対応する
  対応が遅いとみんながツールを使うのをやめてしまう
・布教
 ドキュメンテーションは必須。
  特にTipsを残す。
 ハンズオン
  具体的に理解してくれる
  ハンズオンは何回もやる
・みんな変化は怖い
 受け入れるといいことがあるということを洗い出して、人に誠意を持って伝える
 ハンズオンはココロの障壁を下げます。俺でもできるんじゃんっていうことが伝えられる。
・CTOや上長に反対されたりするときは時間を置く。人は考えが変わる生き物
・CTOと事前に人間関係を作っておく
・仲間を増やして一緒に上長と掛け合う
ボトムアップの場合は『おまえ(だけのの意見だよね』で蹴られることが多い
・変革のメリットを説明する時に、うまくいかなくても決して相手に対して怒ってはいけない。

終わり

思った以上に Consul の発表多くてびっくりした。
HashiCorp社製の製品が激アツ。