Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
株式会社はてなの開発戦略
   株式会社はてな
    舘野祐一
自己紹介
舘野祐一
          id:secondlife


はてなブックマークリードプログラマ
 Perl,   JavaScript ...
社内開発環境の整備
 開発環境改善大好き!
 Development      Environment Conference 開い
たり
アジェンダ
最近のはてなでの開発
はてなブックマーク・リニューアル
への道
最近のはてな
従業員数60名(アルバイト含む)
うち、エンジニア30名
 インフラ8名、アプリケーション22名

結構な規模に
一年間で・・・
開発の変化
2008年・大きな変化が
一言で言うと…
git
そもそも git とは
分散 VCS
 好きなだけレポジトリの複製
 どこからでもコミット

(svn と比べて)動作が高速
低コストなブランチ作成
賢いマージ
SHA1 によるデータ管理
 リビジョン1000などという概念はない
単一?分散?
単一レポジトリ
 レポジトリが中央に一つ
 基本的に誰でもチェックアウト可能
 コミットには権限が必要

分散
 レポジトリを誰でも複製(clone ) 可能
 もちろん複製したレポジトリにコミット可能
 大本のレポジトリの反映 ( push )には権限
2008年初頭・世の中git 期
Rails などが git に移行
      の出現

 以前は分散 VCS 難しそう…と
 これを気に使ってみる
git を使ってみた
[これはべんり]
 コミットしてリモートに即反映とか怖い!
 ブランチ作成一瞬
 ちょくちょくコミット→安心感
 仕事でも       git-svn を使うように
git ベンリスwww
 git   厨期
数年後は分散VCSが主流な予感
しかし…
実際に業務で使うか?
 cvs/svn   に比べて操作難しい
    たくさんのコマンド
 分散の概念の理解
    リモート?ローカル?はたまた別のレポジトリ?
 windows   の GUI クライアントがない
    デザイナー・ディレクターに使ってもらうには酷
 業務への導入はまだまだ先かな
git への道
svn から git へ…
はてなが git へ移行できた
  たった一つの方法
時は
2008年
 4月末
SVN
レポジトリ
デブサミ2009 はてなの開発戦略
壊れた
(^o^)/
\(^o^)/
\(^o^)/
\(^o^)/
\(^o^)/
\(^o^)/\(^o^)/
\(^o^)/\(^o^)/
\(^o^)/\(^o^)/
\(^o^)/\(^o^)/
     r35000
\(^o^)/\(^o^)/
\(^o^)/\(^o^)/
\(^o^)/\(^o^)/
\(^o^)/\(^o^)/
svn レポジトリが壊れた!
まさかのレポジトリ破壊
チェックアウト・コミットできない
デプロイできない
 capistrano   経由の svn up デプロイ
このときは ssh + rsync で転送
 死ぬる…
復旧できなかったの?
RAID 1 でレポジトリを運用
片方の HDD が物理的に壊れる
もう片方の FSFS ( svn のレポジ
トリDB ) も一部壊れる(壊れてた)
特定リビジョン・特定ファイルが取
り出せない
svnadmin 等で復旧試みるも無理
どうしよう…
もういちどまっさらなSVNを構築?
git に移行すべき?
 git
   で運用できそうなら git に
 現在の svn システムを移行できるか調査
git への移行は可能か
デプロイ
 capistrano
       2.2 で git 対応
 レシピ書き換えればできる

svn からの移行
 git-svn   で、ディレクトリ単位のコンバートが
可能
 リビジョンの指定が可能
    壊れているリビジョンを飛ばし,コンバート可能
git から svn へ
 svn からのデータコンバート
  git-svn   で驚くほど簡単に
 デプロイ
  capistrano
          にちょっと手を入れレシピ書き
  svn と比べ、デプロイ速度が1000%ぐらい高
 速に(当社調べ)
構成の変更
svn
      プロジェクトすべて一つのレポジトリ
git
      プロジェクトごとに細かく作成
はてな開発での一番のメリット
ブランチ
 ブランチ作成速度・一瞬
 ディレクトリ変更無しにブランチ切り替え
    ファイルパス変更いらず

 svn   の頃は作成面倒・切り替え重い…
        実用的でない
 いかにスムーズに開発可能かが重要
ブランチ作成ポリシー
origin/master
 本番デプロイファイルのみ

origin/機能ごとのブランチ名
 機能ごとにブランチを作成

ローカルでは適宜ブランチ作成
 リモートには反映されないのでどんどん
ブランチとコードレビュー
適宜コードレビュー
 ブランチを切ることで、簡単に追いかけられ
る
git でのコードレビュー
 git   diff master...branchname
 '...' で、共通の親からの変更点を表示
はてなでのgit 開発の流れ
git checkout -b example
コード書いて適宜 git commit
    リモートにブランチ反映したい / git-publish-branch

    リモートからブランチに反映 / git pull か git pull --rebase


git diff master...example
master に反映
    git merge master # master からマージ, コンフリクト解決

    git checkout master

    git merge example # example から master へマージ

      コンフリクト発生を防ぐ
git 運用はスムーズか?
やっぱり git 難しい
 覚えるコストが        svn と比べて高い
 よく嵌る
 誤った方法でリポジトリ変更・           push すると悲
惨に
     master に merge するときコンフリクト祭り
windows クライアント無い
 デザイナ・ディレクタが         VMWare+Linux から..
 TortoiseGit   に期待
git を利用したツール
git に移行ついでにいろいろ作成
 gitフックフレームワーク
 branch と連動したバーチャルドメイン作成
 ネオあしか
git フックフレームワーク
svn でのフックスクリプト
 すべて一つのレポジトリで運用
 一つ書けば   OK
git では
 プロジェクトごとに別レポジトリ
 git
   レポジトリをサーバに作成時に hooks/*
ファイルを symlink
git フックフレームワーク
すべてレポジトリを監視
 push   などの変更により実行
特定レポジトリのみフック
 WebAPI   を叩いてサーバをリロードなど
projects/Bookmark に push
 以下のスクリプトが実行
    /globals/update/*
    /projects/Bookmark/*
スクリプト例
 社内IRCにコミットを知らせる
module Grit::Hooks
class PostIrc < Hook
 def execute(refname, oldrev, newrev)
 13:29:43 gittan:
  commit = @grit.commit(newrev)
 [projects/hatena-bookmark]
  # ...
 yuichi tateno: ヘッダ色固定
  irc.post('git', message)
 https://git.local.hatena.ne.jp/git/projects/ha
 tena-bookmark/commit/71abae8949b
ブランチと連動したドメイン作成
 git のブランチをリモートに push
 開発サーバのドメインとブランチ
 をひも付け
$ git checkout mobile
# カスタム capistrano タスクを実行
$ cap @vhost
vhost:auto_create:mobiletest

 http://mobiletest.local.hatena.ne.jp/
テスト用ドメイン?
なんで作成するの?
本番サーバと同じ環境
 apache/mod_perl/ディストリビューション

外部ネットワークからの閲覧
 誰でもUI や機能の確認に
 全員がすべてのプロジェクトをローカルで動
かせる訳ではない
ネオあしか
タスク管理システム
 git   やはてなアイデアと連携
Rails + git-ruby
ネオあしか
開発の経緯
 git ブラウザ欲しい
 チケット管理システムほしい
しっくりくる物が見つからない
 社内用途にマッチした機能で実装
基本機能
チケット登録
 担当者・タグ・期限・優先度・etc...

アイデア連携
 はてなアイデアからの連携
git ブラウザ
複数人コミット前提のインターフェイス
github ブラウザで使いにくい点を改良
git ブラウザ
URL を git コマンドっぽく
 /bookmark/diff/HEAD..HEAD~
 /bookmark/diff/e87bb6f3...81f0d24ec2b
git コミットと連携
コミットログに [#1000] とタスク番
号を
自動でタスクとひも付く
 gitフックフレームワークで一括処理

タスク <-> コミットのひも付け
git サーバ運用
git サーバを建てる
 読みこみ   / git-daemon
  高速
  git submodule (svn:externals のような) の参照
  もこちらに
 書き込み   / sshd
git サーバ運用
git ユーザを作ろう
 git@hostname:/projects/path
 パーミション周りの問題のため

git ユーザ管理
 ~/.ssh/authrized_keys   でユーザ管理
git ユーザのログインシェル
 git-shell   ・git 関係のコマンドのみ通してくれ
るシェル
まとめ
git 導入から始まり、とても便利に
 git   のブランチ最高
      svn でも同じことができる・けど実運用に耐
    えれるかどうかが重要
 はてなアイデア・あしか・git

git の導入コストは高い
 そんなにオススメはしない
 けど、分散VCS の波はもう来ている
 今のうちに使っておくのは吉
はてなブックマーク
リニューアルへの道
はてなブックマーク
ソーシャルブックマークサービス
ユーザ数
 21.6万

ページビュー
 790万pv/日

サーバ台数
 約50台
はてなブックマーク
2008年 11月末リニューアル
開発期間約9ヶ月
       20 08年 8月からコミット
自分は

8月から専属の開発メンバー4人
現在5人
diff hatebu1..hatebu2
 デザイン刷新
 ユーザインターフェイス改善
 検索機能
 お気に入り強化
 カテゴリ刷新
リニューアル?
本当にフルスクラッチでリニュー
アルする必要は?
旧サービス問題点振り返り
旧システム問題点
保守性・拡張性
テスタビリティ
他サービスとの密結合
保守性・拡張性の問題
2002年に作られたはてなフレーム
ワークを利用
今使うにはちょっと古い設計
 クラス継承ベースでのコントローラの実装
 一つの機能を使いたいがために多重継承
 継承しすぎ   or コピペしすぎ
 冗長な view へのマッパクラスの作成
保守性・拡張性の問題解決
Ridge (社内フレームワーク) の利
用
 Rails/Catalyst   ライクな軽量 WAF
MVC -> MVAC
テスタビリティ問題
はてなフレームワーク
 テスト考慮されてない

旧ブックマーク
 ほとんどテスト無い
テスタビリティの解決
Ridge/MoCoでテストが書きやすく
移行部分の機能の仕様は確定
 そこは完全に   TDD
新機能
 テストが実装の後になる場合も

MVAC の MA を重点的にテスト
他サービスとの密結合問題
サービス拡張による密結合
DB から直接
 データ加工などの実装が必要

他サービスの Perl コードを利用
 ライブラリ依存問題
他サービスとの密結合解決
祖結合
WebAPI利用
 RSS
 JSON
既存の MVC の問題点
ORM に処理が集中
 データソースが   RDB だけならまだ良い
他のデータソースを扱う場合は?
 適当にクラス作成?
 コントローラに実装?
MVAC
MVAC
 Model   / View / Applicaiont / Controller
アプリケーションレイヤの作成
 コントローラとモデルの間に挟んで抽象化
はてなブックマークでは
 データソース層
 サービス層
 アプリケーション層
という3層構造
データソース層
ORM のクラス
 基本的な機能
 リレーション情報
サービス層
 ドメインロジックの実装
 例:人気エントリーの取得
my $service = H::B::S::Hotentry->new;
$service->threshold(5);
$service->category('life');
my $entries = $service->entries(0, 10);
// 10件取得
アプリケーション層
 サービス層を利用して実装
 ページャの作成・キャッシュ操作など
my $app = H::B::A::Hotentry::Top->new;
$app->show_detail = 1;
# view で必要な項目なども設定
$app->offset(0);
$app->limit(10);
my $entries = $app->entries;
my $pager = $app->pager;
冗長?
サービス・アプリケーションと分け
るのは冗長?
アプリケーションはビューとのつな
ぎ込み
サービスはドメインロジック
 CUI   アプリも簡単に作れるように
フレームワークを切り離す
さきほどの3層は、WAF を一切利
用していない
単体テストが断然書きやすく
WAF では
 URL/コントローラ/ビューのマッピングのみ
 コントローラでクエリパラメータをアプリ・サー
ビスにマッピング
リニューアル開発
当初・id:naoya が一人で
 黙々とテスト・実装

後半・多人数開発
 ポストイット     + ホワイトボード
        ポストイット便利
 git   を利用しての機能開発
        master はテストが通ったコードのみ
        コードレビュー
スケジューリング
社内スケジュール通り
ただ、最後はテストがおろそかに..
リリース直後の高速化などでどた
ばた
 実はリリース直後、全テスト通ってなかった
  教訓を得た
テストが青い
全部通る!気持ちよい!
こんなにテストがあるよ
 ならきちんとテスト書かないと
 やたーテスト増えたよ
テストが赤いと
全部テスト通らない!やる気が…
 このテスト通らないの自分のせいじゃないし..

別にテスト増やさなくていいかな…
テスト赤い→やる気でない→テス
ト書かない→赤い
負のスパイラル
現在は
 100 個以上のテストファイル
 2000 個以上のアサーション
all tests successful.
files=103, tests=2077, 327 wallclock secs
( 1.81 usr 0.59 sys + 170.40 cusr 110.59
csys = 283.39 cpu)
result: pass
「テストの」高速化
テスト時間
 以前は合計10分強
 1テストでも、fixture   (DB) を使うと10秒ほど
テスト実行時間がストレスに
 もっとさくっと終わって欲しい!
fixture の高速化
YAML -> ORM -> RDB
 数百件のデータを     ORM 経由で insert
 遅い
 テストメソッドごとに走る

テスト -> 実装 -> テスト -> 実装
 テストの時間   MOTTAINAI !
局所高速化
YAML -> ORM -> RDB ->
mysqldump
 YAML  のタイムスタンプが変更無い
 mysqldump のデータ insert 一行

fixture テストが 10秒→4秒に
全体のテストも 10分→6分に
 life-changing
まとめ
こんな感じでリニューアル開発
 適度な抽象化
 適度なテスト
終わりに
全体の開発環境を向上させる
 ストレスレスで開発したい!
 開発しやすい環境も重要
 楽しい開発を!
ご静聴ありがとうございました

More Related Content

デブサミ2009 はてなの開発戦略