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

3,467 views

Published on

1 Comment
12 Likes
Statistics
Notes
No Downloads
Views
Total views
3,467
On SlideShare
0
From Embeds
0
Number of Embeds
1,030
Actions
Shares
0
Downloads
5
Comments
1
Likes
12
Embeds 0
No embeds

No notes for slide

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

  1. 1. 初心者エンジニア の システム構築 失敗談 @Spring_MT13年1月14日月曜日
  2. 2. Profile13年1月14日月曜日
  3. 3. @Spring_MT Engineer13年1月14日月曜日
  4. 4. 13年1月14日月曜日
  5. 5. 福岡RRuubbyy会議001113年1月14日月曜日
  6. 6. 福岡RRuubbyy会議001113年1月14日月曜日
  7. 7. 初心者エンジニア の システム構築 失敗談 @Spring_MT13年1月14日月曜日
  8. 8. 初心者??13年1月14日月曜日
  9. 9. ・前職でエンジニアに転向� その前までは一切コード書いてないんです。。。 営業とかもやってたんですよ ・エンジニア歴 22年半くらい ・ruby歴はちょうど一年13年1月14日月曜日
  10. 10. なので ・gitしか使ったことない...... ・utf8しかしらない........13年1月14日月曜日
  11. 11. エンジニア の ゆとり世代13年1月14日月曜日
  12. 12. 前の環境13年1月14日月曜日
  13. 13. 言語 フレームワーク perl 独自フレームワーク テストはあんまりない >>__<<13年1月14日月曜日
  14. 14. DDBB関連 databaseは複数 joinは基本しない masterとslave autoincrement使わない13年1月14日月曜日
  15. 15. 新しい環境13年1月14日月曜日
  16. 16. なんもない。。。。13年1月14日月曜日
  17. 17. 13年1月14日月曜日
  18. 18. 00からスタート13年1月14日月曜日
  19. 19. フレームワーク13年1月14日月曜日
  20. 20. ・テスト周�りの環境が揃っ てる ・新しくjoinする人((学生 含めて))の学習コストが低い13年1月14日月曜日
  21. 21. Rails13年1月14日月曜日
  22. 22. 実際は やってみた かっただけ13年1月14日月曜日
  23. 23. Rails で アプリ作る13年1月14日月曜日
  24. 24. はじめの一歩13年1月14日月曜日
  25. 25. 課題13年1月14日月曜日
  26. 26. ・複数DB対応 ・master  slave振り分け ・採番(sequence) ・belongs_toの扱い13年1月14日月曜日
  27. 27. えっ。。。13年1月14日月曜日
  28. 28. いきなり大きいこと考えすぎ でもこの時は必要だと思ったんで す。。。。13年1月14日月曜日
  29. 29. 大規模病 >>__<<13年1月14日月曜日
  30. 30. 複数DBの対応master・slave振り分け13年1月14日月曜日
  31. 31. 方針 ・DB + master、slave毎に Modelのクラスを作る ・Controllerで明示的にDBア クセス先を指定する13年1月14日月曜日
  32. 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} end13年1月14日月曜日
  33. 33. octopus ・テストではまる ・明示的に書いたほうがトラブ ルが少なそう13年1月14日月曜日
  34. 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    end13年1月14日月曜日
  35. 35. View Controller Model UserController UserMaster master UserSlave slave FeedController FeedMaster master FeedSlave slave GroupController GroupMaster master GroupSlave slave13年1月14日月曜日
  36. 36. 採番 sequence13年1月14日月曜日
  37. 37. 方針 アプリ内で一意のIDを発行する13年1月14日月曜日
  38. 38. ・IDがわかれば、それに紐付 くデータが一意に決まる ・重複が起きない ex)) user_id ++ コンテンツ ((feed  or  image  or  ...))のID13年1月14日月曜日
  39. 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    endend13年1月14日月曜日
  40. 40. belongs_to13年1月14日月曜日
  41. 41. 方針 今回は複数DBを想定したので 使わないことにしました>>__<<13年1月14日月曜日
  42. 42. 課題 ・Controllerからはmaster slaveを意識せずに使いたい13年1月14日月曜日
  43. 43. いきなりこの時点でスケール を考えている。。。 そもそも考慮する必要があっ たのか?13年1月14日月曜日
  44. 44. 自分で見えない敵を作って た。。。13年1月14日月曜日
  45. 45. 大規模病 >>__<<13年1月14日月曜日
  46. 46. 第二期13年1月14日月曜日
  47. 47. 課題 ・Controllerからはmaster slaveを意識せずに使いたい13年1月14日月曜日
  48. 48. 方針 ・モデルを2つに分ける ** データベースとテーブル の抽象化((masterとslave毎にク ラスがある)) ** master/slaveの抽象化13年1月14日月曜日
  49. 49. View Controller Model Logic Data UserController UserLogic UserMaster master UserSlave slave FeedController FeedLogic FeedMaster master FeedSlave GroupController slave GroupLogic GroupMaster master GroupSlave slave13年1月14日月曜日
  50. 50. Model  Data ・DBへのアクセスを管理する層 ・connectionの設定、SQLを管 理のみ13年1月14日月曜日
  51. 51. class  TestMasterShard  <  ActiveRecord::Base    self.abstract_class  =  true    establish_connection  "#{ENV[RAILS_ENV]}_test_master"end 1class  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)  }end13年1月14日月曜日
  52. 52. Model  Logic ・Model Dataを用いて、 master/slaveの処理をまと める層13年1月14日月曜日
  53. 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 endclass  TestLogic  <  BaseLogic    attr_accessor  :foo    attr_accessible  :foo        def  get_test_one        TestSlave.get_one    endend13年1月14日月曜日
  54. 54. View Controller Model Logic Data UserController UserLogic UserMaster master UserSlave slave FeedController FeedLogic FeedMaster master FeedSlave GroupController slave GroupLogic GroupMaster master GroupSlave slave13年1月14日月曜日
  55. 55. 課題 ・複数のテーブルをまたいでデー タを処理する場合、どこにその処 理を書くのかが不定 (Model  Logic  or  Controller)13年1月14日月曜日
  56. 56. 現在13年1月14日月曜日
  57. 57. 課題 ・複数のテーブルをまたいでデー タを処理する場合、どこにその処 理を書くのかが不定 (Model  Logic  or  Controller)13年1月14日月曜日
  58. 58. 方針 ControllerとModelの間に一層 ((Context))を追加 サービス層に近い13年1月14日月曜日
  59. 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 slave13年1月14日月曜日
  60. 60. Model Data ・DBへのアクセスを管理する層 ・connectionの設定、SQLを管 理するだけに留める13年1月14日月曜日
  61. 61. Model Logic ・Data層をコントロールする 層 ・一つのテーブルに一つ ・受け持つテーブルのデータ の処理に関してのみ責任を負 う13年1月14日月曜日
  62. 62. Context ・ ユーザーのしたいことを 実現するための処理の流れを 実装する -->>ユーザが操作する内容ご とに実装 ・Controllerと11::11対応さ せる13年1月14日月曜日
  63. 63. Controller ・Contextで作成されたデー タをViewに受け渡す cellsを使って、uriで表現されている処理のみを実 装するようにしている13年1月14日月曜日
  64. 64. View ・データを描画する ・ここにロジックは書かない13年1月14日月曜日
  65. 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 slave13年1月14日月曜日
  66. 66. 課題 ・validationをどうする?13年1月14日月曜日
  67. 67. Validation13年1月14日月曜日
  68. 68. ・Railsは22つのvalidation が一緒になってる13年1月14日月曜日
  69. 69. ・ユーザーが入�力した値の チェック ・DBに格納する前のデータの チェック13年1月14日月曜日
  70. 70. 今の構成13年1月14日月曜日
  71. 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 slave13年1月14日月曜日
  72. 72. Contextが入�ったことで validationでエラーが起きた時 のARオブジェクトの受け渡しをど うするか?13年1月14日月曜日
  73. 73. Contextでは複数のARオブジェ クトが格納されて、その中から validationエラーをまとめ る。。。。13年1月14日月曜日
  74. 74. 正直面倒13年1月14日月曜日
  75. 75. Validation ・ユーザーが入�力した値の チェック ・DBに格納する前のデータの チェック13年1月14日月曜日
  76. 76. 分ける!13年1月14日月曜日
  77. 77. DBに格納する前のデータ のチェック 今まで通りARの validateを使う13年1月14日月曜日
  78. 78. ユーザーが入�力した値の チェック ??13年1月14日月曜日
  79. 79. ユーザーが入�力した値の チェック リクエストを 受けとった直後が 望ましい13年1月14日月曜日
  80. 80. controllerの before_filterで やる13年1月14日月曜日
  81. 81. ・ユーザーが入�力した値のチェック ==>> Controllerのbefore_filter・DBに格納する前のデータのチェック ==>> Model13年1月14日月曜日
  82. 82. before_filter で Validation13年1月14日月曜日
  83. 83. DataValidator を書きました13年1月14日月曜日
  84. 84. 13年1月14日月曜日
  85. 85. DataValidator ARのvalidatorとほぼ同じバ リデーションロジックを実装 しています13年1月14日月曜日
  86. 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:  ["cant  be  blank",  "is  invalid"] }13年1月14日月曜日
  87. 87. ・ユーザーの入�力値 ==>> Controllerのアクション 毎にDataValidatorを使う ・DBに格納する値 ==>> ModelでActiveRecord を使う13年1月14日月曜日
  88. 88. Controllerでvalidationし た後は、ユーザーの入�力値は 正しい値としてみなし、DBに 入�れる値をチェックする時に エラーになった場合はシステ ムのエラーとみなし例外で落 とす13年1月14日月曜日
  89. 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 ssllaavvee13年1月14日月曜日
  90. 90. ・この構成で落ち着いてます ・これ以上は手を入�れない予定13年1月14日月曜日
  91. 91. Railsやめ ちゃいなよっ てつっこみは なしです>>__<<13年1月14日月曜日
  92. 92. gem ・data_validator ・rack_session_redis_store ・redis_json_serializer13年1月14日月曜日
  93. 93. ご清聴 ありがとうご ざいました!13年1月14日月曜日
  94. 94. 時間があれば。。。。13年1月14日月曜日
  95. 95. 画像・ファイル ストレージ13年1月14日月曜日
  96. 96. ・分散ファイルシステムを自 前で作る? ・色々なアプリでAPIちっく に使いたい13年1月14日月曜日
  97. 97. 画像・ファイルAWS VPC ストレージ App(RoR) ・sinatraでappは作 HTTP 成 Nginx ・閲覧権限等は本体で 管理 varnish varnish ・自前で分散ファイル システム構築は難しい sinatra sinatra のでS3を使用 app app ・Storage  Proxyパ S3 ターン13年1月14日月曜日
  98. 98. サーバー構成13年1月14日月曜日
  99. 99. オールAWS!13年1月14日月曜日
  100. 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 f13年1月14日月曜日
  101. 101. その他 ・session storeにredis ・queue処理はfluentd + resque    =>  http://spring-­‐mt.tumblr.com/post/35097726578/fluent-­‐plugin-­‐resque ・fluentd  +  GrowthForecastを 使った集計と可視化13年1月14日月曜日
  102. 102. 13年1月14日月曜日

×