初心者エンジニアの システム構築 失敗談
Upcoming SlideShare
Loading in...5
×
 

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

on

  • 3,517 views

 

Statistics

Views

Total Views
3,517
Views on SlideShare
2,082
Embed Views
1,435

Actions

Likes
10
Downloads
9
Comments
1

9 Embeds 1,435

http://spring-mt.tumblr.com 1381
http://tumblr.hootsuite.com 25
https://twitter.com 10
http://heaven-controlled22.rssing.com 9
http://webcache.googleusercontent.com 3
http://tweetedtimes.com 2
http://s.deeeki.com 2
https://www.google.co.jp 2
http://twitter.com 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Logic層の役割が曖昧だった\nある程度は太ってもぽっちゃり系で許容できるけど、スパゲッティにならないことが重要\nLogic層はあくまでModel\nここでカオスった\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • エラーがARの中に入ってる(ARをViewまで引き回す)\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • controller のアクション毎に設定できる\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n

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

  • 初心者エンジニア の システム構築 @Spring_MT
  • Profile
  • @Spring_MTin 10xLabInfra andApp Engineer
  • 初心者?
  • ・前職でエンジニアに転向・エンジニア歴 2年半くらい・福岡歴は10ヶ月
  • 前の環境
  • 言語 フレームワーク perl 独自フレームワークテストはあんまりない >_<
  • DB関連 databaseは複数 joinは基本しない masterとslaveautoincrement使わない
  • 新しい環境
  • なんもない。。。。
  • 0からスタート
  • フレームワーク
  • ・テスト周りの環境が ってる・新しくjoinする人(学生含めて)の学習コストが低い
  • Rails
  • 実際はやってみた
  • Rails で
  • はじめの一歩
  • 課題
  • ・複数DB対応・master slave振り分け・採番(sequence)・belongs_toの扱い
  • えっ。。。
  • いきなり大きいこと考えすぎでもこの時は必要だと思ったんです。。。。
  • 大規模病>_<
  • 複数DBの対応master・slave振り分け
  • 方針・DB + master、slave毎にmodelを作る・Controllerで明示的にDBア
  • class TestMasterShard < ActiveRecord::Base self.abstract_class = true establish_connection "#{ENV[RAILS_ENV]}_test_master"endclass FooMaster < TestMasterShard self.table_name = foo attr_accessible :name validates :content_id, {presence: true}end
  • octopus・テストではまる・明示的に書いたほうがトラブルが少なそう
  • # config.include RSpec::Octopusconfig.before do shards = ActiveRecord::Base.connection_proxy.instance_variable_get(:@shards) @connections = shards.values.map(&:connection) @connections.each do |connection| connection.increment_open_transactions connection.transaction_joinable = false connection.begin_db_transaction endendconfig.after do @connections.each do |connection| if connection.open_transactions != 0 connection.rollback_db_transaction connection.decrement_open_transactions end endend
  • View Controller Model UserController UserMaster master UserSlave slave FeedController FeedMaster master FeedSlave slave GroupControlle GroupMaster master GroupSlave slave
  • 採番
  • 方針アプリ内で一意のIDを発行する
  • ・IDがわかれば、それに紐付くデータが一意に決まる・重複が起きないex) user_id + コンテンツ
  • 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 endend
  • belongs_to
  • 方針今回は複数DBを想定したので使わないことにしました>_<
  • 課題・Controllerからはmasterslaveを意識せずに使いたい・ Fat Model
  • いきなりこの時点でスケールを考えている。。。そもそも考慮する必要があったのか?
  • 自分で見えない敵を作ってた。。。
  • 大規模病>_<
  • 第二期
  • 課題・Controllerからはmasterslaveを意識せずに使いたい・ Fat Model
  • 方針 slave・Controllerがmasterを意識せずにModelを呼び出せる・DBへデータを取得する部分とデータを加工する部分を分ける
  • 方針ModelをLogic層とData層に分ける
  • View Controller Model Logic Data UserController UserLogic UserMaster master UserSlave slave FeedController FeedLogic FeedMaster master FeedSlave GroupControlle slave GroupLogic GroupMaster master GroupSlave slave
  • Data層・DBへのアクセスを管理する層・connectionの設定や、SQLを管理するだけに留める
  • class TestMasterShard < ActiveRecord::Base self.abstract_class = true establish_connection "#{ENV[RAILS_ENV]}_test_master"endclass 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
  • Logic層・Data層を組み合わせてデータの加工を行う
  • class BaseLogic include ActiveModel::MassAssignmentSecurity include ActiveRecord::AttributeAssignment include ActiveModel::Conversion include ActiveModel::Validations extend ActiveModel::Naming extend ActiveModel::Translation def persisted?; false; endendclass TestLogic < BaseLogic attr_accessor :foo attr_accessible :foo validates :foo, {presence: true, length: {maximum: 255}} def get_test_one endend
  • View Controller Model Logic Data UserController UserLogic UserMaster master UserSlave slave FeedController FeedLogic FeedMaster master FeedSlave GroupControlle slave GroupLogic GroupMaster master GroupSlave slave
  • 課題・複数のテーブルからデータを取得する場合、どこにその処理を書くかで迷う(Logic層?、Controller?)
  • 現在
  • 課題・複数のテーブルからデータを取得する場合、どこにその処理を書くかで迷う(Logic層?、Controller?)
  • 方針ControllerとModelの間に一層(Context)を追加
  • ユーザーのしたいこと DBのデータを適切な View を実現する処理の流れ 形で受け渡すのみController Context Model Logic DataUserController UserContext UserLogic UserMaster master UserSlaveFeedController FeedContext slave FeedLogic FeedMaster masterGroupController FeedSlave GroupContext slave GroupLogic GroupMaster master GroupSlave slave
  • Model Data層・DBへのアクセスをコントロールする層。発行するSQLはここでコントロールする
  • Model Logic層・Data層をコントロールする層・基本的に一つのテーブルに一つ
  • Context・ ユーザーのしたいことを実現するための処理の流れを実装する->ユーザが操作する内容ごとに実装
  • Controller・Contextで作成されたデータをViewに受け渡すcellsを使って、uriで表現されている処理のみを実装するようにしている
  • View・データを描画する・ここにロジックは書かない
  • ユーザーのしたいこと DBのデータを適切な View を実現する処理の流れ 形で受け渡すのみController Context Model Logic DataUserController UserContext UserLogic UserMaster master UserSlaveFeedController FeedContext slave FeedLogic FeedMaster masterGroupController FeedSlave GroupContext slave GroupLogic GroupMaster master GroupSlave slave
  • 課題・validationをどうする?
  • Validation
  • ・ユーザーが入力した値のチェック・DBに格納する前のデータのチェック
  • ・Railsは2つのvalidationが一緒になってる
  • 今の構成
  • ユーザーのしたいこと DBのデータを適切な View を実現する処理の流れ 形で受け渡すのみController Context Model Logic DataUserController UserContext UserLogic UserMaster master UserSlaveFeedController FeedContext slave FeedLogic FeedMaster masterGroupController FeedSlave GroupContext slave GroupLogic GroupMaster master GroupSlave slave
  • Contextが入ったことでvalidationでエラーが起きた時のARオブジェクトの受け渡しをどうするか?
  • Contextでは複数のARオブジェクトが格納されて、その中からvalidationエラーをまとめる。。。。
  • 正直面倒
  • Validation・ユーザーが入力した値のチェック・DBに格納する前のデータのチェック
  • 分ける!
  • つまり
  • Controllerでもvalidationする
  • えっ(∩゚д゚)
  • Controllerでもvalidationする
  • Controller でもvalidation
  • 言っちゃった..
  • ((((;゚
  • ・ユーザーが入力した値のチェック => Controller・DBに格納する前のデータのチェック => Model
  • Controller でもValidationするために
  • DataValidatorってのを書きました
  • DataValidatorARのvalidatorとほぼ同じバリデーションロジックを実装しています
  • 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.errorsend@errors=> { foo: ["is the wrong length (should be 4 characters)"], bar: ["cant be blank", "is invalid"]}
  • ・ユーザーの入力値=> Controllerのアクション毎にDataValidatorを使う・DBに格納する値=> Modelで
  • Controllerでvalidationした後は、ユーザーの入力値は正しい値としてみなし、DBに入れる値をチェックする時にエラーになった場合はシス
  • ユーザーのしたいこと DBのデータを適切な View を実現する処理の流れ 形で受け渡すのみController Context Model Logic Data UserController UserContextValidator UserLogic UserMaster master UserSlave FeedController FeedContext slaveValidator FeedLogic FeedMaster masterGroupController FeedSlave GroupContext slaveValidator GroupLogic GroupMaster master GroupSlave slave
  • ・この構成で落ち着いてます・これ以上は手を入れない予定
  • Railsやめちゃ いなよってつっこみはな
  • gem・data_validator・rack_session_redis_store・redis_json_serializer
  • 画像・ファイルストレージ
  • ・分散ファイルシステムを自前で作る?・色々なアプリでAPIちっくに使いたい
  • 画像・ファイル ・sinatraでappは作AWS VPC App(RoR) 成 HTTP ・閲覧権限等は本体で Nginx 管理 varnish varnish ・自前で分散ファイル sinatra sinatra app app システム構築は難しい のでS3を使用 S3
  • サーバー構成
  • オールAWS!
  • public subnet net work Gateway NAT SSLの変換 subnet subnet subnet subnet fluentd utility storage ser vice deliver proxy APPWatch redis f f f worker varnish DB + sinatra f f worker f f
  • その他・session storeにredis・queue処理はfluentd +resque=> http://spring-mt.tumblr.com/post/35097726578/fluent-plugin-resque・fluentd + GrowthForecastを
  • 時間があれば。。。。
  • なにかあれば懇親会で!
  • ご清聴ありがとうござ