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

Post on 30-Jun-2015

15.940 Views

Category:

Documents

3 Downloads

Preview:

Click to see full reader

TRANSCRIPT

株式会社はてなの開発戦略

株式会社はてな

舘野祐一

自己紹介

舘野祐一 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レポジトリ

壊れた\(^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)

commit = @grit.commit(newrev)

# ...

irc.post('git', message)

13:29:43 gittan:

[projects/hatena-bookmark]

yuichi tateno: ヘッダ色固定https://git.local.hatena.ne.jp/git/projects/ha

tena-bookmark/commit/71abae8949b

ブランチと連動したドメイン作成

git のブランチをリモートに push

開発サーバのドメインとブランチ

をひも付け

http://mobiletest.local.hatena.ne.jp/

$ git checkout mobile

# カスタム capistrano タスクを実行$ cap @vhost

vhost:auto_create:mobiletest

テスト用ドメイン?

なんで作成するの?

本番サーバと同じ環境 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

MVACModel / 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 ->

mysqldumpYAML のタイムスタンプが変更無い

mysqldump のデータ insert 一行

fixture テストが 10秒→4秒に

全体のテストも 10分→6分に life-changing

まとめ

こんな感じでリニューアル開発適度な抽象化

適度なテスト

終わりに

全体の開発環境を向上させるストレスレスで開発したい!

開発しやすい環境も重要

楽しい開発を!

ご静聴ありがとうございました

top related