2016年 独りで新規WEBサービスを開発・運用した際の知見


私が新規WEBサービス立ち上げ時に取り組んだ内容についてWEBエンジニア向けにまとめた記事です。

例えばNginxの設定でHTTPヘッダーが正しく設定されているかを確認できる**GoogleDevelopers PageSpeed Insights** を知っていると大変有利です。もちろんPageSpeed Insightsを知らなくてもWEBサービスを公開・運用可能ですがユーザに意図せず不利益を与えていたり、知らず知らずのうちにモバイルフレンドリーでないとGoogleから検索ペナルティを加えられている可能性があります。この記事は独りで新規WEBサービスを立ち上げた際のノウハウと取り組んだ内容について記述しています。

# 1. 概要（5行くらいで）
- スマホ対応は必須。トラフィックの50%はスマホから発生する。
- 速度は武器！速いサイトはそれだけで価値がある。
- SEOの内部対策は内部リンク整備とPageSpeed Insightsのみで大丈夫。
- SEOの外部対策はGoogle Search Consoleに登録するだけで大丈夫。GoogleとYahooから十分な検索トラフィックが発生した。
- それなりに結果でた


# 2. 丁寧に施策を実施すると結果は付いてくる
2015年12月17日のサービス公開から3週間で1日のPVが2800件まで上昇しました( ՞ਊ ՞) ✌ 

![スクリーンショット 2016-01-05 11.14.10.png](https://qiita-image-store.s3.amazonaws.com/0/65312/621f42d0-f6a6-82be-2edd-6c9640bec41f.png)

![スクリーンショット 2016-01-05 10.49.26.png](https://qiita-image-store.s3.amazonaws.com/0/65312/e54fb5bd-b76a-5ff3-df59-c420086d56be.png)


# 3. 開発着手前の設計
開発着手前の設計段階で考えておくこと。

![スクリーンショット 2016-01-05 11.16.10.png](https://qiita-image-store.s3.amazonaws.com/0/65312/b16ebe85-9056-a59a-b3b6-cbfc0771f968.png)

## 3-1. スマホ対応
スマホからのトラフィックは増える一方です。私のサイトだと61% はスマホからのアクセスでした。PC版とスマホ版では表示領域が大きく異なります。同じサイトデザインだと、どうしてもどちらかに無理が発生します。スマホ対応するための3つの手法を紹介します。

1. ディスプレイ幅によってCSSを切り替える（レスポンシブWEB）
2. UserAgentを見てWebフレームワーク側で動的にテンプレートを出し分ける
3. URLを分ける

以前2. のテンプレート切り換え方式で開発した結果、フロントエンドのHTML実装が2度手間になり大きく生産性が落ちた経験がありました。1,2,3全て行ったことがありますが、[Bootstrap3](http://getbootstrap.com/) を利用した1. のレスポンシブWEB対応が一番楽に無難に簡単に実装できると思います。

最後に**Googleウェブマスター向けブログ** の記事を貼っておきます。

■ Google 検索結果をもっとモバイル フレンドリーに
Google では、4 月 21 日より、ウェブサイトがモバイル フレンドリーかどうかをランキング要素として使用し始めます。
http://googlewebmastercentral-ja.blogspot.jp/2015/02/finding-more-mobile-friendly-search.html

■ Google がお勧めするスマートフォンに最適化されたウェブサイトの構築方法
http://googlewebmastercentral-ja.blogspot.jp/2012/06/google.html



## 3-2. サーバ構成と維持費を考える
サーバ維持費が必ず月3000円以下になるように構成しました。サーバ費用を抑えるために転送量による従量課金が発生しないクラウドサービスを選択しました。

![スクリーンショット 2016-01-05 12.02.39.png](https://qiita-image-store.s3.amazonaws.com/0/65312/57df2b7a-ed54-f42e-418f-d7c35a2af9ec.png)



## 3-3. 負荷の観点でサーバ構成のスケールする計画を立てておく
次の2つの観点で負荷が掛かったときのスケールアウト計画を立てました。

■ APPサーバのCPUが100%で張り付いたとき
ロードバランサを導入して、APPサーバの台数を1台からN台に増やす

![9ec81fb5-aaad-a8ab-c157-655e3429fa51.png](https://qiita-image-store.s3.amazonaws.com/0/65312/939f3968-6d20-4ab9-8afe-6834e7d63f05.png)


■ DBサーバの容量が不足したとき
クラウドサービスなので、追加でお金を払って再起動すればディスク容量が増やせる。


## 3-4. APPサーバのCPU性能を100%引き出す方法について考える
リバースプロキシの話です。Nginxを利用することが一般的です。たとえばCPUが4コアのサーバでCPUの性能を100%引き出すには4以上のHTTPワーカーを立ち上げる方法が一般的です。ユーザからのHTTP request をワーカーへ振り分けるためにNginxを利用しました。

## 3-5. ログイン/セッション機能は必要か考える
ログイン/セッション機能は脆弱性の温床です。ハッキング問題が発生して夜も眠れなくなる前に対策しておきましょう。ログイン/セッションを利用する場合は、オレオレ実装は我慢して標準でセッション管理機能を搭載した最新版のWEBフレームワークを利用すると無難な対策になります。

## 3-6. やらないことリストを作る
独りで開発しているとリソースはまったくもって足りません。あれもこれもと寄り道しているといつまでたっても完成しないのである程度見切ってしまうことが必要だと思います。自分の場合はこんなやらないことリストを作成しました。

- 1PV0.1円くらいなので、月10万PV突破するまでマネタイズは考えない
- 得意ではないページデザインは頑張らない
- jsとcssのMinifyは後で追加する
- 画像圧縮は後で追加する
- ログ機能は後で追加する
- 死活監視機能は後で追加する
- サーバ最適化設定は問題が起きてから着手する

## 3-7. 類似サービスを調べる/デザインを参考にするサイトを決める
類似サービスにはどんな機能が存在するのか調査して開発する機能を精査しました。また私はデザインが得意ではなかったので、PC版とスマホ版でそれぞれデザインを参考にするサイトを決めておきました。例えばスマホ版はQiitaを参考サイトとして、迷ったらちょくちょくデザインや機能を真似て実装しました。


# 4. 開発
![スクリーンショット 2016-01-05 16.06.30.png](https://qiita-image-store.s3.amazonaws.com/0/65312/085fb3c9-d3bf-03b2-9579-a569f705bbcb.png)

開発は一番楽しい部分です。慣れしたしんだ絶対に作りきる自信がある手堅い言語とフレームワークを利用して開発するか、まったく新しい言語とフレームワークにチャレンジするか。ワクワクしますね。迷ったら日本語ドキュメントがたぶん日本で一番豊富なRuby on Rails を使うことをオススメします。Railsには本番用のイケてる設定が最初から付いてるし、jsやcssのminifyもコマンド一つでやってくれたりと至れり尽くせり感があり、他のフレームワークより1歩も2歩も未来にいるなと感じます。`人間様が気分よくプログラムするための...`というRubyの格言を見事に体現した存在です。

自分はセッション管理機能が必要なかったので、PythonのFlaskで開発しました。具体的な内容は別記事にまとめています。

- [月額2650円でDBアクセス込み秒間214リクエスト捌くWebサーバ構築事例](http://qiita.com/haminiku/items/96fe07d408c1d7d2e24e)


# 5. 負荷試験
1秒に1リクエスト捌けたら1日で最大8万PV捌けます。負荷試験中に実際にサイトにアクセスしてみて問題なくブラウジングできるかの観点でも確認しましょう。負荷はapache benchコマンドを利用して負荷を掛けると簡単に掛けることができます。

- [Apache Benchでサクッと性能テスト](http://qiita.com/flexfirm/items/ac5a2f53cfa933a37192)

```shell-session:100並列で1万リクエスト分の負荷試験
# 100並列で1万回負荷試験（この設定をよく使っていました）
ab -n 10000 -c 100 http://example.com/
```

# 5. 速度を改善しよう
レスポンス速度遅延とユーザの離脱率には相関があります。早いサイトはそれだけで価値があります。

## 5-1. レスポンス速度を改善する
200ms以内にレスポンスを返すべきでしょう。個人的にはWebサービスはデータ肥大化で速度劣化していくものなので公開時は50ms以内を目標にすべきだと思います。応答速度の計測はApacheBenchコマンドで確認可能です。

- [Google 200 ms 以内にレスポンスを返すようにする](http://googlewebmastercentral-ja.blogspot.jp/2013/08/making-smartphone-sites-load-fast.html)

## 5-2. 静的コンテンツをブラウザキャッシュ
画像データ, css, js といったファイルは動的に変化しないのでユーザのブラウザにキャッシュさせると、2度目以降の転送が省略されページ描写速度が高速化します。HTTP通信時のHEADERにCache-Control: public と　Cache-Control: max-age=XXXXXXXXXsec を付与すればブラウザ側でキャッシュしてくれます。Nginxなら設定に`expires 30d;` と設定するだけで大丈夫です。


# 6. SEO対策
SEO対策が成功すると、GoogleやYahooからより多くの検索トラフィックが発生してユーザの目に止まる機会が増えます。SEO対策と書いてありますがGoogle様は優秀です。良いコンテンツを作れば評価されます。SEO対策の多くはユーザビリティの向上に繋がる施策も多いため積極的に取り組みました。

## 6-1. PageSpeed Insights でページを改善
Google Developerで提供されているサービスです。使い方はURLを入力するだけ。指摘された項目を修正していきましょう。

- [Google Developer PageSpeed Insights](https://developers.google.com/speed/pagespeed/insights/)

![スクリーンショット 2016-01-05 17.35.18.png](https://qiita-image-store.s3.amazonaws.com/0/65312/bd3df1bc-48b3-fafa-1013-fde21aba6984.png)

## 6-2. クローラー最適化する
全てのコンテンツへリンクは繋がっていますか？リンクが切れていると検索エンジンのクローラーが辿れなくなるため検索Indexに登録されません。

## 6-3. HTMLヘッダー設定
トップページには、この3つのMETAタグを設定しましょう。`META KEYWORD` は取り組みたい人だけ取り組めばいいと思います。

```html:HTMLヘッダー設定（トップページ）
<!-- サイトの正式なURLを伝えるmetaタグ -->
<meta name="Identifier-URL" content="http://www.example.com/" />

<!-- ページの要約を伝えるmetaタグ（検索エンジンに表示される） -->
<meta content="My Web Service" name="title">
<meta content="このサイトはMy Web Serviceという名前でほげほげー" name="description">
```

```html:HTMLヘッダー設定（その他のページ）
<!-- サイトの正式なURLを伝えるmetaタグ -->
<meta name="Identifier-URL" content="http://www.example.com/" />
```

# 7. コピーサイト対策
魚拓ではありませんが昔サイトを全コピーされたことがあるので個人的には必須の項目です。コピーサイトが発生してからでは遅いです。導入はjs入れるだけでok。副次効果としてIP直打ちでアクセスされた際も正しいURLにリダイレクトされます。jQueryでホスト名を取って設定値と異なっている場合は特定ページにリダイレクトする仕組みです。

- [Web魚拓が作られた時に、魚拓内容を書き換え強制リダイレクトする](http://qiita.com/haminiku/items/506a47ab8c713a325358)

# 8. 検索エンジンへサイトを登録する
準備完了しました。いよいよサイト公開です。[Google Search Console](https://www.google.com/webmasters/tools/?hl=ja) にサイトを登録すれば数日でGoogleで公開されます。Googleで`site:http://your.site.com/` と入力して検索すれば登録されているか簡単に確認できます。

## 8-1. Yahooには登録しない
Google Search Consoleに登録すると、勝手にYahooからも検索トラフィックが発生するので、何もやらなくて大丈夫だと思います。

![スクリーンショット 2016-01-05 18.04.16.png](https://qiita-image-store.s3.amazonaws.com/0/65312/010f2220-a8a1-2d95-5b2e-4b43b961b973.png)


# 9. 運用する
メモ程度で構わないので運用日誌を書いておくと、1ヶ月後に輝きます。誰にも見せなくていいので簡単に書いていこう

```txt:運用日誌
2016/1/4 09:00 自動更新機能が3日止まっていることを確認
2016/1/4 09:30 自動更新機能を深夜に1日1回再起動するように設定した
2016/1/4 19:50 レコメンド機能をリリース
2016/1/4 19:55 アクセス障害5分 pip install pytz忘れ
2016/1/5 22:00 とある機能のページでアクセス障害3件発生。バグ修正した
```

# 10. 独りで開発を進めるための開発手法
独りで開発する際の問題の多くは、プランナーと開発者が同じ人物であることによって引き起こされていると感じています。

プランナーはどんどんやりたいことを提案するのですが、開発者のリソースが不足して開発が止まってしまったり、仕様が決まってないまま開発を進めた結果、試行錯誤と手戻りを繰り返しすことになってしまいがちです。

この問題を完全に解決することはとても難しいです。私は簡単な開発タスクリストを作成して機能毎に開発優先度を割り振ることでこの問題の解消を図ってみました。プランニングタスクと開発タスクを出来るだけ分離しないと、めんどくさくなって途中で挫折してしまうことが多いです。


```txt:開発タスクリスト
# ToDo(やること)
論理削除する機能
クローラーがrobots.txtにアクセスしてエラー出てる
/tmp/log/ にログ吐くのを/var/logに変更する
サイトの死活監視ツールを開発

# Done(対応済み)
バグ:メインコンテンツとレコメンドコンテンツで重複が発生している
次へボタンを付ける
トップ画像がいけてないので差し替える
CSSバグ:トップページの右上の黒い正方形を消す
```


# 11. 開発して便利だったツール
作ってよかったーと後々思ったコマンド

## 11-1. deployコマンド
1コマンドでdeployできるコマンドです。中身はsshでめっちゃ頑張っています。

```shell-session:deploy.sh
ssh -l root conoha "date"
ssh -l root conoha "cd /hoge && git pull origin master"
# webサーバ再起動
ssh -l root conoha "/usr/bin/supervisorctl -c /etc/supervisord.conf restart gunicorn"
```

## 11-2. 本番テストコマンド
実機確認めんどうだったので作りました。deployコマンドに組み込んでいます。

- [ページ内のリンク切れ確認を行うテストコード](http://qiita.com/haminiku/items/227489e7a9ade9167fb1)

## 11-3. 画像圧縮変換ツール
pngを同名のjpgに一括で変換するツールです。PILを使ったこちらの記事が参考になると思います。

- [Python - アンチエイリアスで写真をキレイに縮小](http://qiita.com/haminiku/items/e53aa1d9bda77d2efe28)

## 11-4. WEBサーバ死亡時にSlack通知ツール
これまだ作ってなくてToDoに入ったままです。cronで実行してサーバ落ちてたらslackで通知したい...


# 12. さいごに
新規WEBサービス構築には幅広い知識が必要です。裏を返すと、やりきれれば失敗したって必ずWEBエンジニアとして良い経験が得られるはずです。一緒にがんばりましょう！



-------------------------------------------
# 13. 2ヶ月後の追記
結論だけ、書く。 失敗した失敗した失敗した失敗した失敗した失敗した失敗した失敗した 失敗した失敗した失敗した失敗した失敗した失敗した失敗した失敗した失敗した失敗した

- [ウィルス感染でWebサービスが20日間ダウン。本当にごめんなさい](http://qiita.com/haminiku/items/646124c1ee5d0dd73064)