『Webフロントエンド ハイパフォーマンス チューニング』学習メモ
Ch1 Web performanceとは何か
- performance: userの様々な振る舞いにWeb pageが応答する速さ
- Web page内でのinteractionのperformanceの最適化を目指す
Ch2 browserのrenderingの仕組み
- 対象とするrendering engine
- history
- WebKit系のrendering engineを見る
- rendering engine: browserの内部で利用するHTMLの描画engine
- HTML, 画像ファイル, CSS, JavaScriptなどの各種resourceを読み取って,画面上の実際のpixelとして描画
- JavaScript engine
- V8など
- V8はNode.jsでも使われている
- V8など
- WebView: browserと異なり,Web pageの表示のみを行うcomponent
- online contentsをapplication内で表示/application内のcontentsを再installすることなしにdynamic updateのため.
- WKWebView > UIWebView
- browserのrenderingの流れ
- HTML, CSS, JavaScript, HTTPなどの周辺要素が相互に関連し合って進むため,複雑
- 4つの工程からなるrenderingが始まって,最終的に描画されるまで: Frame
- resourceの読み込み: Loading
- browserが, URLからHTMLを読み込んで,そこからさらにrenderingに必要な付属するresourceを読み込んで解釈
- resourceのdownload + resourceのparse
- resource: HTML/CSS/JavaScript/{JPEG, PNG, GIF, SVG} file
- resourceの取得のためのnetwork protocol
- 各resourceの読み込み
- HTMLの読み込み
- URLからHTTP request → HTTP responseとしてHTMLを取得
- → 取得したHTMLを解釈し,DOM(Document Object Model) treeを構築
- DOM: HTMLのDocumentを表現するObject.rendering engineが利用する木構造を持つ内部表現.
- DOM treeへの変換過程で,画像やCSSなどのDocumentに紐づくresourceの取得や読み込みを行う
- DOM tree: JavaScriptからアクセス〇 → DOM操作
- process
- 字句解析によるtokenのlist化
- 構文木内にあるJavaScriptを実行しつつDOM treeの構築
- img: 画像.link: CSS.script: JavaScript.
- CSSの読み込み
- HTMLの読み込み
- browserが, URLからHTMLを読み込んで,そこからさらにrenderingに必要な付属するresourceを読み込んで解釈
- JavaScript 実行 -Scripting
- JavaScriptの実行: 最初にJavaScriptファイルを読み込んだとき + DOMイベントが発火しevent listenerが起動するとき
- 字句解析と構文解析
- 字句解析: source code → token list
- 構文解析: token list → 抽象構文木
- 抽象構文木: JavaScriptの文法に則った形で表現される木構造のdata
- compile
- 実行
- JavaScript内では,DOM APIを通じてDOM treeを操作
- 後続のRendering, Painting phaseやLoading phaseを引き起こす
- Layout tree構築 -Rendering
- Calculate Style + Layout
- Calculate Style
- Layout
- 要素の大きさ,margin, padding, 位置,z軸の位置を計算
- rendering結果の描画 -Painting
- Paint
- 内部の低レベルな2D graphic engine向けの命令の列(Display List)を,Layerごとに生成
- browserによって,組み込むgraphic engineが異なる
- bottleneckにはならない
- Rasterize
- 生成された命令から,pixel(bitmap)へと描画
- overhead大きい
- layerという単位で1枚ずつ描画
- layer: overwrapして表示するcontentsがあるときに生成
- 描画済みのlayerを再利用して,再renderingが素早く容易になる
- Composite(複合,合成) Layers
- pixelにしたlayerを合成して最終的なrendering結果を生成
- 3Dの処理などはGPU.ほかはCPU.
- Paint
- 再rendering
- DOM eventにより発生
- JavaScriptのコードにより,どのphaseを引き起こすか知ることがimportant
Ch3 tuningの基礎
- 闇雲なtuningの害
- trade off: developerの時間的resource.コードの単純さ.
- best practice
- HTTP requestを減らす
- CDNを使う
- Expires headerを設定する
- componentをgzipする
- style sheetは先頭に置く
- scriptは最後に置く
- CSS expressionの使用を控える
- JavaScriptとCSSは外部ファイル化する
- DNS lookupを減らす
- JavaScriptを最小化する
- redirectを避ける
- scriptを重複させない
- ETagの設定を変更する
- Ajaxをcache可能にする
- ×推測,〇計測
- bottleneckの解消がimportant
- 目指すべき指標を設定する
- performance metrics: RAIL
- user中心のperformance model
- Web page以外にも,複雑なinteractionやanimationを含むWeb applicationやHybrid applicationにも適用できる
- Response, Animation, Idle, Load
- Response: 100 ms
- userが感じられる視覚的な変化
- over 100 msなら,処理中を意味するindicatorの表示が〇
- 指のtouchやscrollはAnimationと同じく16 ms以内が必要
- Animation: 16 ms
- 連続して行われるframeの中で1 frameの処理時間の目安
- frame: Scripting, Rendering, Painting
- 16 ms → 60 FPS(Frames Per Second)を満たす
- frame中のJavaScriptの処理時間は6 ms以内
- Idle: 50 ms
- Idle状態で実行されるJavaScriptの処理時間
- Load: 1000 ms
- 1000 ms以内にsplash screenを表示して,そのほかのresourceの読み込みは遅延でも〇
- cacheやloading 画面の表示で,各種resourceの読み込みを遅らせるのが〇
- performance metrics: RAIL
- 計測手段
- Chrome DevToolsなどdeveloper toolによる計測
- Web page内の細かな計測や解析を行うのに有効
- Web pageがどのように処理されてRenderingに至るのかを詳細・多角的にみられる
- performanceのbottleneckの原因箇所の調査に有効
- 継続的かつ定量的な計測には向かない
- JavaScriptによる計測
- performanceのmetricsの収集・算出の自動化
- userの環境にばらつきがあるcaseで特に有効
- performance診断tool
- performanceが適切かどうか,performance改善のためのtechniqueをadvice
- 継続的監視
- 改修を重ねていくときにperformanceの問題を常に確認する必要がある
- Chrome DevToolsなどdeveloper toolによる計測
- Chrome DevToolsなどdeveloper toolによる計測
- AndroidでのChrome DevToolsの利用方法
- PCとAndroidをUSBで接続する
- WebViewを使う場合
- iOSでのWeb inspectorの利用
- Chrome DevToolsの主要機能
- Network panel
- networkを通じたresource取得のtimelineを細かく見る
- blue line: DOMContentLoaded
- 遅い場合はscriptによる読み込みブロックなどの問題
- red line: Load event
- 遅い場合はresourceの容量が過大
- 回線状況の再現も〇
- 個別のresourceの取得時間: timeline上の表示にカーソルを合わせる
- Connection SetupやRequest/Responseの内容
- Waiting(TTFB)が長いときは,サーバ処理に時間がかかっている
- Performance panel
- page loadや操作に関するすべてのeventを分析〇
- frame chart
- blue/red lineはNetworkと同じ
- green line: 最初のPaintが発生するtiming(page上になんらかの表示が反映されるtiming)
- 特に時間のかかっている処理の割り出しに使う
- profileの取得: Performance panelの記録
- Rendering engine内のほとんどすべてのphaseのprofileを細かくとることができる
- Memory panel
- memory leakの検知やmemoryの使い過ぎの把握のため
- heap snapshot, memory割り当ての確認ができる
- AndroidでのChrome DevToolsの利用方法
- JavaScriptによる計測
- Navigation Timing APIによる計測
- browserのnavigation時の詳細なperformance情報を取得できる
- browserの各段階の処理時間を計測〇
- 以前のWeb pageのunloadの時間など,Web serverでは検知できない情報を得られる
- Objectのpropertyの差を求め,処理時間を算出
- timing Objectは参照するtimingに注意
- navigation Objectの内容も合わせて見る
- どのようなnavigationか
- User Timing APIによる計測
- 任意の処理にかかる時間を計測〇
- interactionなど必ずしも計測地点を機械的に宣言できない処理の計測
- performance
- mark()
- measure()
- getEntriesByName()
- 任意の処理にかかる時間を計測〇
- Resource Timing APIによる計測
- 個別のresourceの取得にかかっている時間の統計情報を取得
- redirectにかかる時間
- DNS lookupにかかる時間
- network connectionの確立にかかる時間
- HTTP responseを受け取るのにかかる時間
- Network panelとほとんど同じものが対象
- PerformanceResourceTiming Object
- 個別のresourceの取得にかかっている時間の統計情報を取得
- Performance Observerによる監視
- これから起こる処理のperformance informationを指定して監視
- 柔軟にperformance informationを取得
- SPAなどinteractionを多く持つようなWeb pageでのperformanceも容易に取得〇
- 記録・解析のためにreal timeでserverに送信も〇
- modern browserの中では,Google Chromeのみ対応
- 高精度なtimestampを得る
- Navigation Timing APIによる計測
- performance diagnostics tools
- performanceの継続的監視
- New Relic Browser
- JavaScriptをWeb siteに埋め込む
- New Relic Browser
Ch4 resource読み込みのtuning
- resource読み込みの流れ
- HTML fileから始まるresourceのgraphを構築しつつ,network protocolを通じてresourceを取得・parse
- TCP/IP + HTTP/1.1で考える
- HTML/CSS/JavaScriptを最小化する
- 余計なbyte列を除去する各tools
- deploy前で自動化する
- JavaScript libraryは最小化されているものを使っても〇
- 余計なbyte列を除去する各tools
- proper image typeを選択
- image fileを最適化
- 各toolsを,wrapper tool, task runnerやbuild toolなどから使うことも多い
- Web fontも最適化可能
- CSSのimportを回避
- HTTP requestを減らすという原則 + 直列な取得・読み込みを避けるため
- toolやメタ言語で結合する
- JavaScriptのsyncな読み込みを避ける
- JavaScriptのdocument.write()はDOM treeの構築に影響を与えるため,script要素はdocumentのparseやCSS fileの読み込みをブロックする
- JavaScriptをasyncに読み込む
- defer attribute
- JavaScript fileは,DOM treeが構築されてから初めて実行
- DOMContentLoaded eventの発火前に実行
- 実行順を保証
- JavaScript fileは,DOM treeが構築されてから初めて実行
- async attribute
- JavaScriptのdownload時点で実行される
- 実行順を保証しない
- 依存関係は,ファイルの結合などで解消が必要
- JavaScriptでscript要素をasyncに読み込む
- 読み込むtimingを細かく制御したい場合など
- async 読み込みの利用方針
- asyncが一番performance〇
- asyncがダメならdefer
- deferもダメなら通常のscript要素
- defer attribute
- device pixel比ごとに読み込む画像を切り替える
- srcset
- さらにresponsive対応をするなら,pictureやsizes
- CSSのmedia queryを適切に指定する
- CSS spriteを使って複数の画像をまとめる
- HTTP requestを減らす
- まとめた画像の一部を切り取って表示
- CriticalCSSで最初の描画を最適化
- resourceを事前読み込みしておく
- Gzip圧縮を有効にする
- CDNを用いてresourceを配信する
- Akamai, Cloudflareなど
- domain sharding
- not redirect
- directoryの名前で終わらず,/をつけるかファイル名を明示する
- directoryの名前で終わると,/をつけたURLにredirectされる
- directoryの名前で終わらず,/をつけるかファイル名を明示する
- browserのcacheを活用
- Expires header
- 強いcache
- Apacheでの指定方法
- HTTP response headerを確認するとわかる
- server/clientで時間設定がずれていると×
- Cache-Control header
- 強いcache
- max-age
- Apacheでの指定方法
- Expires/Cache-Control headerの使い分け
- Cache-Control headerが優先される
- Expires headerは古い
- URLにtokenを付加する
- 強いcacheを疑似的に消す
- PHPなどのserver sideで付加することがほとんど
- 弱いcacheの活用
- 条件つきHTTP requestを使う
- Last-Modified headerの設定
- ETag headerの設定
- Entity Tag(version)で表現
- Last-Modified/ETag headerの使い分け
- ETagが優先される
- Apacheでの指定方法
- 複数台のWeb serverのときは,ETagが変わってしまうため対応が必要
- ETagの柔軟性が不要なら,ETagを付加せずLast-Modifiedのみ指定
- cacheの使い分け
- 静的なresourceは強いcache
- まず強いcacheを使えないか判断し,だめなら弱いcache
- Expires header
- Service Workerの使用
- JavaScriptからcacheの制御を柔軟に実行可能
- Web Workerの一種で,main threadとは別threadで動作
- Web pageとWeb server間でproxyのように動作し,resourceをcacheから取得するかWeb serverから取得するか決定
- Service Workerの導入
- 廃止されるApplication Cacheの代替になる
- HTTP/2の利用
- SPDY protocolがbase
- SPDY protocol: resource読み込みのlatencyの削減を目的にGoogleが開発
- binary化したprotocol
- HTTP/1.1: text baseの通信
- 効率〇
- HTTP/1.1のsemanticsの再利用
- HTTP/1.1とTCPの間に挟まって通信を効率化するような形
- requestとresponseの多重化
- browserの同時connection数のlimitなし
- HTTP headerの圧縮(HPACK)
- RFC7541
- 以前送ったHTTP headerの差分のみをお互いに送る
- 無駄が減る.requestごとの効率up
- HTTP/2 protocolはTLSが事実上必須
- 速度は問題ないケースもある
- HTTP/2で無意味になるtechnique
- HTTP request数を減らしたり,同時接続数の制限を疑似的に増やす必要がなくなる
- HTTP/2 対応 reverse proxyの利用
- clientからのaccessをHTTP/2 serverが処理し,実際のcontents配信はHTTP/1.1 serverが行う構成を取れる
- SPDY protocolがbase
- QUIC protocol
- build tool
- ファイルの依存関係を解決し,複数のファイルをまとめる目的
- task runnerも同等の用途で使われる
- tuningのためのtechniqueの自動化に必要
- TypeScriptやBabelのtranspileや,buildまでの経路の複雑化などから,build toolは不可欠になってきている
Ch5 JavaScript実行(Scripting)のtuning
- HTML5になり,文書だけでなくapplicationを表現するplatformになった.
- 文書と構造: HTML, CSS ←→ 動的な側面: JavaScript
- JavaScriptの実行model
- UI thread
- tab1つにつき1つのUI thread(main thread)
- JavaScriptの実行だけでなく,rendering engineの様々な処理が実行
- Layoutの計算,rendering処理,DOM eventの発火など
- event loopと実行queue
- JavaScriptはevent loopというmodelで動作するため,single threadでの動作にもかかわらず,複数の処理を同時に実行できる
- responseの受け取りなどの継続する処理は,asyncで動作するcallbackの受け渡しやevent listenerによる
- networkなど処理待ちの時間は,タスクを一度終了しUI threadに制御を戻す.処理の再開時にはじめてUI thread上での処理が始まる.
- 例外
- alert(), confirm(), prompt(), sync XMLHttpRequest
- JavaScriptはevent loopというmodelで動作するため,single threadでの動作にもかかわらず,複数の処理を同時に実行できる
- UI thread
- JavaScriptのbottleneckを特定する
- Performance panelによる計測
- rendering engineの行うほとんどの処理のprofileを取れる
- JavaScript, UI threadのrendering, DOM eventの処理など
- JavaScriptでは,どの関数でどのくらい時間がかかっているか細かくわかる
- performance diagnosticsなら,まずはPerformance panelでprofileを取る
- rendering engineの行うほとんどの処理のprofileを取れる
- 各処理の確認方法
- 警告箇所と,ほかの処理の妨げになっているところや明らかに処理時間が長いものを見ていく
- Performance panelによる計測
- GCを避ける
- requestAnimationFrame()などのときに,問題になる
- 検知: Performance panelでprofileを取る
- 防ぐ: 新しいObjectを生成しないか,必要なObjectや配列を予め生成しておく
- memory leakを防ぐ
- importance
- performanceやapplicationの安定性のためにimportant
- desktopでもswapで遅くなるし,mobileではapplicationがcrashする
- detection
- Performance panelでprofileを取る
- heapの3点観測
- heap snapshotを3つとる
- Summary viewの見方
- 黄色のObject: JavaScriptから参照されているObject
- 赤: documentのDOM treeから分離したDOM treeに含まれているDOM要素
- console.log()によるmemory leak
- log()以外も,consoleに値を解析して表示する類のものは,特殊な参照がつく
- debug処理の除去の自動化ができる
- DOM leak
- DOM tree自体もleakする
- DOM leakの検知
- importance
- WeakMap, WeakSet
- weak reference: GCでは利用されていると見られない
- WeakMap: あるObjectの拡張や,private memberを持ちたいときに使える
- WeakSet: あるObjectにflagを立てたいときに使える
- 利用して〇なら最初から利用する
- Web Workersの利用
- codeの複雑化,thread生成costなどのtrade offあり
- 利用方法
- Web WorkersのthreadとUI thread間の通信: message passing(asyncにデータを通信し合う
- postMessage(), event listener
- 共有ではなくcopy
- Web WorkersのthreadとUI thread間の通信: message passing(asyncにデータを通信し合う
- multi Web Workersを生成する
- multi coreで並列計算
- navigator.hardwareConcurrencyを参照してコア数を取り,それに応じたWeb Workersを生成する
- 論理的なコア数が見える
- Transferableを利用
- copyとcopyのoverheadを回避
- 所有権が移動する
- Transferableを実装しているObject
- ArrayBuffer: 型つき配列のdata storage
- MessagePort: ほかのdocumentとの通信のために使う
- 制限
- 使えないObject
- DOM要素,document Object, window Object, parent Object
- → 純粋なデータ処理のみをWeb Workerで行う
- 使えないObject
- asm.jsによるJavaScript高速化
- 高速実行のためのJavaScriptのsubset language
- specification
- 計算はすべてstatic typing
- 計算で使える型はint, double, floatのみ
- asm.js module内部では仮想的にGCが利用不可
- asm.js形式のコードを書きだすtranspilerによって処理を記述する想定
- いずれWebAssemblyにreplaced
- WebAssembly
- より高速なloadと実行を目的として各browser vendorによって策定されている,browser上で実行可能なbinary format
- JavaScriptの一部の機能を代替
- merit, compared to asm.js
- load time短縮
- parseの簡略化
- heap sizeの制限緩和
- memoryに対する柔軟な読み書き
- SIMD.jsの利用
- 高頻度で発火するeventの抑制
- scroll, resize, touchmoveなど
- setTimeout()やrequestAnimationFrame()で,ある一定の頻度でのみ実際の処理を行うようにする
- そのほか,視差効果やscroll event listenerなど
- mobile端末でのclick eventの遅延をなくす
- meta要素によるviewportを適切に設定する
- FastClickやTappy libraryを使っても〇
- Passive Event Listenerでscrollのperformanceを改善する
- event.preventDefault()が無効になることを保証
- capture phaseでevent listenerを呼び出し
- browserでのsupportの確認処理
- scroll performanceの改善以外にも,event listenerがinteractionをブロックする時間が気になるときには検討〇
- setImmediate()のasync 実行
- setTimeout()は,指定した時間の後にasync実行
- ↑ ずれがある
- ←→ setImmediate()は,UI threadがidleになったらすぐに実行
- clearImmediate()で解除
- polyfill libraryのsetImmediate.jsで使える
- setTimeout()は,指定した時間の後にasync実行
- idle時処理を使う
- requestIdleCallback()
- cancelIdleCallback()で解除
- page表示状態を確認する
- 状態に応じて,animationのon/offなどを行う
- 正確なpage viewの測定にも使う
- Page Visibility API
- document.hiddenを参照
- visibilitychange event
- document.visibilityState
- 無駄なForced Synchronous Layoutを減らす
- DOM操作→関連するDOM要素のLayout情報を参照で,Forced Synchronous Layoutが引き起こされる
- Recalculate StyleとLayoutがsyncに処理される
- JavaScriptともsyncに実行
- Layoutに影響する操作
- style attributeやstyle propertyを通じて要素の大きさや座標にかかわる操作をする
- DOM要素のclass属性を変えて,当たるstyleを変更して要素の大きさや座標を変更する
- DOM treeの構造に変更を加える操作(DOM要素の追加・削除など)
- 計測
- Layout Thrashingを避ける
- loop中でFSLを繰り返し起こしてしまうこと
- FSLを防ぐ
- DOM 操作の前にLayout情報を参照する
- requestAnimationFrame()で計算済みのLayout情報を参照する
- DOM操作→関連するDOM要素のLayout情報を参照で,Forced Synchronous Layoutが引き起こされる
- DocumentFragmentの追加
- Web pageのdocumentの断片を表す
- DOM treeへのDOM要素の追加を速くできる
- 複数のDOM要素を格納〇
- Intersection Observerで効率的に交差を検知する
- あるDOM要素と親要素が視覚的に交差しているか監視
- 使い方
- not supportedなら,scroll eventで処理したりしないといけない.問題がある.
- canvas要素の2D Context animation
- requestAnimationFrame()を活用する
- setTimeout()やsetInterval()の課題
- proper timingでcallbackの呼び出しがdifficult
- requestAnimationFrame()によるanimation
- 自動的に呼び出しtimingを最適化
- 指定したcallbackを,browserのrenderingの処理に合わせて,proper timingで呼び出し
- setTimeout()やsetInterval()の課題
- JavaScriptからCSS Transitionを使う
- animationの進行中はJavaScriptのコードは一切実行されない
- requestAnimationFrame()とは異なり,JavaScriptがbottleneckにはならない
- UI threadとは別のthreadで実行
- rendering engine内部で最適なtimingで実行される
- animationの進行中はJavaScriptのコードは一切実行されない
- WebGL
- WebCL
- 小さな最適化
- 有意味でないことが多い
- まずはbottleneckの解析
- 次は,アルゴリズム・データ構造や基礎技術の改善
Ch6 Layout tree構築(Rendering)のtuning
- Rendering: Calculate Style + Layout
- interactionの高速化にもつながる
- Layout tree構築の流れ
- Layout tree構築におけるperformanceの計測
- Performance panel
- Recalculate Style
- Elements Affected
- Layout
- Nodes that need layout
- Layout root
- Recalculate Style
- Performance panel
- 高速なCSS selectorの記述
- BEMを用いる
- 設計・保守しやすさを上げる + performance〇
- BEM: Block, Element, Modifier
- Block: page内を構成するひとかたまり.header, footer, 記事など.
- Element: Blockを構成する要素
- Modifier: BlockやElementの見た目や振る舞いを拡張
- 1つのclass selectorのみでCSS selectorを宣言する
- CSS selectorのmatching処理を避ける
- DOM要素のstyle propertyを直接変更すると,matching処理を回避できる
- 必ずそうするべきというわけではなく,高速なperformanceが必要なanimationやinteractionのときのみ
- 利用していないCSS rule setを減らす
- UNCSS
- build toolとの組み合わせも〇
- UNCSS
- media queryを指定する
- 不要なrule setをまとめて除外できて〇
- DOM要素のstyle propertyを直接変更すると,matching処理を回避できる
- Layoutを高速化する
- a.c.a Reflow
- Layoutを避ける
- Layoutの原因
- DOM要素の座標や大きさの変化
- DOM treeの構造の変化
- DOM要素のcontentの変化
- Layoutの範囲を限定する
- いずれかの条件
- svg要素
- type="text", or type="search"のinput要素
- table要素の子孫じゃなくてかついろいろ条件を満たす
- いずれかの条件
- Layoutの原因
- DOM treeから切り離して処理する
- DOM treeから離れれば,Renderingはなくなる
- remove()
- 必要になった時にappendChild()などで再挿入すればよい
- Layoutを減らす非表示
- display: none
- img要素のsizeを固定
- height, widthを指定しないと仮の大きさで1度Layoutが走る
Ch7 Rendering結果の描画(Painting)のtuning
- interactionやanimationを実装するときに頻繁に実行される
- Rendering結果の描画の流れ
- → Ch2
- 再描画(Repaint)
- CSS propertyの変更が何を引き起こすか
- CSS Triggers
- Layerの生成条件
- Layer treeが構成される
- GPUに転送されるGraphics Layerが,performanceに影響大きい
- うまく扱うと,animationを高速化できる
- Layer treeを確認する
- Performance panel
- Layer treeの詳細を確認
- 歯車 → Enable advanced paint instrumentation(slow)にチェック → profileを取得 → Frames → Layers
- Layerの範囲を確認
- Rendering optionのLayers Borders
- 描画のoverheadを解析
- Performance panelでPaint Profilerを見る
- Paint Profilerの確認方法
- GPUによって合成されるlayer
- translateZ hack
- translateZ(0)により,結果を変えずにGPUで合成できる
- position: fixedのscroll speedの改善
- body要素にtranslateZ hackを用いる問題
- translateZを使うためのrule
- Rasterizeされることが少ない要素に用いる
- 領域がそれほど大きくない要素に用いる
- 必要なときだけ用いる
- translateZを使うためのrule
- 必要なtimingだけtranslateZ hackを用いる
- JavaScriptでDOM要素のstyle propertyを指定する
- will-changeCSS propertyによるtranslateZ hackの代替
Ch8 高度なtuning
- 大量のDOM要素を扱うvirtual rendering
- なめらかなanimation
- 指標と基本的な考え方
- RAILを使う
- Rerenderingのphaseを減らす
- skip Calculate Style
- JavaScriptでDOM要素のstyle propertyを直接変更
- 不要ならDOM treeの構造やDOM属性を変更しない
- skip Layout
- transformCSS propertyの値に,translate()やscale()を使う
- skip Paint
- Paintを引き起こさないproperty
- opacity
- transform
- これらを使えない場合は仕方ない
- Paintを引き起こさないproperty
- layerの合成の最適化
- translateZ hack
- 指標と基本的な考え方
- will-changeCSS propertyによる最適化
- CSS property名を指定
- opacity, transformのみ
- scroll-positionを指定
- 要素の移動(animation)や素早いscrollに対応
- contentsを指定
- animationや変更を予想
- cacheの生成・維持を省ける
- dynamicに利用
- JavaScriptからのdynamicな利用が〇
- CSSでの宣言は,その要素が常に変更されるときのみ
- 使い方
- 最適化においては,見かけほど有用ではない
- CSS property名を指定
- CSS ContainmentでRerenderingを最適化
- CSS Containment: DOM treeの一部に封じ込め〇
- 利用方法
- layout: Layoutの封じ込め
- 副作用: floatCSS propertyでの回り込みの影響がなくなる
- paint: Paintの封じ込め
- Layoutの封じ込めとともに,大きな最適化
- 副作用3点
- style: styleの封じ込め
- 単体では使わない
- size: 大きさの封じ込め
- 単体では使わない
- layoutと併用したり,content/strictを指定して使う
- content/strict: 複数の封じ込め
- content: layout + paint + style
- strict: layout + paint + size + style
- 最も最適化の効果〇
- まずはstrictで,だめならcontent
- AMP(Accelarated Mobile Pages)
- static contentsを高速に提供
- 専用CDNやprerenderingなどで〇
Ch9 認知的tuning
- indicatorを使う
- 1sを超える処理や読み込みのとき
- 10sを超えるときはprogress barなどの進捗の表示が必要
- interface previewを使う
- indicatorより印象〇
- 処理が終わったように振る舞う
- beforeunloadで処理中の離脱へのアラート
- 無限scroll
- 同様の要素を表示するpageで使う
- userのscrollをJavaScriptで検知,pageの最下部になると,次のpageの情報を読み取って動的に読み込むべきcontentsを画面下部に追加
- 一部のRerenderingで済むため速い
- 実装上の注意
- → 5.11
- virtual renderingとの違い
- 無限scrollはvirtual renderingと併用する
- merit
- waiting time小さい
- demerit
- footer使えない
- back buttonで表示が壊れることがある
- リンクは別windowにするなど対応が必要
- 投機的なresourceの先読み
- user activityの洞察と解析が必要
- 事例
- 手段
- JavaScriptで実装したapplication levelのcacheを使う
- IndexedDB, LocalStorageなどのstorageで保存するか,もしくは単にJavaScriptの変数で保持(SPAなどのとき)
- Resource Hints API(4.11)も〇
- SPA: Single Page Application
- SPA以外は,page操作で断絶 → userの体感速度を大きく低下
- Ajaxの発展形
- library, frameworkが必要
- React.js, Angular, Vue.jsなど
Appendix SVGのperformance特性
- SVG: Scalable Vector Graphics
- XMLで表現されるVector Graphicsのformat
- browserで利用できる唯一のVector Graphics format
- HTMLと親和性がある
- img要素ではなく,svg要素で,その画像をdocument内に直接埋め込める
- tagの記述も〇
- JavaScriptでの振る舞いを追加したり,CSSで修飾もできる
- img要素ではなく,svg要素で,その画像をdocument内に直接埋め込める
- JavaScriptでSVG内の視覚的要素をanimationさせたり,event listenerを追加してinteractionを与えられる
- HTMLのanimationの問題もいくつか回避している
- JavaScriptでanimationを行う
- SMILによるanimation
『Web API: The Good Parts』学習メモ
Ch01 what's Web API
- Web API: HTTP protocolを利用してnetwork越しに呼び出すAPI
- API: Application Protocol Interface
- APIのpattern
- 使用例
- APIで公開するもの
- Web APIを美しく設計する重要性
- 使いやすさ,変更しやすさ,頑強さ,魅力
- Web APIを美しくするには
- 仕様が決まっているものは仕様に従う
- 仕様がないものはdefacto standardに従う
- RESTとWeb API
- RESTの本来の意味に合っていない使われ方がされている
- RESTの考えを適用する場面は多いが,すべてがRESTではない
- target developerの数とAPIの設計思想
- LSUDs(Large Set of Unknown Developers)とSSKDs(Small Set of Known Developers)
- SSKDs向けは,RESTを基本にしたAPIでは不十分
- → Orchestration layer
- まとめ
Ch02 endpointのdesignとrequestの形式
- APIとして公開する機能をdesign
- UCを考える
- API endpointの考え方
- HTTP methodとendpoint
- APIのendpoint design
- 検索とquery parameterのdesign
- loginとOAuth 2.0
- 認証のAPIとして,Authが真っ先に検討できる標準仕様
- 自社開発のClient Applicationにおいて,ユーザ名とパスワードをapplication内に入力して認証を行う場合
- OAuthのGrant Typeのうち,Resource Owner Password Credentialsを使う
- 扱い方
- OAuthのGrant Typeのうち,Resource Owner Password Credentialsを使う
- access tokenの有効期限と更新
- other Grant Type
- Client Credentials: User name, Password不要な認証.Clientの認証のみ行う.
- 自分の情報へのalias
- me, self
- ほかのユーザの情報の処理とは,処理自体を分岐することでバグを防げる
- hostnameとendpointの共通部分
- api.example.comの形が最も適当
- SSKDsとAPI design
- HATEOASとREST LEVEL3 API
- まとめ
- [Good] 覚えやすく,どんな機能を持つか一目でわかるendpointにする
- [Good] 適切なHTTP methodを利用する
- [Good] 適切な英単語を利用.単複にも注意.
- [Good] 認証はOAuth 2.0
Ch03 response dataの design
- data format
- JSONPの取り扱い
- dataの内部構造の考え方
- 各dataのformat
- response dataのdesign
- あるデータを返すときは同じ構造になるよう,それぞれのデータの構造を定義してしまうとsimpleで〇
- errorの表現
- proper status code
- detail
- bodyで〇.headerに入れるのも悪くはなさそう
- detail code, detail information link
- HTMLで返らないようにする
- @maintenance
- 503
- Retry-After
- 意図的に不正確な情報を返す
- まとめ
Ch04 HTTPの仕様を最大限利用する
- 意義
- 不本意に独自仕様をいれてしまう危険性を下げる
- HTTP protocolがenvelopeの役割という例
- status codeを正しく使う
- APIで使うcode一覧
- 2xx: success
- 204: No Contentは,是非あり
- PUT, PATCHは,200とともに操作したデータを返す(POSTは201)
- DELETEは204
- 204: No Contentは,是非あり
- 3xx: 追加で処理が必要
- redirect: 301, 302, 303, 307
- Locationを伴う
- POSTによるデータ送信 → GETで別のページを表示のケースが多い
- 302, 301はmethodの変更を許可
- 308, 307は不許可
- APIではできるだけredirectを避ける
- 300: Multiple Choices
- 304: Not Modified
- redirect: 301, 302, 303, 307
- 4xx: Clientのrequestに問題があった場合
- 400: Bad Request
- ほかのcodeでは表せない「その他」
- 401: Unauthorized. Authentication(認証) error. ← 誰ですか?
- 403: Forbidden. Authorization(認可) error. ← 許可がないよ.
- ほかにも色々ある
- 400: Bad Request
- 5xx: Serverに問題があった場合
- cacheとHTTPの仕様
- cacheのmerit. → 可能な限り利用するべき
- proxy serverへの考慮必要
- reverse proxy
- Expiration Model
- fresh ←→ stale
- Expires
- 特定の日時に更新されることがあらかじめわかっているdataに使う
- Cache-Control
- max-age
- HTTP時間
- RFC1123を使う
- HTTP時間
- max-age
- Validation Model
- 条件付きrequest
- Last-Modified, ETag (Entity Tag)
- If-Modified-Since, If-None-Match
- e.g. MurmurHash3
- strong/weak Validation
- weakなら,広告などの違いは無視できる
- 条件付きrequest
- Heuristic Expiration(発見的期限切れ)
- ClientがCacheの期限を自分で決める
- Cache-Control: no-cache
- VaryでCacheの単位を指定
- Server Driven Content Negotiation
- Accept-Encoding, User Agent, Accept-Language, Authorization, Cookie
- Cache-Control header
- stale-while-revalidate
- asyncでcacheの検証をしている間はcacheを返してよい → 速度〇
- stale-if-error
- origin serverに接続できなかったときに,stale cacheを返してよい秒数
- stale-while-revalidate
- media typeの指定
- media type: data format
- Content-Type @response
- MIME: Multipurpose Internet Mail Extensions
- top level type name/ sub type name [; parameter]
- top level type: text/image/video/applicationなど
- sub type: 具体的なdata format
- top level type name/ sub type name [; parameter]
- 前提知識なくても読めればtext, そうでなければapplication
- MIME: Multipurpose Internet Mail Extensions
- 正しいmedia typeをContent-Typeで返す
- x-で始まるmedia type
- IANA(Internet Assigned Numbers Authority)に登録されていないもの
- application/x-www-form-urlencodedだけ例外的に登録されている
- IANA(Internet Assigned Numbers Authority)に登録されていないもの
- 自分でmedia typeを定義する
- Registration treeで接頭辞が決まっている
- vnd.を使うことが多い
- Registration treeで接頭辞が決まっている
- JSONやXMLを用いた新しいdata形式を定義する場合
- 独自に別のHTTP headerを用意するのが折衷案として〇
- media typeが正しくないと,security riskあり
- media type @request
- 同一生成元policy(Same Origin Policy)とCross-Origin Resource Sharing
- 独自のHTTP headerを定義する
- 接頭辞: X-
- X-は不要という論もある
- まとめ
- [Good] HTTPの仕様を最大限利用し,独自仕様の利用を最低限に止める
- [Good] 適切なstatus codeを用いる
- [Good] 適切な,なるべく一般的なmedia typeを返す
- [Good] Clientが適切なcacheを行えるように情報を返す
Ch05 設計変更をしやすいWeb APIを作る
- 設計変更のしやすさのimportance
- 影響が分かりづらい
- 外部/mobile/web serviceいずれの場合も問題あり
- web service,自分のserviceで使っているAPIであれば,問題は小さいが,cacheの問題はある
- APIをversionで管理する
- versionを変えるときの指針
- security, authorityにアップデートは,後方互換なしで〇
- 以降のバージョンアップの影響を小さくするために実施する
- 常に最新版を返すaliasは不要
- APIの提供を終了する
- 終了日時の周知
- Blackout Test
- 予め提供終了時の仕様を盛り込む
- 強制アップデート,ユーザのOSの調査
- 利用規約にサポート期限を明記
- applicationの性質による
- Orchestration layer
- LSUDs: one-size-fits-all(OSFA)
- OSFAではなく,それぞれのClientに対応するために,ServerとClientの間にOrchestration layerを挟むようにする.
- まとめ
Ch06 堅牢なWeb APIを作る
- 安全性と安定性
- Web APIを安全にする
- riskのe.g.
- Server-Client間での情報の不正入手
- browserでアクセスするAPIの問題
- browserは汎用的で機能が豊富
- XSS
- XSRF: Cross Site Request Forgery
- Forgery: 偽造,捏造
- 回避方法
- methodを正しく使う
- XSRF tokenを使う
- X-Request-With
- JSON hijack
- 回避方法
- JSONをSCRIPT要素では読み込めないようにする
- X-Requested-With
- XMLHttpRequest, browser以外からのClientからのアクセスのみを想定の場合は,必ずやる
- X-Requested-With
- JSONをbrowserが必ずJSONと認識するようにする
- 正しいmedia typeを返す
- JSONをJavaScriptとして解釈不能,または実行時にデータを読み込めないようにする
- JSONをSCRIPT要素では読み込めないようにする
- 回避方法
- browserからのアクセスを想定しないAPIでは,browserからのSCRIPT要素を使ったアクセスを防ぐのが〇
- 悪意あるaccessへの対策
- security関係のHTTP header
- 大量accessへの対策
- まとめ
Appendix
『メタプログラミングRuby』 学習メモ
Part 1 meta programming Ruby
Ch01 initial M
- introspection
- Active Recordがintrospectionを使っている
- meta programming: 言語要素を実行時に操作するコードの記述
- codeを記述するcodeを記述
- meta programmingの学習により,Rubyのruleがわかる
Ch02 Monday, Object model
- すべての言語要素はObject model内に共存する
- Open Class
- classはscope 演算子のようなもの
- monkey patchは×
- Object modelの内部
- Objectの中身
- instance variable
- 値が代入されたときに初めて出現
- method
- ObjectではなくClassに存在する.
- 共通のClassを持つObjectはメソッドも共通
- → instance method: Classに定義されていて,呼び出すにはObject(instance)が必要になるmethod
- ←→ method: Object(instance)がもつmethod
- ObjectではなくClassに存在する.
- instance variable
- Classの真相
- Class.superclass # => Module
- Class: Objectの生成やClassを継承するための3つのinstance methodを追加したModule
- Moduleはinclude, Classはinstanceの生成や継承
- Classの参照も保持できる.ClassはObject,Class名は定数
- 定数
- file systemと類似
- Rakeの例: moduleで定数をまとめる例
- まとめ
- Object: instance variableの集まりに,クラスへのリンクがついたもの
- Classについて
- load, require
- load: codeの実行のため.呼び出すたびにファイルを実行する.
- 定数の扱いのための引数
- require: libraryのimportのため.1回だけファイルを読み込む.
- load: codeの実行のため.呼び出すたびにファイルを実行する.
- Objectの中身
- Object, Module, Classの関係について
- 循環したり自己参照したりしている.
- method call
- method探索 + method実行
- method 探索
- receiverと継承チェーン
- one step to the right, then up
- Moduleも継承チェーンに入る.
- includeは上に,prependは下にModuleを挿入
- include, prependは1度目のみ有効
- Kernel: ObjectがKernelをinclude
- method 実行
- receiverの参照を持つ
- self, top level
- private: explicit receiver不可
- Refinements
- monkey patchの回避.
- usingで有効にする
- 発展途上なので,直感に合わない挙動がある
- 絡み合ったModule
- 継承チェーンの確認
- まとめ
Ch03 Tuesday, method
- boiler plate methodの回避
- 重複問題
- dynamic method
- dynamic dispatch: sendを使うことで,method nameをargumentにしてdynamicにcallできる
- :(name) ← symbol
- immutable. String: mutable.
- immutableなので,メソッド名などのmeta programmingに関係する名前に使う
- Pryの例
- methodをdynamicにdefine
- 実行時にmethod nameを決定するため,defではなくModule#define_methodを使う
- Stringと変換可能
- e.g.
- Array#grep → define_method
- method_missing
- ghost method: method_missingのoverride
- Hashieのe.g.
- dynamic proxy: ghost methodを補足して,ほかのObjectに転送するObject
- Gheeのe.g.
- GitHubのObjectをdynamic hash に保持.hashのattributeは,ghost methodの呼び出しでアクセスできる
- hashをProxy Objectでラップ.
- Gheeのe.g.
- respond_to_missing?もあわせてoverride必要
- const_missing
- 古いクラス名が呼び出されたときに,警告を出して新しいクラス名を返す
- 受付可能な引数以外はBasicObject#method_missingを呼ぶ必要がある
- ghost method: method_missingのoverride
- blank slate
- 最小限のmethodしか引き継がないClass
- BasicObjectの継承.指定しなければObject.
- methodの削除
- Builderのe.g.
- まとめ
- Rubyのdynamicな能力により,複数のmethodに共通した外部の重複を排除できる
- 可能であればdynamic method, 仕方なければghost method
Ch04 Wednesday, block
- not from Object Oriented Design, but from Functional Programming Language like LISP
- block day
- blockの基本
- do...end, {}
- yieldでblockを呼び出す
- blockの基本
- Kernel methodで,usingのように例外の有無によらず処理を呼び出せるようにする振る舞いを追加できる
- block is closure
- blockは,コードと束縛の集まりの両方を含む
- scope
- scope gate: scopeを切り替えて,新しいscopeをopenする場所
- class, module, def
- defは呼び出したときに実行.class, moduleはすぐに実行
- scopeのflatten, flat scope
- shared scope
- instance_eval
- instance_evalに渡したblock: context 探査機
- instance_execなら引数で渡すことができる
- replace scope gate to method call
- encapsulateの破壊
- irb, test
- Padrinoのe.g.
- clean room: blockを評価するためだけのObject
- callable Object
- blockの使用の2process
- codeの保管 → blockを呼び出して実行
- block以外のコードを保管できるところ
- Procのなか.← blockがObjectになったもの.
- lambdaのなか. ← Procの変形.
- methodのなか.
- Proc Object
- あとで評価
- lambdaとprocで生成できる
- ->lambda
- &修飾
- methodに渡されたblockを受け取って,それをProcに変換
- Procをblockに戻すときも&修飾
- HighLineのe.g.
- あとで評価
- Proc vs lambda
- return
- lambdaはlambdaから戻るだけ.Procは,Procが定義されたscopeから戻る
- 項数(引数の数)
- lambdaは一般的に厳しい.Procは合わせてくれる.
- lambdaはmethodに似ていて,一般的にはlambdaを使う.
- return
- Method Object
- blockやlambdaに似ているが,所属するObjectのscopeで評価
- UnboundMethod
- Active Supportのe.g.
- 自分ではやらない方が〇
- blockの使用の2process
- DSLを書く
- event間で共有
- global variableの削除
- clean roomの追加
- まとめ
Ch05 Thursday, Class definition
- RubyのClass definitionはcodeを実行する
- Classは高性能のModule. Class definitionに関することはModule definitionにも置き換えられる.
- Class definitionの分かりやすい説明
- Class, Moduleも単なるObjectで,selfになれる.
- current Class
- class_eval
- self, current Classを変更する → Classを再open可能
- flat scope
- class_execもある
- instance_evalとの使い分け.
- class_eval
- Class instance variable
- Class instance variableとObjectのinstance variableは別物
- Class variableは△.共有の度合いが大きい.
- testでのClass instance variableの使用
- Class のtaboo
- Class.new()で,Class keywordを使わずにClass作成
- 特異method
- 特定のObjectにmethodを追加できる.
- Duck typing
- Class methodはClassの特異method
- Class macro
- Module#attr_*のe.g.
- attr_accessorなど
- Module Classに定義されているので,selfがModuleでもClassでも使えるもの.
- Class定義の中で使える単なるClass method
- Module#attr_*のe.g.
- 特異Class
- a.c.a. meta Class, singleton Class
- 変わった構文を使わないとみることができない.
- only one instance( so that called singleton Class )
- Objectの特異methodの在り処
- 特異methodがあれば,特異Classから探索する.特異ClassがObjectのsuper Classになる.
- 継承
- metaの2乗
- 特異Classの特異Class
- 大統一理論
- Object, Module, Methodはそれぞれ1種類だけ.
- Objectの特異Classのsuper Classは,ObjectのClass
- Classの特異Classのsuper Classは,Classのsuper Classの特異Class
- Class methodの構文
- Class methodはClassの特異Classにある特異method
- instance_evalは,current Classをreceiverの特異Classに変更する
- 意図としては,selfの変更で良い.
- Classのattributeの追加のe.g.
- metaの2乗
- Class拡張
- Object拡張も〇
- どちらもObject#extendを使うのが〇
- method wrapper
- methodの再定義: 新しいmethodを定義して,元のmethodに名前を付ける
- Thorのe.g.
- around alias
- Refinementsでaround alias
- Prepend wrapper
- 計算methodをaround aliasで変更することもできるというe.g.
- まとめ
Ch06 Friday: codeを記述するcode
- meta programmingの新しいtrickと,様々なtrickを組み合わせて難しいcoding課題を解決する方法を見る
- Kernel#eval
- REST Clientのe.g.
- code文字列は文字列の代わりになるものを使うことが多い
- 外部ソースにある任意のcode文字列を評価するときも使う
- Binding Object
- scopeをObjectにまとめたもの
- eval "@x", b ← b: Binding
- TOPLEVEL_BINDING
- Pryの例
- irbのe.g.
- code 文字列 vs block
- 基本はblockを使うべき
- evalのproblem
- code injection
- 代用: dynamic dispatch
- Object taintとsafe level
- ERBのe.g.
- safe levelがあるときは, sandboxが作られてそこで実行される.
- load, requireとの比較
- REST Clientのe.g.
- evalでの実装とevalの置き換え
- classのscopeに入るためにclass_eval → 実行時まで分からないのでdynamic method
- instance variableの読み書き: Object#instance_variable_set(/get)
- blockでの置き換え
- Kernel methodをClass macroに変更
- あらゆるClass定義で使うために,ModuleまたはClassのinstance methodを作成する.
- → class_evalも不要になる
- あらゆるClass定義で使うために,ModuleまたはClassのinstance methodを作成する.
- hook method
- Class#inheritedなどのmethod.defaultでは何もしない
- 特異methodにはsingletonをつけないと動作しない
- standard methodにplugin
- superで元のincludeを呼び出す必要ある
- VCRのe.g.
- instance methodを特異Classにmix in → Class methodを追加できる
- Class macroから,includeしたClassだけaccessできるように制限する
- Moduleのincludedを上書きして,ClassMethodsを拡張する
- まとめ
Ch07 epilogue
- meta programmingも単なるprogramming
Part2 Railsにおけるmeta programming
Ch08 Rails tourの準備
- Ruby on Rails
- Active Record(applicationのObjectをDBのテーブルにmapping), Action Pack(Web frameworkの「Web」の部分を扱う), Active Support(時刻計算やloggingなどの汎用的な問題を扱うutility)
- gem unpack activerecord -v=4.1.0
Ch09 Active Recordのdesign
- Object Relational Mapping
- Relational DB + Object Oriented Programming
- Active Recordのまとめられ方
- Active Support + Active Model
- auto loading by ActiveSupport::Autoload
- ActiveRecord::Base
- Moduleの外側にある機能をまとめるClass. Moduleの集まり
- Moduleのincludeで,instance methodとClass methodを手に入れる
- history
- Active RecordからActive Modelが分離
- Active Record: DB操作, Active Module: Object Modelの操作
- Active RecordからActive Modelが分離
- 学んだこと
- ActiveRecord::Baseは,究極的なopen Class
- 疎結合,simplicity, 重複の排除という基本的な設計原則を実現するための技法が,ほかの言語と大きく異なる
Ch10 Active SupportのConcern Module
- history
- ActiveSupport::Concern
- Module#append_features
- Concern#append_features
- concern(ActiveSupport::ConcernをextendしたModule)のなかで,別のconcernをincludeしない
- 依存を管理する.最小主義の依存管理system
- 学んだこと
- 柔軟性のためのmeta programming
- codeが複雑になったり,排除しにくい重複が見つかった時に使う.
- Moduleの相互作用のような基本的な部分でも,meta programmingで変更できる
- 柔軟性のためのmeta programming
Ch11 alias_method_chainの盛衰
- problem
- 学んだこと
- 素直なObject指向で解決できれば,meta programmingは使わない
Ch12 attribute methodの進化
- どのようにmeta programmingを使うか
- codeが複雑になり,微妙に意味が違ってくる中で起きたことを見る.
- Rails 1: はじめはsimple
- method_missing
- Rails 2: performanceに注目
- method_missingは遅い
- → ghost method + dynamic method
- 各Classで1度だけmethod_missingを呼ぶ
- backにDBのカラムがない派生fieldなどのattributeへの対応.→ attribute accessorを定義しない
- Rails 3, 4: もっと特殊なcase
- Rails 4ではattribute accessorの定義時に,UnboundMethodに変更し,Method cacheに保存している. → ほかのClassが同じ名前のattributeを持ち,同じaccessorが必要な場合はcacheから取り出す.
- performanceが目に見えて変わる.
- ReaderMethodCacheの初期化処理にコメントがある
- attribute methodがどれだけ深くて複雑なものになったか,どれだけの数の特殊ケースに対応しているか,最初はsimpleだったところからどれだけ変わったか,を示している.
- Rubyのsafeなmethod nameにするための対応
- Rails 4ではattribute accessorの定義時に,UnboundMethodに変更し,Method cacheに保存している. → ほかのClassが同じ名前のattributeを持ち,同じaccessorが必要な場合はcacheから取り出す.
- 学んだこと
- 「最初から正しくやる」よりも「進化的設計」に傾いている.
- Rubyが柔軟性の高い言語であるため
- 最初から完璧なmeta programmingのcodeを書くことは難しい
- → codeはできるだけsimpleに保ち,必要になったら複雑にする
- 「最初から正しくやる」よりも「進化的設計」に傾いている.
Ch13 最後の教訓
- meta programming: simple, clean, and tested codeを書くための単なるtool
付録
A よくあるidiom
- mimic method
- mimicry: 擬態
- 偽装method
- Campingの例
- class Help < R '/help' ← R('/help')と読み替えるとわかる
- attributeの不具合
- attributeのsetterは,privateでもselfをつけて呼び出せる
- nil guard
- ||=
- OR と =
- falseになりうるときは使わない
- ||=
- 自己yield
- blockにObject自身を渡せる
- Faradayのe.g.
- 新しく生成したConnection Objectをselfとしてyieldに渡す
- tapのe.g.
- 呼び出しのchainを断ち切らずに,中間の作業をtap {} で差し込む
- Symbol#to_proc
- one call blockを短い記述に置き換える
- inject(init)などで使える
B DSL
C 魔術書
- 今までのものの短いsample
D から騒ぎ
『Webを支える技術』学習メモ
Part1 Web概論
Ch01 what's Web
- Webの作用
- 非線形なhyper media @Web
- distributed system @Web
- simple protocol
Ch02 Web history
- Web以前のhyper media
- hyper media: hyper textの拡張
- 必要最小のリンク機能のみ持つWeb
- RPC, CORBA, DCOM
- Web以前のdistributed systemの問題
- Webの起源
- simpleな単方向リンク
- client-server間のIF.simple protocolとしてのHTTP
- IETF→W3Cでのstandardize
- especially HTML, CSS
- Webのstandardize
- RESTの起源,意味
- HTTPはresourceのstateの表現を転送している
- REpresentational State Transfer
- Hyper Media Format: HTML, RSS, Atom, microformat, JSON
- RESTの起源,意味
- Web API
- SOAP @RPC/distributed object
- WS-*
- mashupのためのREST
- SOAP @RPC/distributed object
- REST, Ajax, CometによるWebの進化
Ch03 REST: Web architecture style
概要
- architecture style: architecture pattern
- e.g. MVC, Pipe&Filter, Event System
- architecture style > micro architecture pattern(design pattern) @粒度
- architecture styleをもとに,architectureを決定する
内容
- REST: network systemのarchitecture style
- Web: client/server style
- REST: client/server + 制約
抽象度 | Webでの例 |
---|---|
architecture style | REST |
architecture | browser, server, proxy, HTTP, URI, HTML |
implement | Apache, Firefix, IE |
詳細
- resource: Web上の名前を持ったあらゆる情報
- resource name, identifier: URI
- addressability
- URIによってresourceが表す情報にアクセス
- client-server間でやり取りするdata: resourceの表現
- 1つのresourceは複数表現を持てる
- e.g. html, pdf
- 1つのresourceは複数表現を持てる
- addressability
- RESTの構成
- RESTは複数のarchitecture styleを組み合わせて構築した複合architecture
- a.client-server
- Web: httpでclient-serverが通信するというarchitecture style
- merit: client-serverを分離できる
- multi platform @client + serverの冗長化で可用性UP
- b.stateless server
- clientのapplicationのstateは管理しない
- c.cache
- resourceをclient側で再利用
- d.統一IF
- 統一IFにより,client-server間の独立性を高める
- GET, POSTなど限定的なmethodのみを持つ
- 統一IFにより,client-server間の独立性を高める
- e.階層化system
- 統一IFにより,load balancerやproxyを使用したsystemの階層化が容易になる
- f.code ondemand
- a-fを組み合わせたarchitecture styleがREST
- REST以外のarchitecture style: P2P
- RESTの2つの側面
- RESTとHypermedia
- resourceをリンクで接続することで1つのapplicationを構成する
- 接続性: RESTの基幹をなす
- RESTとdistributed system
- linkをたどってapplication stateを遷移することで性能劣化を抑える.
- 統一IFにより互換の問題が起こらない.
作用
- RESTというdistributed network systemのための理論により,Webが機能する
- RESTの制約に従っていること: RESTful
Part2 URI
Ch04 URIの仕様
目的
- URI: Uniform Resource Identifier
- resourceを統一的に識別するID
概要
詳細
まとめ
Ch05 URI design
目的
概要
詳細
- Cool URI
- usability高まる
- URIの変更のためのredirect
- 拡張子でresourceの表現を特定
- 言語を指定する拡張子
- → Content Negotiationのためのbrowserの設定不要
影響
Part3 HTTP
Ch06 HTTPの基本
目的
- TCP/IPの基礎とHTTPの歴史を見る
- HTTPは以下のRESTの重要な特徴を実現する,Webの基盤となるprotocol
- 統一IF
- stateless server
- cache
概要
- TCP/IPの観点
- 階層型protocol → 層ごとに抽象化して実装
- application layer
- transport layer
- internet layer
- IPでpacket単位でdataをやり取り.IPに相当.
- 自分のnetwork IFでのdata送信の保証
- network IF層
- 物理的な部分
- 階層型protocol → 層ごとに抽象化して実装
詳細
- HTTP history
- client-serverのarchitecture style
- client ≒ user agent
- request-response型のprotocol
- @client, @server
- HTTP message: request-response message
- request messageの構成
- request line
- method, request URI, protocol version
- header
- body
- request line
- response messageの構成
- status line
- header
- body
- request messageの構成
- stateless HTTP
- application state = session state
- statefulの欠点
- client増 → scaleout difficult
- statefulの欠点
- stateless の利点
- 自己記述的messageでscaleout easy
- statelessの欠点
- performance down
- data量,冗長(認証など)
- 通信エラー
- performance down
- application state = session state
作用
- simple HTTPにより,Web ServiceとWeb APIが同じprotocolで表現
Ch07 HTTP methods
目的
- 8 methodsのうち,主要な6つのmethodsの使い方を見る
- and, HTTPの設計上の工夫を見る
- method数が少ないからこそHTTPやWebは成功
概要
- HTTP methodsの観点
詳細
- methodの使用の観点
- POSTでPUT/DELETEを代用
- _method parameter
- X-HTTP-method-override header
- 条件付きrequest
- 冪等性(idempotence)と安全性
- idempotence: PUT, DELETE
- idempotence and safe: GET, HEAD
- どちらでもない: POST
- methodのproper use
- 他methodでできることにPOSTを使わない
- PUTの冪等なuse
- DELETEの冪等なuse
- POSTでPUT/DELETEを代用
作用
- 数少ないmethodによりprotocolをsimpleに保つ
- RESTの統一IFの実現
Ch08 status code
- 観点
- status line
- status codeの分類による意味
- client-server間を疎結合に
- 先頭の数字でclientが解釈
- よく使われるcode
- status codeとerror handling
- {protocol, Accept header}に従ったformatのerror
- status codeの設計
Ch09 HTTP header
目的
- HTTPの構成要素
- method
- status code
- header
- meta dataをstandardize
- 認証やcacheを実現
- history
- headerの成り立ち
- mailと共通の部分
- mailと異なり双方向
- headerの成り立ち
概要
- 観点
- GMTでのdate
- MIME: Multipurpose Internet Mail Extensions
- Content-Type
- charset → textのときの文字化け
- Content-Language: resource表現の自然言語
- Content Negotiation: client がrequest
- Accept
- Content Length
- chunk transfer @画像などを分割
- 認証: realmの値: URI空間
- cache
- cache用headerでcontrol
- 条件付きGET
- 持続的接続 @HTTP1.1でdefault
- pipeline化
- closeで切断
- その他のHTTP header
作用
- various 技術標準の組み合わせでheaderを構成する.十分な調査によりHTTP headerを扱える.
- authenticationやcacheなどのHTTPの重要な機能を実現
Part4 HyperMediaFormat
Ch10 HTML
- HyperMediaFormatとしてのHTMLを見る
Ch11 microformats
目的
- microformatsによりlinkの細かい意味やevent informationを表現
問題
- semantics(意味論)
- program semantics
- program languageのもつ意味を確定させる理論
- Web semantics「semantics Web」
- resourceの持つ意味を確定させる理論
- program semantics
- RDFの問題とmicroformatsでの解決
概要
- microformatsのstandardize
- 分類
- elemental
- compound
- 分類
作用
- microformatsで解決できない部分
- RDFa(RDF-in-attributes)での解決
- 可能性
- microformatsによりWeb pageをそのままWeb APIとして提供
- Web page/APIの機能差少ない
- 保守・開発コスト小さい
Ch12 Atom
目的
概要
- resource model
詳細
- entryの構成
- feedの構成
- Atomの拡張
- Feedの分割
- archived feed
- Open Search
作用
- Atom: title, author, update timeなどの基本的なmeta dataを持ったresource表現のためのformat
Ch13 Atom Publishing Protocol
- Atom Publishing Protocol
- Atom Publishing Protocolのresource model
- 1つのresourceがmulti 表現
- member resourceの操作
- service document
- Atom Publishing Protocolに向いている/いないWeb API
Ch14 JSON
- JSON: hashや配列などのdata構造の記述
Part5 Web Serviceの設計
Ch15 Read Only Web Serviceの設計
目的
- resource designの観点
概要
- resource指向のarchitectureのapproachの観点
- RESTfulなWeb Serviceの性質
- addressability
- stateless
- 接続性
- 統一IF
詳細
- 各手順の観点
作用
- resource design skillの習得でよい設計
Ch16 writable Web Service
目的
- ROのServiceより観点多い
概要
- 観点
- resource create/update/delete
- batch処理
- transaction
- 排他
詳細
- create
- factory resource
- PUT作成
- 〇 作成と更新の区別不要
- × clientにURI構造流出
- update with PUT
- bulk update
- partial update → 通信料cut
- update error
- delete
- 子resource
- batch: POSTでURIを非指定
- response
- transaction
- transaction resource
- (or batchのtransaction化)
- 上位resourceへの操作
- 排他
- pessimistic lock
- LOCK/UNLOCK @WebDAV
- 独自Lock resource
- optimistic lock
- conflictを解消
- Condition PUT/DELETE
- conflictを解消
- pessimistic lock
作用
- 以下の観点でバランス
- なるべくsimple
- 別resourceで解決
- 必要ならPOST
Ch17 resource design
目的
- dataの特定とdataのresource分割のための方法を見る
内容
- 関係モデルからの導出
- data model with math的基盤
- 中心tableの1行を1 resource
- 自己記述のため非正規 → network負荷減
- resourceに必要な項目をすべて入れる
- 階層 difficult
- linkのためのER図
- Object Oriented modelからの導出
- 主要entityからresource
- 階層関係 → URI構造
- link by object reference
- top levelは別に作る
- information architectureからの導出
- information分類の観点: information architecture
- resource oriented architectureと相互補完
- information architectureがinformationを分類し,resource oriented architectureにつながる
作用
- 既存の3つの手法を,serviceとAPIを分けずに用いることで,resourceを導出できる
『Kubernetesで実践するクラウドネイティブDevOps』学習メモ
Ch01 Cloud Revolution
目的
- 3つの革命
- クラウドの創造
- DevOps
- コンテナ
- → Cloud Native with OS:Kubernetes
- revolutionのhistory, 重要性を見て,ソフトウェア deliveryへの作用を考える
- 想定される変化
- Cloud Native DevOpsがtheme
概要
- (1) クラウド
- 処理能力を買う
- SaaS
- Iaas
- Undifferentiated Heavy Lifting(UHL)
- (2) DevOps
- (3) コンテナ
- 依存関係, config
- history, background
- Puppet, AnsibleなどのConfig Management System
- omnibus package
- VM Image
- 問題多い(コスト,不安定)
- 特性: 可搬容量,コストdown, 規模の経済,扱いやすさ
- イメージ fileをコンテナ runtimeで実行
- 仮想化による実行効率downの解決 with real CPU
- file システムのlayerをaddress指定
- → コンテナ間でlayerの共有や再利用〇
- コンテナは再利用の単位
- scalingの単位,リソース配分の単位でもある
- コンテナが依存するのは唯一OSのkernelのみ
- Kubernetes
- history @ Borg
- コンテナをserverのpoolで実行するための割り当てとschedulingを行う集中管理システム
- history @ Borg
- values
- Kubernetesによる従来のシステム 管理 taskのautomate
- デプロイの容易さ
- zero down time デプロイ with Rolling Update
- canaria デプロイ, bluegreen デプロイ in Continuous デプロイ
- auto scale
- 冗長性とfail overでの信頼性と耐障害性up
- cost down by 能力の浪費cut
- クラウド providerと疎である by Kubernetesの抽象化
- コンテナはソフトウェアを定義するための可搬性の方法 & Kubernetes リソースはソフトウェアの実行方法の可搬性のための方法
- Kubernetesの制約
- DBなどのステートフルなworkloadへのcost 大
- → 代わりにmanaged serviceを使用
- Faas, (server served platform). e.g. AWS Lambda
- functionとコンテナのhybrid: Funtainer
- → Knative
- (4) クラウドネイティブ
- 一般的用法: クラウド, コンテナ, orchestrationを活用し,多くの場合OSSをbaseとする,最先端アプリケーションやserviceを簡潔に表現する手段.
- 自動化されたInfrastructure as Code
- 特性
- automate可能
- Ubiquitous and flexible
- resilient(弾力的) and scalable
- dynamic
- Obserbable
- distribution: 分散化,非集中化
- codeを単一のentity(monolithus)としてデプロイ
- or multi 分散 micro servicesで構成
- micro server: 1つのことを実行する自己完結型service
- monolithusの方が理解しやすく,相互作用を追跡できる
- but, monolithusは拡張difficult
- 一般的用法: クラウド, コンテナ, orchestrationを活用し,多くの場合OSSをbaseとする,最先端アプリケーションやserviceを簡潔に表現する手段.
作用
- 運用の観点
- Developer Productivity Engineering(Developer生産性工学), DPE team
- Site Reliability Engineering(SRE)
- Kubernetesの重要性 pointsのまとめ
Ch02 Kubernetes first step
概要
- Docker
- Dockerは複数で異なる but 関連する要素から成る
- コンテナ イメージ format
- コンテナ run time library
- コンテナのlifecycleの管理
- command line tool
- コンテナ 管理用API
- コンテナ イメージ: ZIP fileのようなもの
- 実行のためには,ID or URLを指定するだけ
詳細
(1) コンテナ build
- docker image build with Dockerfile
- Dockerfile specifies all what イメージ has to have
- 既存のイメージ(: base イメージ)にもとづいて新しいイメージをbuild
- multi stage build
- scratch イメージにbuilded binaryをcopy → 軽量化, attack surface(攻撃対象領域)の縮小
- -tによるtagづけ
portの転送
''' -p HOST_PORT:CONTAINER_PORT '''
- docker image build with Dockerfile
(2) コンテナ Registry
- Docker IDをgetし,Docker Hubにオリジナル イメージをpush
- イメージの命名とpush
- → どこからでもコンテナ イメージを実行可能
- (3) Kubernetes
- Enable Kubernetes @Docker Desktop
- demo アプリケーションの実行
- deploymentのcreate
- port forward
- (4) Minikube
まとめ
- コンテナをbuild and runの実践
- Kubernetes環境の確率
Ch03 Kubernetes 環境の選択
目的
- クラスタのbasical structureの理解
- Kubernetesの実行方法を決定するための情報
- managed serviceの長短
概要
- クラスタのarchitecture
- Kubernetesがmulti serverを接続して1つのクラスタとする
- controll plain
- このcomponentを実行するメンバ(ノード): master ノード
- kube-apiserver
- etcd: DB
- kube-scheduler
- kube-controller-manager
- クラウド-controller-manager
- ノードのcomponent @Worker ノード
- kubelet
- kube-proxy
- コンテナ runtime
- 高可用性
- network partitionも処理〇
- controll platformの高可用性の重要性
- quorumを維持
- e.g. 本番クラスタは3つが最小
- quorumを維持
- multi availability zoneへの分散
- testの実施が重要
詳細
- (1) self hosting Kubernetesのcost
- buy or build
- cost 大.engineerの給与約100万ドル
- 初期セットアップから稼働を通してcareが必要
- まずはmanaged service
- (2) managed Kubernetes services
- GKE
- 高可用性
- multi zone/ regional クラスタ
- auto scale
- 高可用性
- EKS
- 後発&割高
- AKS
- OpenShift: PaaS
- IBM Cloud Kubernetes サービス
- HKs
- GKE
- (3) turnkey方式のKubernetes solution
- (4) Kubernetes installer
- kops @AWS
- Kubespray with on-premised install & bare(何も導入されていない) metal server
- TK8 with Terraform and Kubespray
- Kubernetes The Hard Way: 教育に◎
- kubeadm: Kubernetesのinstallに◎
- Tarmak: 変更をノード 設定にrolloutする処理の迅速性と安全性up
- RKE: simple & high-speed
- Puppet Kubernetes module
- Kubeformation: 既存のautomate toolのwrapper
- (5) 原則
- running ソフトウェアを減らす
- standard technologyのuse
- cost 大のタスクはoutsource
- 長寿の競争優位
- → managed Kubernetesの推奨
- クラウドネイティブ: 差別化につながらない要素をoutsourceしビジネスを加速
- self-hostingならkops, Kubespray
- 限られた予算 e.g. Raspberry Pi
- running ソフトウェアを減らす
- (6) clusterless コンテナ service
- Amazon Fargate, ACI
まとめ
- Kubernetes クラスタをservice providerに任せ,確実性と経済性を得る
Ch04 Kubernetes objectの基本操作
目的
- Kubernetesの基本object: Pod, Deployment, サービス + Helm tool
概要
- (1) Deployment
- Superviserの機能 @Kubernetes
- 個々のプログラムに対応
- Deployment Objectを作成
- Deployment controllerによる制御
- Default: コンテナのrestart
- Deployment 情報 get command
- (2) Pod
- 1つ以上のコンテナのグループ ← クジラの群れ
- Podの仕様(spec: specification)のcontainers list
- kubectl run: Deploymentを作成 → DeploymentがPodを起動
- Deployment: 「あるコンテナを持つPodを1つ実行し続ける必要がある」といった,望ましい状態の宣言
- (3) ReplicaSet
- Deployment-ReplicaSet-Pod
- ReplicaSet controllerが必要な数(同一)のPod,ReplicaSetのグループを管理
- → DeploymentがReplicaSetを管理: ユーザのReplicaSetのupdateをcontroll
詳細
- (1) Keep desirable state
- 調整loop
- Deploymentのshutdown
- 調整loop
- (2) Kubernetes scheduler
- DeploymentがKubernetes DBにPod リソースを作成 & Pod into cueue
- → schedulerがPodを取り出してrunnabeなノードを見つける
- ⇔ Podをノードにscheduling
- → kubeletがPodが含むコンテナを起動
- DeploymentがKubernetes DBにPod リソースを作成 & Pod into cueue
- (3) YAML形式のリソース manifest
- Kubernetesは本質的に宣言的
- → continuous reconcliation(調整; cal-, -cli-: 呼び集める)
- → specを変更すればKubernetesが処理してくれる.
- DeploymentやPodなどのKubernetesのリソースはすべて内部のDBのrecordで表現
- 「kubectl run」でnew recordをinsert or 「リソースのmanifestを読み取るよう指示」
- コンテナ イメージの名前とPortが重要
- @DeploymentのYAML Manifest
- ↑→ kubectl runで指定していた
- kubectl applyでmanifestをクラスタに送信
- サービス リソース
- 単一の変化しないIP address or DNSnameを付与
- → 対応するPodへ自動ルーティング
- → Podにnetwork経由でconnect
- Web proxyやload balancerのようなもの
- backendのPodのグループにリクエストを転送
- 単一の変化しないIP address or DNSnameを付与
- サービスのYAML Manifest
- multi Pod → load balance
- 後始末 kubectl delete -f Kubernetes/.
- Manifestのdirectoryをdelete
- kubectlでのクラスタへのquery
- kubectl get
- kubectl describe pod/dem-dev-6c...
- YAML Manifestでの宣言的デプロイにおける繰り返しの解消 → Helm
- Kubernetesは本質的に宣言的
- (4) Helm: Kubernetes package manager
- command line toolでDeployment リソースとサービスをHelmが作成.
- アプリケーションをinstall and configure
- chart: real コンテナ イメージを含まないyaml manifestのwrapper.同じクラスタ内に何度もinstall可能
- アプリケーションをKubernetesで実行するために必要なリソースの定義がすべて格納されるHelm package
- repository: chartの収集と共有
- release: Kubernetes クラスタで実行されるchartの特定のinstance
- helm install -name
- helm list, helm status
- command line toolでDeployment リソースとサービスをHelmが作成.
作用
- 何ができるかを理解
- ↑ PodやDeploymentのメカニズム
Ch05 リソース 管理
目的
- クラスタの最大活用
- リソースの使用状況の管理と最適化など
概要
- リソースの理解
- Kubernetes schedulerの観点
- Podが求めるリソースの量を把握
- リソースの単位: CPU, milliCPU, MiB@memory
- リソース要求: min
- リソース制限: max
- over commit〇: ノードのリソース総量を超えた制限可能
- コンテナのminimize
- Kubernetes schedulerの観点
詳細
- (1) コンテナ lifecycle 管理
- Liveness probe by HTTP
- Probeの遅延と頻度
- death loopの回避
- initialDelaySeconds, periodSeconds
- ほかのtypeのProbe
- TCP, gRPC
- Readiness Probe: 「一時的にリクエスト処理不可能」を知らせる. → 常に「200 OK」を返す必要
- zero downtime upgradeにeffective
- file based Readiness Probe
- minReadySeconds
- Pod Disruption Budget: 失ってもよいPodの数
- minAvailable, maxUnavailable
- (2) Namespace
- (3) クラスタ cost optimize
- Deploymentのoptimize
- serviceが求める処理能力と可用性のビジネス要件
- その要件より少なく達成できるか
- Podのoptimize
- normal 運用のmax + α → リソースのPackman状態の回避
- Vertical Pod Autoscalar
- Nodeのoptimize
- 観察
- 典型的なPodをat least 5個実行数rのに十分なサイズ
- stranded リソース(残されたリソース)の割合をunder 10%
- 10個いじょうなら5%
- Storageのoptimize
- I/O operation 毎秒(IOPS)で観察
- 未使用リソースのclean up
- kubeletのgarbage collection設定を調整
- 所有者metadata Annotationを使用し,Annotationのないリソースを強制終了候補にする
- ↑ すべてのリソースに所有者Annotationを設定
- 使用率が低いリソースの発見
- 受信リクエストの数をPodがメトリクスとして公開
- Web コンソールで各PodのCPUとメモリの使用率の数値をチェック
- finished jobのclean up
- 余剰capacityのcheck
- reserved instanceのuseでのcost down
- preemptive (spot) instance
- preemptive ノードはクラスタ全体の2/3以下にする
- ノード affinityでpreemptive ノードへのscheduling制御
- Kubernetes scheduler: workloadを多くのノードに均等にassign & replicaを異なるノードにおいて高可用性
- schedulerはノード間でPodを移動しない.
- → Deschedulerというtoolでのmove
- schedulerはノード間でPodを移動しない.
- Deploymentのoptimize
Ch06 クラスタの運用
概要
- (1) クラスタのsizingとscaling
- (2) 適合性チェック
- test suite がKubernetesにある
- CNCF認定: Certified Kubernetes, CKA, KCSP
- Sonobuoyでの独自クラスタのtest or managed service
- Sonobuoy Scanner
- (3) 検証と監査
- tool
- (kubernete Guard: Kubernetes クラスタのcommon 問題 check)
- Copper / instrumenta / Conftest
- kube-bench: 不要なことも多い
- Kubernetesの監査logging
- tool
- (4) Chaos Test
- Chaos Monkey Test
- 自動化と継続
- chaos kube
- kube-monkey
- powerful Seal
- → 高可用性を保証
Ch07 Kubernetes's tools
目的
- Kubernetesの作業のためのtoolやutility
- kubectlの高度な使い方と便利なutility
概要
- (1) kubectl
- shell alias
- @.bash_profile: alias k=kubectl
- flagの短縮形のuse
- リソース typeの省略
- kubectlでの自動補完 + aliasでの自動補完
- helpの表示: kubectl -h
- Objectのhelp: kubectl explain {pods, RESOURCE.FIELD, --recursive}
- 詳細な出力の表示
- kubectl get pods -o wide
- JSON形式の出力とjqなどでのfilter (→ jqのinstall)
- or JSON Pathでのquery
- Objectのsupervise: kubectl get pods --watch
- kubectl describe pods demo-xxx・・・
- shell alias
- (2) リソースを使った作業
- (3) コンテナを使う作業
- log: コンテナがstandard output or standard error outputのstreamに書くものすべて
- logの閲覧: kubectl logs -n kube-システム --tail=20 --follow(-f) etcd-docker・・・
- → supervise continuous output
- --tail/--since/--timestamps
- コンテナへのattach
- KubesprayでのKubernetes リソースの監視
- コンテナ Portの転送: kubectl port-forward
- コンテナでのcommand execution: kubectl exec
- debugのためのコンテナ実行
- kubectl run NAME --イメージ=IMAGE --rm(→del after completed) --it(i: 対話型, t: terminal) --restart=Never --command --・・・
- BusyBox(BB) commandの仕様
- 対話型のshell in クラスタ + shell alias → bb
- BBのコンテナへの追加
- BBはたった1MiB
- DockerfileでCOPY --from 命令
- → kubectl exec -it POD_NAME /bin/busybox sh
- コンテナへのプログラムのinstall
- kubesquashでのlive debug(本格的debugger)
- debuggerをコンテナにアタッチ: kubesquash
- with goのdebugger: dlv
- (4) ContextとNamespace
- Context: クラスタ, ユーザ, Namespaceの組み合わせ
- → bookmarkになる
- kubectl: 今のContext
- kubectl config get-context
- kubectxとbubensでContext切り替え高速化
- kube-ps1で現在のContextをpromptに追加
- → [( )]
- Context: クラスタ, ユーザ, Namespaceの組み合わせ
- (5) Kubernetesのshellとtool
- kube-shell: 補完のpopup
- Click: 対話型kubectl
- kubed-sh: クラスタ自体の上でプログラムを実行
- Stern: log
- (6) オリジナル Kubernetes toolの構築
- client-goでkubectlができるすべてを実現
作用
- kubectlで必要なことは何でもできる
Ch08 コンテナの実行
目的
- ~Ch07: 運用
- Ch08: 最も基礎的なObject in Kubernetes: コンテナ
概要
- (1) コンテナとPod
- Pod: Kubernetesでの{minimum デプロイ, schedule}単位
- Pod Objectが{単一/複数のグループ} コンテナを表す
- Kubernetesのすべての実行はPodを使用する
- 同じ実行環境上のアプリケーション コンテナ + storage volumeの集まり
- 1つのPod内のコンテナはすべて同じマシン上に配置
- コンテナ: 1つのソフトウェア, 依存関係, config, データなど,実行に関するものすべて
- 実行の担保はプロセス
- プロセス: 実行するアプリケーションのbinary codeとmemory statusを表現し,同じglobalなNamespaceに存在
- → プロセス間のやり取り〇.同じリソースのpoolを共有
- プロセス: 実行するアプリケーションのbinary codeとmemory statusを表現し,同じglobalなNamespaceに存在
- コンテナ: オリジナル Namespace内にある分離されたプロセス(のグループ)を表現する
- コンテナの内外ではプロセスは隠れる
- 実行の担保はプロセス
- コンテナの構成要素
- Podの構成要素
- Pod: 相互に通信してデータを共有する必要がある
- コンテナのグループを表現
- ともにschedule. 起動終了も同時.同じ物理マシン上で実行
- ⇔ 常に同じノード上で実行
- 異なるマシンで動作しないコンテナをPodでグループ化する
- Pod: 相互に通信してデータを共有する必要がある
- Pod: Kubernetesでの{minimum デプロイ, schedule}単位
- (2) コンテナのManifest
- 複数のコンテナsのtemplate spec
- name, イメージ
- イメージ識別子
- registry hostname, repository Namespace, イメージ repository, tagの4つで構成
- tagの例
- latest tag
- default: latest e.g. alpine:latest
- 本番環境ではlatestは×
- コンテナのdigestで決定的デプロイ
- ←→ tagでの非決定的デプロイ
- base イメージのtag
- 特定のtag/ digestのuse
- Port: Kubernetes上には意味なし.しかし,Manifestには含める
- リソース要求制限
- イメージのpullについてのpolicy: imagePullPolicy
- 基本はIfNotPresent
- 環境変数の設定
- 複数のコンテナsのtemplate spec
- (3) コンテナのSecurity
- principle of least privilege
- bug riskのminimize
- 一般ユーザの割り当て: runAsUser
- UID 1000: first not root ユーザ
- security maximize: コンテナごとのUID
- データを共有するためのアクセス: 共通UID
- runAsNonRoot: true
- readOnlyRootFileSystem: true
- allowPrivilegeEscalation: false
- setuid(権限昇格)のmechanismから守る.
- Capability
- 従来のnormal/super ユーザ問題への対応
- default CapabilityのDropと特定のCapabilityのadd
- 一部のConfigはPodのレベルでも〇
- Pod Security Policy リソースにより,クラスタ levelでsecurityを指定
- Podのサービス Accountの指定
- defaultは,Namespaceのdefaultのサービス Accountが持つpermissionで実行
- principle of least privilege
- (4) Volume
- 同じPodの別のコンテナとのデータ共有 & restart後もデータを永続保持
- emptyDir
- download fileや生成データのcaching
- データ処理ジョブ用のtmpworkspace
- Pod内コンテナのファイル共有
- コンテナへのマウント方法
- PodのVolumes field
- コンテナのvolumeMounts field
- lockはない
- 永続Volume
- DBはほかのクラウドで〇.Kubernetesは×.
- ↑ stateless Kubernetesのため.
- DBはほかのクラウドで〇.Kubernetesは×.
- (5) restart policy
- restartPolicy: Always(default)/ OnFailure/ Never
- → Job リソース
- (6) Image Pull Secret
- registryに認証情報を提供
まとめ
- コンテナの概要
- Pod内でのコンテナの連携
- Kubernetesでのコンテナの実行のコントロール
Ch09 Pod 管理
目的
- Podのfeatureを見る
概要
- (1) Label
- definition: PodなどのObjectにつくkey-value pair
- core システムのsemanticsを直に構成しない.Object識別属性を指定するためのLabel
- e.g. Podが属するアプリケーションをlabeling → documentation
- selectorと組み合わせて価値が生じる
- selector: Label(or Labelのset)との一致条件を記述
- → リソースのグループをLabelでspecify
- 用途
- サービスとPodを接続
- kubectl get ~ --selector(-lでもOK) app=demo
- --show-labelsでLabelを確認
- selector: Label(or Labelのset)との一致条件を記述
- サービスは等価selectorのみ
- Labelの使い方
- staging/real
- カナリアデプロイ track: stable/canary
- Label: リソースを識別 ←→ Annotation: 外部toolやservice
- どちらもk-v pair
- definition: PodなどのObjectにつくkey-value pair
- (2) Node Affinity
- schedulingの選好性の表現
- hard: required ...
- soft: preferred ...
- schedule時のみ
- Hard Affinity
- Podを実行させたいノードの種類を述べる. @nodeSelectorTerms
- Soft Affinity
- weightの指定
- schedulingの選好性の表現
- (3) PodのAffinityとAnti-Affinity
- ノード内のPodの状態をAffinityに反映する
- Podの同居: hard/soft Pod Affinity
- Podの分離: podAntiAffinity
- soft Anti-Affinity
- Pod Affinityでしか解決できない問題にのみ使用
- (4) Taint(汚染)とToleration
- ノードの属性に基づき,ノードがPodを避ける
- kubectl taint ←→ kubectl taint ~-(-: minusでdelete)
- TolerationでTaintにも許容
- e.g. networkが×のときのunreachable
- (5) Pod Controller
- 手動workのautomate
- 主要はデプロイ → ReplicaSetを管理
- デプロイ以外
- DaemonSet: クラスタ内の個々のノードで,Podのcopyを1つだけ実行
- e.g. logging
- StatefulSet: Podを特定の順序で起動・終了
- 番号でPodを識別 to Redis, MongoDB, Cassandra
- Headless サービスでaddress指定
- DaemonSet: クラスタ内の個々のノードで,Podのcopyを1つだけ実行
- Job: Podを指定した回数だけ実行する
- ←→ デプロイ Pod数を指定しcontinuousに実行
- completions
- parallelism
- Cron Job
- Jobのschedule
- Horizontal Pod Autoscaler(HPA)
- needsに応じてKubernetesがreplica数をautoscale
- Vertical: replica自体を大/小化
- CPU使用率などのメトリクス{での決定, の指定}
- システム/service(← ユーザのdefinition) メトリクス
- needsに応じてKubernetesがreplica数をautoscale
- Pod Preset
- admission controllerの一部
- admission controller: objectへの変更を監視.変更の直前にaction
- Pod Presetのconfigは,個々のPodのconfigとmergeされる
- admission controllerの一部
- OperatorとCustom リソース Definition
- ステートフル setを超えたcomplicateな管理が必要なアプリケーションのため.
- (6) Ingress リソース
- (7) Istio
- サービス mesh: 複数アプリケーションsやサービスの相互通信のある環境の運用のための技術
- (8) Envoy
- 高度なload balancer
作用
- Kubernetesの全てはPodの実行にかかわる
Ch10 Config, Secret データ
目的
- Kubernetesのlogicとconfigの分離
- Podのspecでdefineする環境変数で値をアプリケーションに引き渡す
- or ConfigMapとSecret ObjectでConfigをKubernetesに直に保存
概要
- (1) ConfigMap
- KubernetesにConfig データを保存するためのmain Object
- kubectl create configmap demo-config --namespace=demo --from-file=config.yaml で作成
- kubectl getでManifestを出力
- ConfigMapで環境変数を設定
- ConfigMapから環境全体を設定
- encFromでConfigMapから全keyを取り込む
- ←→ envがprior
- encFromでConfigMapから全keyを取り込む
- command argumentで環境変数を使う
- $(VARIABLE)は環境変数のVARIABLEの値で置き換える
- → コンテナのentry pointにcommand line argumentとして与えられる
- $(VARIABLE)は環境変数のVARIABLEの値で置き換える
ConfigMapからConfig fileを作る
'''
データ: config: | greeting: Buongiorno
'''
- |は生データのblockを表す
'''
volumes: - name: configMap: name: items: - key: config path: demo.yaml
'''
Configの変更を伴うPodの更新 @Helm
- Annotationを設定 @デプロイのyaml
- (2) KubernetesのSecret
- (3) Secret Data Management戦略
- 問題
- secret データの可用性のための保存場所
- running アプリケーションがsecret データを使う
- secret データの変更へのrunning アプリケーションの対応
- version 管理でのsecret データのencrypt
- デプロイ時にdecrypt
- secret データのrotationがdifficult
- 容易さ〇,柔軟さ〇
- secret データのremote 保存
- 一元補完
- 手間アリ
- 変更の管理のために監査ログが必要
- workflow必要
- 専用のsecret データ 管理 tool
- 大規模組織のみ
- infrastructureがcomplicateになる.コスト大
- 推奨
- SOPSなどの軽量encrypt toolのuse
- 問題
- (4) SOPSでのsecret データのencrypt
作用
- 必要なconfigやデータをアプリケーションと結びつける方法の理解
Ch11 Security and Backup
目的
- Kubernetesにおけるsecurityとaccess controllの仕組みの検討
- 脆弱性をscanするための代表的toolやservice
- Kubernetesのデータとstateのbackup と復元方法
概要
- (1) access controllとpermission
- クラスタ別のaccess controll
- クラスタ運用者/ アプリケーション developerの2group化
- 本番/ staging
- RBAC(Role-Based Access Control) @Kubernetes
- 有効化
- 確認: kubectl describe pod ...
- 有効化
- Role
- ユーザが持つpermissionの特定のsetをroleが統制
- namespaceやクラスタを対象に
- RoleBinding ObjectでユーザとRoleを紐づけ
- 加法的Permission
- 必要なrole: defined roleのクラスタ-admin, edit, viewでおおよその要件は〇
- クラスタ-admin ≒ root
- not クラスタ 運用者やinternetにopenなservice accountには×
- アプリケーション専用のservice accountに対してRoleBinding Objectでroleを紐づける
- CD toolにのみアプリケーションのデプロイを許可
- "edit" role
- RBACの問題の対処方法
- API serverのログでRBAC DENYを探す
- クラスタ別のaccess controll
- (2) Security Scan
- (3) Backup
- (4) クラスタのstatusの監視
- kubectl
- クラウド providerのconsole
- Kubernetes Dashboard
- securityが重要
- never public internet
- minimumの権限.kubectl proxy経由のaccess
- 不要なら使わない
- Weave Scope: クラスタの監視と視覚化
- kube-ops-view: クラスタ内の視覚化
- ノード-問題-detector: Kubernetesのaddon ノードの問題の検出
作用
- 知識・思考・注意を要するcontinuous プロセス: security
Ch12 Kubernetes アプリケーションのデプロイ
目的
- Manifest fileからアプリケーションを実行
- アプリケーション用のHelm Chartのbuild
概要
- (1) HelmでのManifestのbuild
- fileの保守 + 配布の問題を解決
- 設定値や変数を生のmanifest fileから分離
- ほかのアプリケーションやserviceへの依存関係も公開できる
- Chartの内部校正
- Helm template
- 依存関係の指定 → helm 依存関係 update
- requirements.yaml
- fileの保守 + 配布の問題を解決
- (2) Helm Chartのデプロイ
- 変数の設定
- 追加の値file. releaseにおける値の指定: helm install ~ --values...
- 値の確認: helm inspect values
- Helmでのアプリケーションの更新.何度でも〇
- helm upgrade \<既存のデプロイ>
- 追加の値file. releaseにおける値の指定: helm install ~ --values...
- 指定のversionへのrollback: helm rollback \<デプロイ name> 1
- rollforwardもrollbackで〇
- helm-monitorによるauto rollback
- Helm Chart Repositoryの作成
- 普通はアプリケーション独自のrepositoryに保存のため不要
- Secret by SOPS in Helm Chart
- secret データを値fileにいれ,SOPSでencrypt
- command, 適用手順
- 変数の設定
- (3) Helm fileによる複数 Chartの管理
- (4) 高度なManifest 管理 tool
- ksonnet: 計算やlogicが必要な大規模でcomplicateなデプロイに〇
- → projectが中止
- Jsonnet: JSONの拡張.KubernetesはJSONも〇
- prototypeの導入: よく使われるManifest pattern
- Kapitan
- 設定値の階層DB: inventory
- → 環境やアプリケーションに合わせて異なる値でmanifest patternを再利用
- 設定値の階層DB: inventory
- kustomize
- plainなYAML
- overlayでパッチとして適用
- kustomize build ~ | kubectl apply -f ~
- kompose
- docker-compose.yml: 連携して機能する一連のコンテナを定義, and デプロイ + コンテナの通信方法を定義
- → Kubernetes Manifestに変換するtool
- Ansible
- 混合infrastructureの場合に強力
- Kubernetes クラスタのinstallと設定
- Kubernetes moduleでデプロイやサービスなどのKubernetes リソースを直に管理
- kubeval
- Manifestの検証 to schema by version
- CD パイプラインへの追加が〇
- Conftestも〇
- ksonnet: 計算やlogicが必要な大規模でcomplicateなデプロイに〇
作用
- Kubernetesでのデプロイの簡単化
Ch13 Development workflow
目的
- localのdevelopmentからKubernetes クラスタへの更新のデプロイまでのアプリケーションのlifecycleを扱う
概要
- (1) development tool
- Skaffold: development workflowのspeed up
- skaffold.yamlにworkflowを定義
- → skaffold command line toolの実行でパイプライン start
- Draft
- Skaffoldと同様, by Azure team
- Draft Pack: アプリケーションが使用する言語に対応したDockerfileとHelm Chart
- draft init && draft createで言語を特定
- リソースの適用: draft up
- Telepresence: local machineをremote クラスタに参加させられる
- Knative: 開発中. コンテナ化されたアプリケーションやserverless styleの機能を含めたあらゆるworkloadをKubernetesにデプロイ
- KubernetesとIstioの両方と統合
- build プロセスのsetup, デプロイ のautomate, Eventing
- Skaffold: development workflowのspeed up
- (2) デプロイ戦略
- zero downtime デプロイ → ユーザのリクエストに対応するアプリケーションでは必要
- Rolling Update( 0 downtime ) ←→ Recreate (high speed)
- デプロイ Manifestで定義
- default: RollingUpdate
- minReadySecondsでroll outをPodの安定まで待機. @RollingUpdate
- MaxSurgeとmaxUnavailable: 基本は変える必要なし
- blue green デプロイ
- サービスからtrafficを受信するPodを決定するため,Labelを使う
- → サービスのselectorのdeployment fieldに設定
- blue, green, ... → rainbow デプロイ
- canaria デプロイ → Istioを使うと高度なデプロイが〇
- (3) Helmでの移行
- DBがかかわるときに必要な「移行」
- Job リソースで実現
- Helmのhookで可能
- Job リソースで実現
- Helmのhook: デプロイ中の処理準をcontroll
- JobのAnnotationで指定
- 失敗にも対応〇
- pre-upgrade以外のhook
- hookのchain化: 複数 hooks をchain化 by order
- helm.sh/hook-weight propertyを使う
- DBがかかわるときに必要な「移行」
作用
- Kubernetes アプリケーションの開発の高速化. by tools
- 変更の本番環境へのrooloutが容易
Ch14 KubernetesでのCD
目的
- CDとCDのKubernetes based クラウドネイティブ 環境での実現
- Kubernetesと連携して動くCD パイプライン
- コンテナ化されたアプリケーションのパイプラインの典型
- codeの変更をgit repositoryにpush
- build システムがbuild & test
- test ok → コンテナ イメージがコンテナ Registryに対してpublish
- new builded コンテナがautomatically デプロイ to staging 環境
- automatic acceptance test in staging 環境
- tested コンテナ イメージ tobe デプロイ to production 環境
- デプロイの対象の成果物は〇コンテナ, ×Source Code
対応
- (1) CD tool
- (2) CDのComponent
- 既存のCDにコンテナ用Componentの追加のe.g.
- Docker Hub
- Gitkube: self hosting. simple + 可搬性〇.setupも間t何
- Flux: with GitOps extended
- Keel ≒ Flux
- 既存のCDにコンテナ用Componentの追加のe.g.
- (3) CD Pipeline のe.g. by Cloud Build
- Google CloudとGKEのセットアップ
- test run
- アプリケーション コンテナのbuild → アプリケーション コンテナの作成
- Kubernetes Manifestの検証
- イメージのPublish
- Git SHA tag @成果物 → Codeのsnapshotになる
- triggerの作成: 監視target Git Repository, active化の条件, パイプライン fileの指定
- triggerのテスト
- CD パイプラインからのデプロイ
- Kubernetes クラスタへの認証情報の獲得
- ユーザ definitionの置換
- 環境 tagの追加
- クラスタへのデプロイ
- Kubernetes クラスタへの認証情報の獲得
- デプロイ triggerの作成
- tagのpushでtrigger
- 代入変数
- Build PipelineのOptimize
- コンテナ based CD Pipeline toolは,各stepのコンテナをminimize
- multi stage buildでオリジナル custom イメージをbuild
- コンテナ based CD Pipeline toolは,各stepのコンテナをminimize
作用
- アプリケーションのためにCD Pipelineをsetup → 一貫した方法と高い信頼性でソフトウェアを迅速にデプロイ
Ch15 オブザーバビリティと監視
目的
- オブザーバビリティと監視の関係
- Kubernetesでの監視,logging, メトリクス tracingの扱い
概要
- (1) オブザーバビリティ
- 監視を超えた概念
- 監視
- automatic 監視 @DevOps
- blackbox監視
- up/down test
- logging: 中央DBに集約 → 問題のtrouble shoot
- limit: developerのjudgeで作成.query difficult, signal/noise比が△
- scale difficult
- logを超えた方法が必要 → Metrics
- メトリクスの導入
- @アプリケーション's メトリクス
- @Infrastructure's メトリクス
- プロセス/コンテナのCPU使用率
- ノードやServerのdisc I/O activity
- machine, クラスタ, load balancerのI/O network traffic
- メトリクス: 「なぜか」の解決に有用
- 予測にも使える
- アプリケーションを内部から監視
- 実際の動作に基づいてシステムの隠れた側面に関する重要 情報を外に伝えられる
- → 〇内からの監視/ ×reverse engineering
- tracing @分散 システム
- メトリクスやtracingなど全体をカバーした用語としてのオブザーバビリティ: システムがなぜ正しく機能しないのかの理解
- ←→ 監視: システムが正しく機能しているかどうか
- データについてのオブザーバビリティも重要
- 不透明なソフトウェアを測定
- Codeのdevelopmentとproduction 環境での大規模実行との間のloopを縮める重要 tool culture
- (2) オブザーバビリティ Pipeline
- bufferによる統合 with standard メトリクス style by structured データ
詳細
- Kubernetesでの監視
- 外部からのblackbox check
- 監視はユーザの挙動を模倣
- 外部からサービスの可用性を監視 vs 機能停止: Monitoring as a サービス
- 既存サービスを使用する(安価 or freeのため)
- 内部health check
- ユーザ's happinessが観点となる
- @コンテナ
- × Liveness check
- 〇 Readiness check to 依存関係 failures
- circuit breaker pattern
- elegant 劣化とする
- 外部からのblackbox check
作用
- クラウドネイティブ環境で監視が目指すべき方向性
- オブザーバビリティの価値 with メトリクス
Ch16 KubernetesにおけるMetrics
目的
- Metricsの扱い方
- Metricsとは
- 特定の対象を測定した数値
- → 特定の瞬間における状況のsnapshot + 変化を示す
- 時系列データ by sampling
- メトリクス値: Counter/Gauge
- Counter: increment only or reset to 0.
- 量の表現
- Gauge: 増減〇. memory使用率など
- 比率の表現
- Counter: increment only or reset to 0.
- 異常やfailureの通知 + 機能状況の表示
- → 「なぜか」の解決
- 特定の対象を測定した数値
概要
- (1) 優れたメトリクスのchoice
- メトリクスの一部へのfocus
- 要件ごとのオブザーバビリティのためのメトリクス pattern
- service: RED pattern
- リソース: USE pattern → 性能問題の分析とボトルネックの発見のためのbottom up型の方法 ←→ service
- :システムの健全性のcheck, 高速で可視性高い
- Utilization: 使用率
- Saturation: 飽和度
- Error
- 対象は〇リソース/ ×Service
- → システム 性能のbottleneckの発見
- e.g. CPU, disc, networkのIFやLink
- → システム 性能のbottleneckの発見
- ビジネス メトリクス
- 加入者についてのデータの把握
- funnel analysis
- 解約率
- 収益/顧客
- help, support pageの有効性
- System Status pageへのtraffic量
- funnel analysis
- 共通のdatalakeを使用 in two or more groups
- 加入者についてのデータの把握
- Kubernetesのメトリクス
- クラスタ healthのメトリクス
- ノード数
- ノードのhealth status
- Pod数/ノード or Pod数 in all
- リソース使用率, 割り当て by ノード or 全体
- クラスタ healthのメトリクス
- デプロイのメトリクス
- デプロイの数
- デプロイごとのreplicaの設定数
- デプロイごとの利用不可のreplicaの数
- コンテナに関するメトリクス
- コンテナ/Podの数 by ノード or 全体
- リソース使用率 to リソース要求/リソース制限
- コンテナのLiveness/Readiness
- コンテナ/Podのrestart 数
- 各コンテナのnetwork I/O traffic and error
- アプリケーションのメトリクス
- アプリケーションの機能による
- 性能や可用性の問題のため
- アプリケーションの実行内容,頻度,処理時間
- とりあえず不明なら記録する
- SLOやSLAに対するアプリケーションの性能も知る
- runtimeのメトリクス
- プロセスのrun statusを知る
- 6こ
- 性能の劣化やcrashについての診断に〇
- プロセスのrun statusを知る
- (2) メトリクスの分析
- (4) メトリクスのdashboardによるグラフ化
- (5) メトリクスに基づくアラート
- アラートの問題
- 分散 システムは完全upにはならない
- S/N比を高める必要
- アラートは,直ちに人間が対処すべきもの(という単純な事実)のみ表すべき
- いずれ対処 → mail, chatでのアラートでよい
- OnCallの負担の軽減の重要性
- アラートは緊急かつ重要で対処可能なもののみ
- → 一握りのメトリクスに限定
- → そうでないものは非同期通知
- 要因についてのメトリクス
- アラートの問題
- (6) メトリクス 管理のtool, サービス
- OSSが優秀
- Prometheus: defact standard with Kubernetes
- scraping(収集) プロセスでautomaticにメトリクスを収集
- Helmでcommand 1つでKubernetes クラスタにinstallできる
- simpleな構成・仕組み
- pull type の監視
- Grafanaなどで,Prometheusで収集・保存した情報を活用
- → 時系列データのグラフ化
- Alertmanager
- 重複排除 → アラートのグループ化 → 通知serviceにルーティング
- Open メトリクスのbaseとなっている
- その他のtools
作用
- proper データの収集 → proper方法で処理 → properな問題の解決に活 → proper方法でvisualize → properな事項をproperな対象者にアラート
『パーフェクトRuby on Rails』学習メモ
Part1 Rails overview
Ch01 Ruby on Railsの概要
- Rakefile
- rake -T : タスク一覧
- rake (taskname) : タスク実行
- bundle
- gem packageを束ねる
- Gemfileが作られる.
- Railsの思想
- Web application開発のためのframework
- CoC(Convention over Configuration)
- 設定より規約
- 規約により設定が不要になる.
- DRY
- REST(REpresentational State Transfer)
- 自動テスト
- まとめ
- Railsをはじめよう
- rails new (project name)
- 重要なファイルなど
- binstubファイルとして,binにbundle exec省略可能なコマンドを置いている.
- MVC architectureとして,appディレクトリ以下にmodels, views, controllers + Viewで使うhelpers + assets for frontend + others
- rails s: Web applicationを起動. s: server
- libは,独自に実装したRakeタスクなどを配置するのみ.かつては,独立性の高いコードを置く運用もあった.
- よく使うrailsコマンド
- routes: display routing information
- runner: 処理を明確にするため,Rakeとは個別のコマンドとして用意された単体スクリプトの実行
- rails new (project name)
- scaffold(足場)
Ch02 Ruby on RailsとMVC
目的
内容
- MVC architecture
- Model
- DBとの接続とデータに対する操作,およびビジネスロジック
- View
- Modelの内容を参照し,視覚表現を行う
- Controller
- Modelのロジック呼び出し,必要なViewの選択など,ModelとViewをつなぐ部分
- モデルの基礎と考え方
- modeling: システムを作ることは,解決する問題に対して必要な概念を探して,命名・関係性の整理を行うこと.
- ActiveRecordでのmodelのimplementation
- ActiveRecordでのmodelの役割
- DBのrecordとActiveRecord objectを結びつける
- ActiveRecordの内部のActiveModelというモジュールにより,ビジネスロジックの実装的な振る舞いの部分を実行する.
- ActiveRecordでのmodelの役割
- modelとCRUDとの対応.
- Model
- modelを扱う
- modelを通じた検索
- ActiveRecord::Relationクラスについて
- ActiveRecordのQuery Interfaceによる操作結果をオブジェクトとして表現するもの
- SQLの情報を保持し,実際に必要になったときのみDBにアクセス.
- 明示的にSQLを発行するときは,to_a method
- Scopeで,よく使う検索条件をまとめて命名
- nilを返す必要があるときはクラスメソッドで定義する方が〇
- default_scopeは安易には使えない
- ActiveRecord::Relationクラスについて
- model同士のrelation
- 関連付け
- SQLite3のための対応必要.
- has_many, has_one, belong_to
- 多対多
- 中間テーブルが必要.
- 関連付け
- dataの更新
- create, save
- validation
- !をつけるとvalidation失敗時に例外発生
- callback
- callbackpoint
- enum
- !, ?
- modelを通じた検索
- controllerの役割
- hook
- CSRF(Cross Site Request Forgeries)対策
- resources routing
- exception
- rescue_from
- StrongParameters
- Mass Assignmentで利用できるHashのkeyの許可リストを定義する
- 権限の扱いなど
- controllerとviewの協調と,view templateの基本
- renderingまでの流れ
- contentsのtypeに合わせる
- respond_to
- redirect_to
- 部分テンプレート, layout
- variantsによるtemplateの切り替え
- about view template
- Prefixの値 + _path で,routingで定義したpathを取得できる
- _urlでは,ドメインなども含んだ完全なURL
- helper methodの活用例
- url_for
- link_to
- form_with
- stylesheet_link_tag, javascript_pack_tag
- その他
- 独自メソッド定義
- app/helpers
- escape 処理
- XSS対応
- そのまま表示 → raw
- XSS対応
- template engine
- API server として振る舞うときのviewについて
- Prefixの値 + _path で,routingで定義したpathを取得できる
まとめ
- Model層について,ActiveRecordの基本的な操作,validation,callback
- Controller層について,ModelとViewをつなぐこと,request objectやaction callback,脆弱性への対処
View層について,受け取ったModelを表示すること,template engine, helper method,様々なformatでの表示
applicationの主要なlogicはなるべくModelに書くべき
- Fat Modelへの対応必要.
Ch03 Railsのbasic機能
- testの種類と実行方法
- RackとRailsの関係
- Rack: Web application serverとWeb application frameworkの中間において,interfaceを共通化した仕様・実装
- 疎結合なやり取りを行えるようにするもの
- Rack application: call methodから受け取ったHTTP request dataなどを元にresponceとして返す内容を決定し,call methodの戻り値とするもの
- Rack middleware
- middlewareは,initializeで後続として処理していくapplication(or middleware)のオブジェクトを受け取り,自身のcall methodが呼ばれたときにinitializeで受け取ったオブジェクトのcall methodを呼ぶことで,後続処理を行うという流れ.
- Pylonsの説明にある玉ねぎの図
- config内で,使用の有無を管理
- middlewareの上下関係の設定もできる
- Rack: Web application serverとWeb application frameworkの中間において,interfaceを共通化した仕様・実装
- DBの管理
- 秘密情報の管理
- versionごとに管理方法が異なる
- より開発プロセスにあった形になっている.
- HTTPとRails application
- Early Hints
- 200 OKの前に,103 Early Hints
- HTMLのパース中にアセットのロード可能
- 200 OKの前に,103 Early Hints
- CSP(Contents Security Policy)
- config/initializers/content_security_policy.rb
- nonce
- strict-dynamic
- Early Hints
Part 2 Railsの周辺知識
Ch04 frontendの開発手法
- Railsで利用するエコシステムの軸をfrontend開発の標準的な仕組みに移している.
- JSを管理
- CSSや画像の管理
- 自動ビルド
- ビルド方法の切り替え
- libraryの統合
- plugin, loaderの追加
- CSSの管理
- 控えめなJS framework
- Stimulus: 規約をもたらすframework
- server sideにbusiness logicの実装が寄る
- HTMLはサーバから返す
- server sideとfrontendを合わせたトータルの工数が少ない
- frontendで表現できる幅が狭まる
- server sideにbusiness logicの実装が寄る
- Stimulus: 規約をもたらすframework
Ch05 Rails標準の機能を活用して素早く機能実装する
- Active Jobによる非同期実行
- mail sending, data集計→CSVファイル作成などの時間がかかる処理に使う
- 実装,キュー,引数,バックエンドの設定,複数キューの管理,ジョブの例外処理,ジョブのテスト
- Active Storageによるファイルアップロード
- 動作,設定
- サムネイルの生成
- access制限
- direct upload
- helperの不足
- cacheの不足
- Action Mailerによるメール送信
- 使い方,動作確認
- 設定
- test
- Action Mailerによるメール受信
- 対応サービス
- 事前準備
- projectの作成
- 処理の流れと実装手順
- test
- Action TextによるRich text 機能
- 使い方
- N+1問題
- customize
- Action Cableによるreal time通信
- web socketを使ったリアルタイム処理
- chat serviceの作成
- config
- 認証
- worker数の設定
- UT
Part3 Web Application development
Ch06 Rails application development
- Railsの機能をいつどのように使うか,一般的なWeb applicationを開発する際に気を付けるべきポイントを見る
- event notify applicationを作る
- applicationの作成と下準備
- OAuthを利用して「GitHubでログイン」機能を作る
- GitHub applicationの登録
- ログインのための機能の作成
- user model作成
- ログイン処理の作成
- ログアウト処理の作成
- event registration機能の作成
- eventの閲覧機能を作る
- l: localize
- eventの編集・削除機能を作る
- 関連を利用する
- 登録されたeventへの参加機能,参加キャンセル機能を作る
- 退会機能を作る
- 基本の7つ以外のアクションを作りたくなったら別のコントローラを作る.
- おわりに
- なぜこのような機能があるのかが重要
Ch07 Rails applicationの test
- test codeをどう書いていくか
- minitest, RSpec
- test data作成
- factory_bot
- sequenceで,固定値を回避
- 乱数を同じにする場合はseedをオプションで指定する.
- factory_bot
- system test
- 環境の問題の解決が必要@wsl2
- controller test
- 権限のテスト
- viewのテストはシステムテストで集約することが多い
- model test
- stub, mock
- ランダムな値で都合のいいデータを回避
- validationのテストの扱い
Part4 Rails applicationの拡張・運用
Ch08 Rails application 拡張
- file upload機能の作成
- libvipsを使う
- direct upload時のvalidationは注意点アリ
- gemで機能拡張する
- Kaminari: pagenation
- searchkick
- https://www.elastic.co/guide/en/elasticsearch/reference/current/targz.html
- 単純な検索はGET, 複雑な検索フォームならPOST
- その他の機能
- error handling
- rescue_fromは後に登録したものから順番に判定
- Rack Middlewareを使ったerror handling
- 独自の例外でpublic/500.html以外を表示したい場合に設定する
- dynamic error pageのdemerit
- routingの制限
- error handling
- gemの選定
Ch09 コードの品質を上げる
- CI
- GitHub actions
- Elasticsearchとplugin
- GitHub actions
- gemの定期更新
- Dependabot
- static analysis
- coverage測定
- SimpleCov
- Coveralls
- Application Performance Measure(APM)
- Skylight
- rack-mini-profiler
- localで手軽に動かせる
Ch10 containerを利用したRails applicationの運用
- Rails applicationのinfrastructure概要
- Infrastructure as Code → Docker
- Disposable
- 基本的なDocker imageの構築
- 開発環境におけるDockerの活用
- ホストマシン上のdirectoryをコンテナ上にマウント
- docker-compose
- 環境によって可変する設定値や秘匿情報の管理
- log出力
- stdout
- error tracking
- 外部サービスをuse
- HTTP serverとの通信
- nginxなど,速さ,扱いやすさなどで必要
- Herokuのガイドなど
- kubernetesについて
Part5 expert Rails
Ch11 複雑なドメインを表現する
- architecture patternから見るRails
- domain modelとActiveRecord
- RailsではデータストアにRDBを想定
- ActiveRecordというarchitecture patternを用いて,DBのレコードとオブジェクトを対応付け
- RailsではデータストアにRDBを想定
- what's ActiveRecord
- 単一table継承
- あるクラスから派生するすべてのサブクラスを1つのtableに対応させる
- type columnで,各レコードがどのクラスに属するか識別
- 扱いがほかのカラムと異なる
- type columnで,各レコードがどのクラスに属するか識別
- 継承の是非の検討が必要
- あるクラスから派生するすべてのサブクラスを1つのtableに対応させる
- domain modelとActiveRecord
- value object
- entity: 属性の値にかかわらず一意に識別
- 値objectに切り出す
- composed_of
- service object
- 複数のobjectを組み合わせて表現するとき
- eventで表現できる場合はeventで表現する
- test doubleを使えないdemeritあり
- 実装rule, interface
Ch12 複雑なUCを実現
- UCとmodel
- DBと紐づかないmodelを作る
- UCのlogic の分離
- ActiveModel
- DBに紐づかないmodel
- Attributes, Callback
- Serialization
- attributes
- Validations
- Model
- controller, viewのメソッドでobjectを使えるようにする
- form object
- UC logicを実装するobject, application serviceやInteractor, にform_withとの連携に必要なIFを持たせたもの
- Userとのやり取りに用いるformを簡単に実装できる
- 共通のvalidation ruleの定義
- UC logicを実装するobject, application serviceやInteractor, にform_withとの連携に必要なIFを持たせたもの
- presenter
- view helperの問題点への対応
- a.c.a. Decorator
- ActiveDecorator
Ch13 複雑なデータ操作を実装する
- Concern
- data 操作に関するlogicの実装と関連付けの宣言を行うlayer
- ActiveSupport::Concern
- included, class_methods, module間の依存関係解決
- @routing
- Callback Object
- 実装方針
- 更新系はCallback Object
- for test
- 参照系には利用できない
- 更新系はCallback Object
- 実装方針
VSCodeでGitを使うときに覚えておくこと
VSCodeでGitを使うときに覚えておくこと。
https://qiita.com/y-tsutsu/items/2ba96b16b220fb5913be
コマンドパレット:ctrl+shift+P
リポジトリの初期化 or clone
ファイル追加→ステージング
コミット
コミットログの確認
ブランチの作成
画面の左下のブランチ名(master)が表示されている個所をクリックし,新しいブランチを作成
マージ
まずはmasterに切り替え
Git Historyでマージ元となるnew-branchの右にあるアイコンをクリックしてMerge this commit into current branch
マージ後のブランチの削除
リモートリポジトリの作成
git remote add origin (remote URL)
origin:リモートリポジトリの識別子
リモートへのプッシュ
git push -u origin master
ログからのブランチの作成
競合、部分コミット
(フェッチ→)プル
gitignore
GitHub実践入門はP200から読む。 GitよりもGitHubの方がメインとなっていると思う。 ワークフローについて。