SlideShare a Scribd company logo
初心者エンジニア
      の
   システム構築
     失敗談
              @Spring_MT

13年1月14日月曜日
Profile

13年1月14日月曜日
@Spring_MT
              Engineer




13年1月14日月曜日
13年1月14日月曜日
福岡RRuubbyy会議0011




13年1月14日月曜日
福岡RRuubbyy会議0011




13年1月14日月曜日
初心者エンジニア
      の
   システム構築
     失敗談
              @Spring_MT

13年1月14日月曜日
初心者??

13年1月14日月曜日
・前職でエンジニアに転向�
             その前までは一切コード書いてないんです。。。
             営業とかもやってたんですよ

       ・エンジニア歴  22年半くらい
       ・ruby歴はちょうど一年


13年1月14日月曜日
なので
         ・gitしか使ったことない......
         ・utf8しかしらない........



13年1月14日月曜日
エンジニア
                の
              ゆとり世代
13年1月14日月曜日
前の環境

13年1月14日月曜日
言語
              フレームワーク
                    perl
               独自フレームワーク
              テストはあんまりない  >>__<<

13年1月14日月曜日
DDBB関連
                databaseは複数
                joinは基本しない
                 masterとslave
              autoincrement使わない

13年1月14日月曜日
新しい環境

13年1月14日月曜日
なんもない。。。。




13年1月14日月曜日
13年1月14日月曜日
00からスタート

13年1月14日月曜日
フレームワーク

13年1月14日月曜日
・テスト周�りの環境が揃っ
      てる
      ・新しくjoinする人((学生
      含めて))の学習コストが低い


13年1月14日月曜日
Rails

13年1月14日月曜日
実際は
              やってみた
              かっただけ
13年1月14日月曜日
Rails
                 で
              アプリ作る
13年1月14日月曜日
はじめの一歩

13年1月14日月曜日
課題

13年1月14日月曜日
・複数DB対応
        ・master	
  slave振り分け
        ・採番(sequence)

        ・belongs_toの扱い


13年1月14日月曜日
えっ。。。

13年1月14日月曜日
いきなり大きいこと考えすぎ

   でもこの時は必要だと思ったんで
   す。。。。


13年1月14日月曜日
大規模病  
               >>__<<
13年1月14日月曜日
複数DBの対応
master・slave振り分け


13年1月14日月曜日
方針
        ・DB  +  master、slave毎に
      Modelのクラスを作る
        ・Controllerで明示的にDBア
      クセス先を指定する

13年1月14日月曜日
class	
  TestMasterShard	
  <	
  ActiveRecord::Base
 	
  	
  self.abstract_class	
  =	
  true
 	
  	
  establish_connection	
  "#{ENV['RAILS_ENV']}_test_master"
 end


 class	
  FooMaster	
  <	
  TestMasterShard
 	
  	
  self.table_name	
  =	
  'foo'
 	
  	
  attr_accessible	
  :name
 	
  	
  validates	
  :content_id,	
  {presence:	
  true}
 end




13年1月14日月曜日
octopus
     ・テストではまる
     ・明示的に書いたほうがトラブ
     ルが少なそう



13年1月14日月曜日
 	
  #	
  config.include	
  RSpec::Octopus
	
  	
  config.before	
  do
	
  	
  	
  	
  shards	
  =	
  ActiveRecord::Base.connection_proxy.instance_variable_get(:@shard
	
  	
  	
  	
  @connections	
  =	
  shards.values.map(&:connection)
	
  	
  	
  	
  @connections.each	
  do	
  |connection|
	
  	
  	
  	
  	
  	
  connection.increment_open_transactions
	
  	
  	
  	
  	
  	
  connection.transaction_joinable	
  =	
  false
	
  	
  	
  	
  	
  	
  connection.begin_db_transaction
	
  	
  	
  	
  end
	
  	
  end

	
  	
  config.after	
  do
	
  	
  	
  	
  @connections.each	
  do	
  |connection|
	
  	
  	
  	
  	
  	
  if	
  connection.open_transactions	
  !=	
  0
	
  	
  	
  	
  	
  	
  	
  	
  connection.rollback_db_transaction
	
  	
  	
  	
  	
  	
  	
  	
  connection.decrement_open_transactions
	
  	
  	
  	
  	
  	
  end
	
  	
  	
  	
  end
	
  	
  end




13年1月14日月曜日
View


              Controller             Model

               UserController   UserMaster    master

                                UserSlave
                                              slave
               FeedController

                                FeedMaster    master

                                FeedSlave
                                              slave
              GroupController


                                GroupMaster   master

                                GroupSlave
                                              slave

13年1月14日月曜日
採番
              sequence

13年1月14日月曜日
方針
      アプリ内で一意のIDを発行する




13年1月14日月曜日
・IDがわかれば、それに紐付
       くデータが一意に決まる

       ・重複が起きない
       ex))  user_id  ++  コンテンツ
       ((feed	
  or	
  image	
  or	
  ...))のID

13年1月14日月曜日
class	
  Sequence	
  <	
  SequenceShard
	
  	
  self.table_name	
  =	
  'seq'

	
  	
  def	
  self.generate(model)
	
  	
  	
  	
  result	
  =	
  self.connection.execute(
	
  	
  	
  	
  	
  	
  "UPDATE	
  seq	
  SET	
  id=LAST_INSERT_ID(id+1)"
	
  	
  	
  	
  )
	
  	
  	
  	
  id	
  =	
  self.connection.last_inserted_id(result)	
  
                      or	
  raise	
  RuntimeError
	
  	
  	
  	
  return	
  id
	
  	
  end

end


13年1月14日月曜日
belongs_to

13年1月14日月曜日
方針
         今回は複数DBを想定したので
         使わないことにしました>>__<<




13年1月14日月曜日
課題
         ・Controllerからはmaster  
         slaveを意識せずに使いたい



13年1月14日月曜日
いきなりこの時点でスケール
         を考えている。。。
         そもそも考慮する必要があっ
         たのか?



13年1月14日月曜日
自分で見えない敵を作って
         た。。。




13年1月14日月曜日
大規模病  
               >>__<<
13年1月14日月曜日
第二期

13年1月14日月曜日
課題
         ・Controllerからはmaster  
         slaveを意識せずに使いたい



13年1月14日月曜日
方針
   ・モデルを2つに分ける
           **    データベースとテーブル
   の抽象化((masterとslave毎にク
   ラスがある))
           **    master/slaveの抽象化

13年1月14日月曜日
View


              Controller                     Model

                                 Logic                 Data

               UserController   UserLogic            UserMaster    master

                                                     UserSlave
                                                                   slave
               FeedController

                                FeedLogic            FeedMaster    master

                                                     FeedSlave

              GroupController                                      slave


                                GroupLogic           GroupMaster   master
                                                     GroupSlave

                                                                   slave
13年1月14日月曜日
Model	
  Data
      ・DBへのアクセスを管理する層
      ・connectionの設定、SQLを管
      理のみ


13年1月14日月曜日
class	
  TestMasterShard	
  <	
  ActiveRecord::Base
	
  	
  self.abstract_class	
  =	
  true
	
  	
  establish_connection	
  "#{ENV['RAILS_ENV']}_test_master"
end



                                        1
class	
  FooMaster	
  <	
  TestMasterShard
	
  	
  self.table_name	
  =	
  'foo'
	
  	
  attr_accessible	
  :name
	
  	
  validates	
  :content_id,	
  {presence:	
  true}

	
  	
  default_scope	
  where(is_deleted:	
  0)
	
  	
  scope	
  :hoge,	
  lambda	
  {	
  |foo|	
  where('bar	
  =	
  ?',	
  bar)	
  }
end



13年1月14日月曜日
Model	
  Logic
         ・Model  Dataを用いて、
         master/slaveの処理をまと
         める層


13年1月14日月曜日
class	
  BaseLogic
 	
  	
  include	
  ActiveModel::MassAssignmentSecurity
 	
  	
  include	
  ActiveRecord::AttributeAssignment
 	
  	
  include	
  ActiveModel::Conversion
 	
  	
  include	
  ActiveModel::Validations
 	
  	
  extend	
  ActiveModel::Naming
 	
  	
  extend	
  ActiveModel::Translation

 	
  	
  def	
  persisted?;	
  false;	
  end
 end

class	
  TestLogic	
  <	
  BaseLogic
	
  	
  attr_accessor	
  :foo
	
  	
  attr_accessible	
  :foo	
  	
  

	
  	
  def	
  get_test_one
	
  	
  	
  	
  TestSlave.get_one
	
  	
  end
end
13年1月14日月曜日
View


              Controller                     Model

                                 Logic                 Data

               UserController   UserLogic            UserMaster    master

                                                     UserSlave
                                                                   slave
               FeedController

                                FeedLogic            FeedMaster    master

                                                     FeedSlave

              GroupController                                      slave


                                GroupLogic           GroupMaster   master
                                                     GroupSlave

                                                                   slave
13年1月14日月曜日
課題
  ・複数のテーブルをまたいでデー
  タを処理する場合、どこにその処
  理を書くのかが不定
  (Model	
  Logic	
  or	
  Controller)


13年1月14日月曜日
現在

13年1月14日月曜日
課題
  ・複数のテーブルをまたいでデー
  タを処理する場合、どこにその処
  理を書くのかが不定
  (Model	
  Logic	
  or	
  Controller)


13年1月14日月曜日
方針
    ControllerとModelの間に一層
    ((Context))を追加

    サービス層に近い

13年1月14日月曜日
View           ユーザーのしたいこと          DBのデータを適切な
                      を実現する処理の流れ          形で受け渡すのみ


   Controller           Context                  Model

                                         Logic           Data
     UserController     UserContext
                                       UserLogic     UserMaster    master

                                                     UserSlave
     FeedController     FeedContext                                slave


                                       FeedLogic     FeedMaster    master

    GroupController                                  FeedSlave
                        GroupContext
                                                                   slave


                                       GroupLogic    GroupMaster   master
                                                     GroupSlave
                                                                   slave
13年1月14日月曜日
Model  Data

      ・DBへのアクセスを管理する層
      ・connectionの設定、SQLを管
      理するだけに留める


13年1月14日月曜日
Model  Logic
         ・Data層をコントロールする
         層
         ・一つのテーブルに一つ
         ・受け持つテーブルのデータ
         の処理に関してのみ責任を負
         う
13年1月14日月曜日
Context
         ・  ユーザーのしたいことを
         実現するための処理の流れを
         実装する  
             -->>ユーザが操作する内容ご
         とに実装
         ・Controllerと11::11対応さ
         せる
13年1月14日月曜日
Controller
         ・Contextで作成されたデー
         タをViewに受け渡す

        cellsを使って、uriで表現されている処理のみを実
        装するようにしている
13年1月14日月曜日
View
         ・データを描画する
         ・ここにロジックは書かない



13年1月14日月曜日
View           ユーザーのしたいこと          DBのデータを適切な
                      を実現する処理の流れ          形で受け渡すのみ


   Controller           Context                  Model

                                         Logic           Data
     UserController     UserContext
                                       UserLogic     UserMaster    master

                                                     UserSlave
     FeedController     FeedContext                                slave


                                       FeedLogic     FeedMaster    master

    GroupController                                  FeedSlave
                        GroupContext
                                                                   slave


                                       GroupLogic    GroupMaster   master
                                                     GroupSlave
                                                                   slave
13年1月14日月曜日
課題

         ・validationをどうする?



13年1月14日月曜日
Validation

13年1月14日月曜日
・Railsは22つのvalidation
         が一緒になってる




13年1月14日月曜日
・ユーザーが入�力した値の
         チェック
         ・DBに格納する前のデータの
         チェック



13年1月14日月曜日
今の構成

13年1月14日月曜日
View           ユーザーのしたいこと          DBのデータを適切な
                      を実現する処理の流れ          形で受け渡すのみ


   Controller           Context                  Model

                                         Logic           Data
     UserController     UserContext
                                       UserLogic     UserMaster    master

                                                     UserSlave
     FeedController     FeedContext                                slave


                                       FeedLogic     FeedMaster    master

    GroupController                                  FeedSlave
                        GroupContext
                                                                   slave


                                       GroupLogic    GroupMaster   master
                                                     GroupSlave
                                                                   slave
13年1月14日月曜日
Contextが入�ったことで
 validationでエラーが起きた時
 のARオブジェクトの受け渡しをど
 うするか?


13年1月14日月曜日
Contextでは複数のARオブジェ
      クトが格納されて、その中から
      validationエラーをまとめ
      る。。。。



13年1月14日月曜日
正直面倒

13年1月14日月曜日
Validation
         ・ユーザーが入�力した値の
         チェック
         ・DBに格納する前のデータの
         チェック


13年1月14日月曜日
分ける!

13年1月14日月曜日
DBに格納する前のデータ
              のチェック


              今まで通りARの
              validateを使う

13年1月14日月曜日
ユーザーが入�力した値の
                  チェック



                   ??

13年1月14日月曜日
ユーザーが入�力した値の
                  チェック

               リクエストを
              受けとった直後が
                望ましい
13年1月14日月曜日
controllerの
              before_filterで
              やる

13年1月14日月曜日
・ユーザーが入�力した値のチェック  
    ==>>  Controllerのbefore_filter
・DBに格納する前のデータのチェック
    ==>>  Model


13年1月14日月曜日
before_filter
              で
          Validation
13年1月14日月曜日
DataValidator
               を書きました

13年1月14日月曜日
13年1月14日月曜日
DataValidator

         ARのvalidatorとほぼ同じバ
         リデーションロジックを実装
         しています


13年1月14日月曜日
params	
  =	
  {foo:	
  'foo',	
  bar:	
  'bar'}

  validator	
  =	
  DataValidator::Validator.new(
  	
  	
  params,
  	
  	
  {foo:	
  {length:	
  {is:	
  4}}},
  	
  	
  {bar:	
  {presence:	
  true,	
  format:	
  {with:	
  /A[a-­‐zA-­‐Z]+z/}}}
  )

  unless	
  validator.valid?
  	
  	
  @errors	
  =	
  validator.errors
  end

  @errors
  =>	
  {
  	
  	
  foo:	
  ["is	
  the	
  wrong	
  length	
  (should	
  be	
  4	
  characters)"],
  	
  	
  bar:	
  ["can't	
  be	
  blank",	
  "is	
  invalid"]
  }



13年1月14日月曜日
・ユーザーの入�力値  
           ==>>  Controllerのアクション
         毎にDataValidatorを使う
         ・DBに格納する値
             ==>>  ModelでActiveRecord
         を使う

13年1月14日月曜日
Controllerでvalidationし
         た後は、ユーザーの入�力値は
         正しい値としてみなし、DBに
         入�れる値をチェックする時に
         エラーになった場合はシステ
         ムのエラーとみなし例外で落
         とす

13年1月14日月曜日
View                         ユーザーのしたいこと                         DDBBのデータを適切な
                                      を実現する処理の流れ                         形で受け渡すのみ



   Controller                           Context                                     Model

                                                                      Logic                    Data
       UUsseerrCCoonnttrroolllleerr      UUsseerrCCoonntteexxtt

    VVaalliiddaattoorr
                                                                   UUsseerrLLooggiicc     UUsseerrMMaasstteerr     mmaasstteerr

                                                                                           UUsseerrSSllaavvee
      FFeeeeddCCoonnttrroolllleerr      FFeeeeddCCoonntteexxtt                                                      ssllaavvee
    VVaalliiddaattoorr

                                                                   FFeeeeddLLooggiicc     FFeeeeddMMaasstteerr     mmaasstteerr

     GGrroouuppCCoonnttrroolllleerr                                                        FFeeeeddSSllaavvee
                                        GGrroouuppCCoonntteexxtt
                                                                                                                    ssllaavvee
    VVaalliiddaattoorr


                                                                   GGrroouuppLLooggiicc   GGrroouuppMMaasstteerr   mmaasstteerr
                                                                                           GGrroouuppSSllaavvee

                                                                                                                    ssllaavvee
13年1月14日月曜日
・この構成で落ち着いてます
       ・これ以上は手を入�れない予定




13年1月14日月曜日
Railsやめ
       ちゃいなよっ
       てつっこみは
       なしです>>__<<
13年1月14日月曜日
gem
  ・data_validator
  ・rack_session_redis_store
  ・redis_json_serializer


13年1月14日月曜日
ご清聴
          ありがとうご
          ざいました!
13年1月14日月曜日
時間があれば。。。。




13年1月14日月曜日
画像・ファイル
 ストレージ
13年1月14日月曜日
・分散ファイルシステムを自
         前で作る?
         ・色々なアプリでAPIちっく
         に使いたい



13年1月14日月曜日
画像・ファイル
AWS VPC
                 ストレージ
                App(RoR)              ・sinatraでappは作
                     HTTP             成
                 Nginx                ・閲覧権限等は本体で
                                      管理
     varnish               varnish    ・自前で分散ファイル
                                      システム構築は難しい
      sinatra               sinatra   のでS3を使用
        app                   app

                                      ・Storage	
  Proxyパ
                           S3         ターン
13年1月14日月曜日
サーバー構成

13年1月14日月曜日
オールAWS!

13年1月14日月曜日
public

                       subnet
                       net work

                             Gateway                      NAT
                                           SSLの変換


        subnet                                                             subnet       subnet
                        subnet                                             fluentd
        utility                                                                         storage
                        ser vice
                                                                        deliver      proxy
                       APP
    Watch
                                                                redis
                        f              f              f
                                                                        worker       varnish
                        DB                                                              +
                                                                                     sinatra


                             f                f            worker


                                   f              f




13年1月14日月曜日
その他
   ・session  storeにredis
   ・queue処理はfluentd  +  resque
   	
  	
  =>	
  http://spring-­‐mt.tumblr.com/post/35097726578/fluent-­‐plugin-­‐resque


   ・fluentd	
  +	
  GrowthForecastを
   使った集計と可視化
13年1月14日月曜日
13年1月14日月曜日

More Related Content

KEY
初心者エンジニアの システム構築 失敗談
KEY
Automation tech casual_talks_1_20120717
PPTX
20140518 JJUG MySQL Clsuter as NoSQL
PPT
Spring3.1概要 データアクセスとトランザクション処理
PDF
MySQL ガチBeginnerがやってみたことと反省したこと
PDF
What's New in MySQL 5.7 Optimizer @MySQL User Conference Tokyo 2015
PDF
DBスキーマもバージョン管理したい!
PDF
SpringMVCとmixer2で作るWebアプリのキホン 2013-01-24 Spring勉強会 #jsug
初心者エンジニアの システム構築 失敗談
Automation tech casual_talks_1_20120717
20140518 JJUG MySQL Clsuter as NoSQL
Spring3.1概要 データアクセスとトランザクション処理
MySQL ガチBeginnerがやってみたことと反省したこと
What's New in MySQL 5.7 Optimizer @MySQL User Conference Tokyo 2015
DBスキーマもバージョン管理したい!
SpringMVCとmixer2で作るWebアプリのキホン 2013-01-24 Spring勉強会 #jsug

What's hot (20)

PDF
Java Batch 仕様 (Public Review時点)
PDF
Groovyで楽にSQLを実行してみよう
PDF
Javaはどのように動くのか~スライドでわかるJVMの仕組み
PPTX
Java EE8 Report
PDF
MySQL de NoSQL Fukuoka
PDF
配布用Beginnerならきっと役立つmaster slave環境
KEY
My sql casual_in_fukuoka_vol1
PDF
PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12
PDF
MySQL日本語利用徹底入門
PDF
Introduction to JShell: the Java REPL Tool #jjug_ccc #ccc_ab4
PDF
なぜリアクティブは重要か #ScalaMatsuri
PDF
第2回 松本勉強会 2012 05 25 - apache2.4とmod_lua
PDF
MySQL 5.6新機能解説@dbtechshowcase2012
PDF
スマートフォン向けサービスにおけるサーバサイド設計入門
PDF
MHA for MySQLとDeNAのオープンソースの話
PDF
Using Chef for Infrastructure Automation of Ameba Pigg
PDF
PostgreSQLアーキテクチャ入門
PDF
Introducing MySQL MHA (JP/LT)
PDF
イマドキの現場で使えるJavaライブラリ事情
PPTX
Mod lua
Java Batch 仕様 (Public Review時点)
Groovyで楽にSQLを実行してみよう
Javaはどのように動くのか~スライドでわかるJVMの仕組み
Java EE8 Report
MySQL de NoSQL Fukuoka
配布用Beginnerならきっと役立つmaster slave環境
My sql casual_in_fukuoka_vol1
PHP in Java -Quercus- によるレガシーマイグレーション実例 #jjug_ccc #ccc_r12
MySQL日本語利用徹底入門
Introduction to JShell: the Java REPL Tool #jjug_ccc #ccc_ab4
なぜリアクティブは重要か #ScalaMatsuri
第2回 松本勉強会 2012 05 25 - apache2.4とmod_lua
MySQL 5.6新機能解説@dbtechshowcase2012
スマートフォン向けサービスにおけるサーバサイド設計入門
MHA for MySQLとDeNAのオープンソースの話
Using Chef for Infrastructure Automation of Ameba Pigg
PostgreSQLアーキテクチャ入門
Introducing MySQL MHA (JP/LT)
イマドキの現場で使えるJavaライブラリ事情
Mod lua
Ad

Viewers also liked (7)

PDF
Fluentd meetup #2
PDF
fluent-plugin-resque_stat
PDF
DB技術[実践]入門を読んだ
PDF
MySQL カジュアル 福岡 03
PDF
Fluentd in Co-Work
PDF
PayPal Big Data and MySQL Cluster
PDF
Fluentd Meetup #2 @外道父 Fluentdを優しく見守る監視事例
Fluentd meetup #2
fluent-plugin-resque_stat
DB技術[実践]入門を読んだ
MySQL カジュアル 福岡 03
Fluentd in Co-Work
PayPal Big Data and MySQL Cluster
Fluentd Meetup #2 @外道父 Fluentdを優しく見守る監視事例
Ad

Similar to 初心者エンジニアのシステム構築失敗談 (20)

KEY
Rails基礎講座 part.2
PDF
Weeklycms20120218
PDF
Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo
PDF
DDD 20121106 SEA Forum November
PDF
Heroku Postgres
PDF
PDF
20091030cakephphandson 02
PDF
ソーシャルゲームにおけるMongoDB適用事例 - Animal Land
PPTX
PDF
Rails初心者レッスン lesson2 3edition
PPTX
Tech fun rails_workshop
PDF
クラウド・アプリケーション・モデリングへのアプローチ
PDF
大規模ソーシャルゲーム開発から学んだPHP&MySQL実践テクニック
PDF
「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」
PDF
Ruby on Rails 入門
PDF
CodeIgniter入門
PDF
MySQL Casual な生活
PDF
PHPフレームワーク入門
PDF
ドメイン駆動設計(DDD)の実践Part2
PDF
Ruby on Rails Overview
Rails基礎講座 part.2
Weeklycms20120218
Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo
DDD 20121106 SEA Forum November
Heroku Postgres
20091030cakephphandson 02
ソーシャルゲームにおけるMongoDB適用事例 - Animal Land
Rails初心者レッスン lesson2 3edition
Tech fun rails_workshop
クラウド・アプリケーション・モデリングへのアプローチ
大規模ソーシャルゲーム開発から学んだPHP&MySQL実践テクニック
「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」
Ruby on Rails 入門
CodeIgniter入門
MySQL Casual な生活
PHPフレームワーク入門
ドメイン駆動設計(DDD)の実践Part2
Ruby on Rails Overview

More from Makoto Haruyama (9)

PPTX
Rails on GKEで運用するWebアプリケーションの紹介
PDF
マイクロサービスっぽい感じの話
PDF
DeNAオリジナル ゲーム専用プラットフォーム Sakashoについて
PDF
DeNAのゲーム開発を支える Game Backend as a Service
PDF
backbone.jsの使用例 その1
KEY
Mysql casual fukuoa_vlo_2
KEY
Yapc2012 ltthon
KEY
分散ファイルストレージ
PPTX
20110622 haruyama webso]cket
Rails on GKEで運用するWebアプリケーションの紹介
マイクロサービスっぽい感じの話
DeNAオリジナル ゲーム専用プラットフォーム Sakashoについて
DeNAのゲーム開発を支える Game Backend as a Service
backbone.jsの使用例 その1
Mysql casual fukuoa_vlo_2
Yapc2012 ltthon
分散ファイルストレージ
20110622 haruyama webso]cket

初心者エンジニアのシステム構築失敗談

  • 1. 初心者エンジニア の システム構築 失敗談 @Spring_MT 13年1月14日月曜日
  • 3. @Spring_MT Engineer 13年1月14日月曜日
  • 7. 初心者エンジニア の システム構築 失敗談 @Spring_MT 13年1月14日月曜日
  • 9. ・前職でエンジニアに転向� その前までは一切コード書いてないんです。。。 営業とかもやってたんですよ ・エンジニア歴 22年半くらい ・ruby歴はちょうど一年 13年1月14日月曜日
  • 10. なので ・gitしか使ったことない...... ・utf8しかしらない........ 13年1月14日月曜日
  • 11. エンジニア の ゆとり世代 13年1月14日月曜日
  • 13. 言語 フレームワーク perl 独自フレームワーク テストはあんまりない >>__<< 13年1月14日月曜日
  • 14. DDBB関連 databaseは複数 joinは基本しない masterとslave autoincrement使わない 13年1月14日月曜日
  • 20. ・テスト周�りの環境が揃っ てる ・新しくjoinする人((学生 含めて))の学習コストが低い 13年1月14日月曜日
  • 22. 実際は やってみた かっただけ 13年1月14日月曜日
  • 23. Rails で アプリ作る 13年1月14日月曜日
  • 26. ・複数DB対応 ・master  slave振り分け ・採番(sequence) ・belongs_toの扱い 13年1月14日月曜日
  • 28. いきなり大きいこと考えすぎ でもこの時は必要だと思ったんで す。。。。 13年1月14日月曜日
  • 29. 大規模病 >>__<< 13年1月14日月曜日
  • 31. 方針 ・DB + master、slave毎に Modelのクラスを作る ・Controllerで明示的にDBア クセス先を指定する 13年1月14日月曜日
  • 32. class  TestMasterShard  <  ActiveRecord::Base    self.abstract_class  =  true    establish_connection  "#{ENV['RAILS_ENV']}_test_master" end class  FooMaster  <  TestMasterShard    self.table_name  =  'foo'    attr_accessible  :name    validates  :content_id,  {presence:  true} end 13年1月14日月曜日
  • 33. octopus ・テストではまる ・明示的に書いたほうがトラブ ルが少なそう 13年1月14日月曜日
  • 34.    #  config.include  RSpec::Octopus    config.before  do        shards  =  ActiveRecord::Base.connection_proxy.instance_variable_get(:@shard        @connections  =  shards.values.map(&:connection)        @connections.each  do  |connection|            connection.increment_open_transactions            connection.transaction_joinable  =  false            connection.begin_db_transaction        end    end    config.after  do        @connections.each  do  |connection|            if  connection.open_transactions  !=  0                connection.rollback_db_transaction                connection.decrement_open_transactions            end        end    end 13年1月14日月曜日
  • 35. View Controller Model UserController UserMaster master UserSlave slave FeedController FeedMaster master FeedSlave slave GroupController GroupMaster master GroupSlave slave 13年1月14日月曜日
  • 36. 採番 sequence 13年1月14日月曜日
  • 37. 方針 アプリ内で一意のIDを発行する 13年1月14日月曜日
  • 38. ・IDがわかれば、それに紐付 くデータが一意に決まる ・重複が起きない ex)) user_id ++ コンテンツ ((feed  or  image  or  ...))のID 13年1月14日月曜日
  • 39. class  Sequence  <  SequenceShard    self.table_name  =  'seq'    def  self.generate(model)        result  =  self.connection.execute(            "UPDATE  seq  SET  id=LAST_INSERT_ID(id+1)"        )        id  =  self.connection.last_inserted_id(result)   or  raise  RuntimeError        return  id    end end 13年1月14日月曜日
  • 41. 方針 今回は複数DBを想定したので 使わないことにしました>>__<< 13年1月14日月曜日
  • 42. 課題 ・Controllerからはmaster slaveを意識せずに使いたい 13年1月14日月曜日
  • 43. いきなりこの時点でスケール を考えている。。。 そもそも考慮する必要があっ たのか? 13年1月14日月曜日
  • 44. 自分で見えない敵を作って た。。。 13年1月14日月曜日
  • 45. 大規模病 >>__<< 13年1月14日月曜日
  • 47. 課題 ・Controllerからはmaster slaveを意識せずに使いたい 13年1月14日月曜日
  • 48. 方針 ・モデルを2つに分ける ** データベースとテーブル の抽象化((masterとslave毎にク ラスがある)) ** master/slaveの抽象化 13年1月14日月曜日
  • 49. View Controller Model Logic Data UserController UserLogic UserMaster master UserSlave slave FeedController FeedLogic FeedMaster master FeedSlave GroupController slave GroupLogic GroupMaster master GroupSlave slave 13年1月14日月曜日
  • 50. Model  Data ・DBへのアクセスを管理する層 ・connectionの設定、SQLを管 理のみ 13年1月14日月曜日
  • 51. class  TestMasterShard  <  ActiveRecord::Base    self.abstract_class  =  true    establish_connection  "#{ENV['RAILS_ENV']}_test_master" end 1 class  FooMaster  <  TestMasterShard    self.table_name  =  'foo'    attr_accessible  :name    validates  :content_id,  {presence:  true}    default_scope  where(is_deleted:  0)    scope  :hoge,  lambda  {  |foo|  where('bar  =  ?',  bar)  } end 13年1月14日月曜日
  • 52. Model  Logic ・Model Dataを用いて、 master/slaveの処理をまと める層 13年1月14日月曜日
  • 53. class  BaseLogic    include  ActiveModel::MassAssignmentSecurity    include  ActiveRecord::AttributeAssignment    include  ActiveModel::Conversion    include  ActiveModel::Validations    extend  ActiveModel::Naming    extend  ActiveModel::Translation    def  persisted?;  false;  end end class  TestLogic  <  BaseLogic    attr_accessor  :foo    attr_accessible  :foo        def  get_test_one        TestSlave.get_one    end end 13年1月14日月曜日
  • 54. View Controller Model Logic Data UserController UserLogic UserMaster master UserSlave slave FeedController FeedLogic FeedMaster master FeedSlave GroupController slave GroupLogic GroupMaster master GroupSlave slave 13年1月14日月曜日
  • 55. 課題 ・複数のテーブルをまたいでデー タを処理する場合、どこにその処 理を書くのかが不定 (Model  Logic  or  Controller) 13年1月14日月曜日
  • 57. 課題 ・複数のテーブルをまたいでデー タを処理する場合、どこにその処 理を書くのかが不定 (Model  Logic  or  Controller) 13年1月14日月曜日
  • 58. 方針 ControllerとModelの間に一層 ((Context))を追加 サービス層に近い 13年1月14日月曜日
  • 59. View ユーザーのしたいこと DBのデータを適切な を実現する処理の流れ 形で受け渡すのみ Controller Context Model Logic Data UserController UserContext UserLogic UserMaster master UserSlave FeedController FeedContext slave FeedLogic FeedMaster master GroupController FeedSlave GroupContext slave GroupLogic GroupMaster master GroupSlave slave 13年1月14日月曜日
  • 60. Model Data ・DBへのアクセスを管理する層 ・connectionの設定、SQLを管 理するだけに留める 13年1月14日月曜日
  • 61. Model Logic ・Data層をコントロールする 層 ・一つのテーブルに一つ ・受け持つテーブルのデータ の処理に関してのみ責任を負 う 13年1月14日月曜日
  • 62. Context ・ ユーザーのしたいことを 実現するための処理の流れを 実装する -->>ユーザが操作する内容ご とに実装 ・Controllerと11::11対応さ せる 13年1月14日月曜日
  • 63. Controller ・Contextで作成されたデー タをViewに受け渡す cellsを使って、uriで表現されている処理のみを実 装するようにしている 13年1月14日月曜日
  • 64. View ・データを描画する ・ここにロジックは書かない 13年1月14日月曜日
  • 65. View ユーザーのしたいこと DBのデータを適切な を実現する処理の流れ 形で受け渡すのみ Controller Context Model Logic Data UserController UserContext UserLogic UserMaster master UserSlave FeedController FeedContext slave FeedLogic FeedMaster master GroupController FeedSlave GroupContext slave GroupLogic GroupMaster master GroupSlave slave 13年1月14日月曜日
  • 66. 課題 ・validationをどうする? 13年1月14日月曜日
  • 68. ・Railsは22つのvalidation が一緒になってる 13年1月14日月曜日
  • 69. ・ユーザーが入�力した値の チェック ・DBに格納する前のデータの チェック 13年1月14日月曜日
  • 71. View ユーザーのしたいこと DBのデータを適切な を実現する処理の流れ 形で受け渡すのみ Controller Context Model Logic Data UserController UserContext UserLogic UserMaster master UserSlave FeedController FeedContext slave FeedLogic FeedMaster master GroupController FeedSlave GroupContext slave GroupLogic GroupMaster master GroupSlave slave 13年1月14日月曜日
  • 73. Contextでは複数のARオブジェ クトが格納されて、その中から validationエラーをまとめ る。。。。 13年1月14日月曜日
  • 75. Validation ・ユーザーが入�力した値の チェック ・DBに格納する前のデータの チェック 13年1月14日月曜日
  • 77. DBに格納する前のデータ のチェック 今まで通りARの validateを使う 13年1月14日月曜日
  • 78. ユーザーが入�力した値の チェック ?? 13年1月14日月曜日
  • 79. ユーザーが入�力した値の チェック リクエストを 受けとった直後が 望ましい 13年1月14日月曜日
  • 80. controllerの before_filterで やる 13年1月14日月曜日
  • 81. ・ユーザーが入�力した値のチェック ==>> Controllerのbefore_filter ・DBに格納する前のデータのチェック ==>> Model 13年1月14日月曜日
  • 82. before_filter で Validation 13年1月14日月曜日
  • 83. DataValidator を書きました 13年1月14日月曜日
  • 85. DataValidator ARのvalidatorとほぼ同じバ リデーションロジックを実装 しています 13年1月14日月曜日
  • 86. params  =  {foo:  'foo',  bar:  'bar'} validator  =  DataValidator::Validator.new(    params,    {foo:  {length:  {is:  4}}},    {bar:  {presence:  true,  format:  {with:  /A[a-­‐zA-­‐Z]+z/}}} ) unless  validator.valid?    @errors  =  validator.errors end @errors =>  {    foo:  ["is  the  wrong  length  (should  be  4  characters)"],    bar:  ["can't  be  blank",  "is  invalid"] } 13年1月14日月曜日
  • 87. ・ユーザーの入�力値 ==>> Controllerのアクション 毎にDataValidatorを使う ・DBに格納する値 ==>> ModelでActiveRecord を使う 13年1月14日月曜日
  • 88. Controllerでvalidationし た後は、ユーザーの入�力値は 正しい値としてみなし、DBに 入�れる値をチェックする時に エラーになった場合はシステ ムのエラーとみなし例外で落 とす 13年1月14日月曜日
  • 89. View ユーザーのしたいこと DDBBのデータを適切な を実現する処理の流れ 形で受け渡すのみ Controller Context Model Logic Data UUsseerrCCoonnttrroolllleerr UUsseerrCCoonntteexxtt VVaalliiddaattoorr UUsseerrLLooggiicc UUsseerrMMaasstteerr mmaasstteerr UUsseerrSSllaavvee FFeeeeddCCoonnttrroolllleerr FFeeeeddCCoonntteexxtt ssllaavvee VVaalliiddaattoorr FFeeeeddLLooggiicc FFeeeeddMMaasstteerr mmaasstteerr GGrroouuppCCoonnttrroolllleerr FFeeeeddSSllaavvee GGrroouuppCCoonntteexxtt ssllaavvee VVaalliiddaattoorr GGrroouuppLLooggiicc GGrroouuppMMaasstteerr mmaasstteerr GGrroouuppSSllaavvee ssllaavvee 13年1月14日月曜日
  • 90. ・この構成で落ち着いてます ・これ以上は手を入�れない予定 13年1月14日月曜日
  • 91. Railsやめ ちゃいなよっ てつっこみは なしです>>__<< 13年1月14日月曜日
  • 92. gem ・data_validator ・rack_session_redis_store ・redis_json_serializer 13年1月14日月曜日
  • 93. ご清聴 ありがとうご ざいました! 13年1月14日月曜日
  • 96. ・分散ファイルシステムを自 前で作る? ・色々なアプリでAPIちっく に使いたい 13年1月14日月曜日
  • 97. 画像・ファイル AWS VPC ストレージ App(RoR) ・sinatraでappは作 HTTP 成 Nginx ・閲覧権限等は本体で 管理 varnish varnish ・自前で分散ファイル システム構築は難しい sinatra sinatra のでS3を使用 app app ・Storage  Proxyパ S3 ターン 13年1月14日月曜日
  • 100. public subnet net work Gateway NAT SSLの変換 subnet subnet subnet subnet fluentd utility storage ser vice deliver proxy APP Watch redis f f f worker varnish DB + sinatra f f worker f f 13年1月14日月曜日
  • 101. その他 ・session storeにredis ・queue処理はfluentd + resque    =>  http://spring-­‐mt.tumblr.com/post/35097726578/fluent-­‐plugin-­‐resque ・fluentd  +  GrowthForecastを 使った集計と可視化 13年1月14日月曜日