『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でも使われている
    • 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の取得のためのnetwork protocol
      • (表)
      • 内部的な手続き
          1. URLに含まれるhostnameの解決
          1. HTTPによる取得
          2. 2-1. TCP connectionの確立
          3. 2-2. (@HTTPS) TLS connectionの確立
          4. 2-3. HTTP requestの送信とHTTP responseの受信
      • IPについて
      • TCPについて
      • TLSについて
      • UDPについて
        • QUIC protocolなどで使われている
      • HTTPについて
      • DNSについて
    • 各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
          • img: 画像.link: CSS.script: JavaScript
      • CSSの読み込み
        • CSS: HTMLで記述されるDocumentの内容や構造に対して装飾を加える
        • 要素を指定するCSS selectorと,それらに適用するCSS propertyと値の組を宣言する
        • link: 外部CSS fileを宣言.style: HTML file内部に埋め込まれたCSSの読み込み.
        • rendering engineがparse → CSSOM(Object Model) treeに変換
        • CSSOM treeはrendering engineの内部表現だが,JavaScriptからaccess
  • JavaScript 実行 -Scripting
    • JavaScriptの実行: 最初にJavaScriptファイルを読み込んだとき + DOMイベントが発火しevent listenerが起動するとき
    • 字句解析と構文解析
    • compile
      • 抽象構文木 → 実行可能な形式
      • JIT compile型が多い ←→ 仮想マシン用コードへの変換
        • JIT compile型: その処理系が動作しているマシンのCPUが直接解釈できる機械語に変換
          • 実行時のperformance〇
          • multi platform対応difficult
          • compile時のoverhead大
        • JIT(Just In Time) ←→ AOT(Ahead Of Time)
    • 実行
      • JavaScript内では,DOM APIを通じてDOM treeを操作
      • 後続のRendering, Painting phaseやLoading phaseを引き起こす
  • Layout tree構築 -Rendering
    • Calculate Style + Layout
    • Calculate Style
      • すべてのDOM要素に対して,どのようなCSS propertyが当たるのか計算
      • CSSOM tree内をすべて参照して,CSS selectorのCSS ruleのマッチング
      • CSS rule のmatching
        • CSS selectorのmatching
          • ある要素の親要素や同じ階層の要素に条件をつけるCSS selectorがある
            • e.g. body > .container > .button
            • selectorを右から左に解釈してmatching
        • 適用されるCSS propertyの算出
          • DOM要素に適合する複数のCSS rule setを,詳細度でソートしてスタイルを計算する.
          • 詳細度は,CSS selectorにより決定.
            • p.41 表に,selectorと詳細度の対応がある
          • 詳細度が大きいほど優先.同じときは,後に宣言されたものが優先.
          • 要素のstyle属性に記述されたCSS ruleは,どのCSS rule setよりも優先
          • CSS propertyに付加する!importantはstyleよりさらに優先される
          • Specificity Calculatorで確認できる
    • 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.
  • 再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の使用を控える
      • JavaScriptCSSは外部ファイル化する
      • 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の読み込みを遅らせるのが〇
  • 計測手段
    • 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による計測
    • AndroidでのChrome DevToolsの利用方法
      • PCとAndroidをUSBで接続する
    • WebViewを使う場合
      • minimum code for Android application内でWebViewを呼び出しつつChrome DevToolsを利用するactivity
    • 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割り当ての確認ができる
  • 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
    • Performance Observerによる監視
      • これから起こる処理のperformance informationを指定して監視
      • 柔軟にperformance informationを取得
        • SPAなどinteractionを多く持つようなWeb pageでのperformanceも容易に取得〇
        • 記録・解析のためにreal timeでserverに送信も〇
      • modern browserの中では,Google Chromeのみ対応
    • 高精度なtimestampを得る
      • performance.now()とDate.now()の違い
        • performance.now()は高い信頼性と精度
        • performance.timing.navigationStartからの経過時間を返す
        • 浮動小数点 ←→ 整数
          • FPSの算出など高い精度が必要な計算や,animationの同期処理を行う場合などで有効
  • performance diagnostics tools
    • performanceの改善のための助言ができるtool, service
    • 詳細は分からないが,best practiceとの乖離が分かる
    • Audits @ Chrome DevTools
      • 数clickだけの操作で手軽に行える
    • PageSpeed Insights
      • onlineでURLを入力
    • Lighthouse
      • PageSpeed Insightsと近い用途だが,CLI toolの提供や結果のexportの容易さなど,定期的な実行により適している部分がある
      • PWAへの準拠度や,accessibility対応の計測も〇
  • performanceの継続的監視
    • 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は最小化されているものを使っても〇
  • proper image typeを選択
    • 写真: JPEG, simple animation: GIF, others: PNG
  • 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の発火前に実行
      • 実行順を保証
    • async attribute
      • JavaScriptのdownload時点で実行される
      • 実行順を保証しない
        • 依存関係は,ファイルの結合などで解消が必要
    • JavaScriptでscript要素をasyncに読み込む
      • 読み込むtimingを細かく制御したい場合など
    • async 読み込みの利用方針
      • asyncが一番performance〇
      • asyncがダメならdefer
      • deferもダメなら通常のscript要素
  • device pixel比ごとに読み込む画像を切り替える
    • srcset
    • さらにresponsive対応をするなら,pictureやsizes
  • CSSのmedia queryを適切に指定する
    • FOUC(Flash Of Unstyled Content)の回避のため,renderingの前にCSSの取得と読み込みを待つようになっている
    • link要素のmedia属性を適切に指定することで,screen以外のCSS fileの読み込みがrenderingをブロックしないようになる
      • CSS内でmedia属性を指定することよりよい
  • CSS spriteを使って複数の画像をまとめる
    • HTTP requestを減らす
    • まとめた画像の一部を切り取って表示
  • CriticalCSSで最初の描画を最適化
    • CSSをinline化
    • 最初の描画に必要なCSSをstyle要素に書き出す
    • CriticalCSS以外のtoolもある
    • ほかの最適化techniqueではperformanceが不十分なときに検討
  • resourceを事前読み込みしておく
    • DNS pre fetch(dns-prefetch)
      • 対象のpageをホストしているドメインには意味ない
    • resourceの事前読み込み
      • link rel="prefetch"
    • Web pageのpre rendering
      • link rel="prerender"
      • landing pageやpage送りのnavigationがあるときなど,遷移先が限られているときに〇
    • connectionの投機的開始
      • link rel="preconnect"
    • 事前読み込みするresourceの動的追加
      • 事前読み込みのtimingを制御
  • Gzip圧縮を有効にする
    • HTTP response内のContent-Encoding: gzip
    • Apacheでの圧縮の指定方法
    • 画像や動画など圧縮済みのものは回避要
    • HTTP response headerをdeveloper toolで見ることで圧縮の確認ができる
  • CDNを用いてresourceを配信する
  • domain sharding
    • 多くのmodern browserでは,hostごとの同時connection数の上限は6
    • CDNなどでresourceを配信するhostを複数用意
    • DNSの名前解決にかかる時間は増える
    • HTTP/2ではあまり意味がない
      • 1つのconnectionで並列にrequest/response
  • not redirect
    • directoryの名前で終わらず,/をつけるかファイル名を明示する
      • directoryの名前で終わると,/をつけたURLにredirectされる
  • 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
  • Service Workerの使用
    • JavaScriptからcacheの制御を柔軟に実行可能
    • Web Workerの一種で,main threadとは別threadで動作
    • Web pageとWeb server間でproxyのように動作し,resourceをcacheから取得するかWeb serverから取得するか決定
    • Service Workerの導入
      • https or localhostのみ〇
      • code例
      • offlineに対応したWeb applicationの開発もできる
      • cacheの制御やresourceの取得も柔軟にcustomize〇
      • cacheでresourceのload時間を短くしたい場合にも有効
      • 対応browserは限定的なので,HTTP headerによるcacheをまず適用したうえで実施する
    • 廃止される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が行う構成を取れる
  • QUIC protocol
    • UDP上のnetwork protocolで,QUIC protocolの上でHTTP/1.1やHTTP/2 protocolを使える
    • merit
      • connection開始時のlatencyの削減
        • tokenの使用による
      • Head-of-Line Blockingの削除
        • 再送を個別のpacket単位で行う
    • UDP上でありながら,TCPのpacket loss検出や誤り検出ができ,TLSの盗聴・改ざん防止もできる
    • 書籍が書かれた時点では,Google Chromeのみ対応
      • Googleのserviceでは使われている
  • 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上での処理が始まる.
        • 例外
  • JavaScriptのbottleneckを特定する
    • Performance panelによる計測
      • rendering engineの行うほとんどの処理のprofileを取れる
        • JavaScript, UI threadのrendering, DOM eventの処理など
        • JavaScriptでは,どの関数でどのくらい時間がかかっているか細かくわかる
      • performance diagnosticsなら,まずはPerformance panelでprofileを取る
    • 各処理の確認方法
      • 警告箇所と,ほかの処理の妨げになっているところや明らかに処理時間が長いものを見ていく
  • 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の検知
      • memory leakの検知と同じ
      • 不要になったDOM要素はGCで初めて回収される → profileを取り終える前に,Performance panelの左上のゴミ箱マークで,GCを発動させて不要なDOM要素の解放が必要.
  • 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
    • 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で行う
  • 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の利用
    • SIMDJavaScriptから扱えるAPI
    • SIMD: Single Instruction Multiple Data
      • 複数の値の計算を一度に行う
      • data levelでの並列計算
      • x86ではSSE(Streamed SIMD Extensions), ARMではNEONという命令セットがある
        • SIMD.jsのAPIは,内部でこれらの命令を使う
    • 利用方法
    • 算術演算の一覧
    • 高速化の目安
      • 4つを一度に計算しても2~3倍程度
    • 標準化と対応browser
      • WebAssemblyに置き換えられていき,正式な仕様にはならない見通し
  • 高頻度で発火する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で使える
  • 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情報を参照する
  • DocumentFragmentの追加
    • Web pageのdocumentの断片を表す
    • DOM treeへのDOM要素の追加を速くできる
    • 複数のDOM要素を格納〇
  • Intersection Observerで効率的に交差を検知する
    • あるDOM要素と親要素が視覚的に交差しているか監視
    • 使い方
    • not supportedなら,scroll eventで処理したりしないといけない.問題がある.
  • canvas要素の2D Context animation
    • 特徴
      • requestAnimationFrame()やsetTimeout()で一定時間ごとにcanvas要素の再描画が必要
    • sub pixelを避ける
      • あらかじめ整数値に変換しておく
    • 描画結果のcache
      • prerenderingとも呼ぶ
    • canvas要素をlayerとして使う
      • 必要な前景layerでのみ描画
  • requestAnimationFrame()を活用する
    • setTimeout()やsetInterval()の課題
      • proper timingでcallbackの呼び出しがdifficult
    • requestAnimationFrame()によるanimation
      • 自動的に呼び出しtimingを最適化
      • 指定したcallbackを,browserのrenderingの処理に合わせて,proper timingで呼び出し
  • JavaScriptからCSS Transitionを使う
    • animationの進行中はJavaScriptのコードは一切実行されない
      • requestAnimationFrame()とは異なり,JavaScriptがbottleneckにはならない
    • UI threadとは別のthreadで実行
    • rendering engine内部で最適なtimingで実行される
  • WebGL
    • GPUを用いた高速なgraphic処理のためのcross platformなAPIであるOpenGLのうちの,OpenGL ES2.0をbrowser上から利用するためのAPI
    • library
  • WebCL
    • GPUによる超並列計算ができるOpenCLをbrowser上から利用できるAPI
    • not supportedで,一般的な使用は×
  • 小さな最適化
    • 有意味でないことが多い
    • まずはbottleneckの解析
    • 次は,アルゴリズム・データ構造や基礎技術の改善

Ch6 Layout tree構築(Rendering)のtuning

  • Rendering: Calculate Style + Layout
  • interactionの高速化にもつながる
  • Layout tree構築の流れ
    • CSSのmatching処理
      • CSS rule set: CSS selector + CSS property
      • CSS selectorは右から左に向けて処理
      • selectorの記述が増えるほど,試行回数が増えて時間がかかる
    • DOM要素の位置情報を計算する
      • rendering対象内での絶対位置
    • Rerendering
      • 内部表現の再利用,不要な処理のskip
      • Recalculate Style
      • 操作とRerendering時に起こる処理との対応を知る
  • Layout tree構築におけるperformanceの計測
    • Performance panel
      • Recalculate Style
        • Elements Affected
      • Layout
        • Nodes that need layout
        • Layout root
  • 高速なCSS selectorの記述
    • DOM treeにも注意が必要
    • CSS selectorをsimpleにする
      • 試行回数の改善に加えて,CSS rule setの詳細度が一定になることで,保守性も上がる
    • 子孫selector, 間接selectorを避ける
    • 全称selectorとの組み合わせを避ける
      • そもそも全称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との組み合わせも〇
    • media queryを指定する
      • 不要なrule setをまとめて除外できて〇
  • Layoutを高速化する
    • a.c.a Reflow
  • Layoutを避ける
    • Layoutの原因
      • DOM要素の座標や大きさの変化
      • DOM treeの構造の変化
      • DOM要素のcontentの変化
    • Layoutの範囲を限定する
      • いずれかの条件
        • svg要素
        • type="text", or type="search"のinput要素
        • table要素の子孫じゃなくてかついろいろ条件を満たす
  • 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)
    • 原因
      • Layoutが引き起こされる
      • 描画が引き起こされる
        • Paintingに直接関係するCSS propertyを変更したとき
        • 確認: Chrome DevToolsのRendering option内の,Paint Flashing
      • Layerの合成が引き起こされる
        • opacity, transform CSS propertyが変更されたとき
          • 高速なanimationを実装するためには,これらのみの変更とするのが〇
        • cost小さい
  • CSS propertyの変更が何を引き起こすか
  • 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
    • transformCSS propertyに3D変形を指定したとき
      • GPUのVRAMに転送→Composite Layers処理があって初めて3Dになる
        • transform propertyが変更されてもPaintは起こらずComposite Layersのみ起こる.
        • Composite Layers内のGPUでの変換のみの処理は,Rerenderingの中で最速
  • translateZ hack
    • translateZ(0)により,結果を変えずにGPUで合成できる
    • position: fixedのscroll speedの改善
    • body要素にtranslateZ hackを用いる問題
      • translateZを使うためのrule
        • Rasterizeされることが少ない要素に用いる
        • 領域がそれほど大きくない要素に用いる
        • 必要なときだけ用いる
    • 必要なtimingだけtranslateZ hackを用いる
      • JavaScriptでDOM要素のstyle propertyを指定する
    • will-changeCSS propertyによるtranslateZ hackの代替

Ch8 高度なtuning

  • 大量のDOM要素を扱うvirtual rendering
    • virtual rendering(virtual list): 実際にuserに見える箇所でのみ,表示する要素をDOM treeに動的に挿入
    • concept
    • algorithm
      • scroll領域の確保
      • contentsの読み込み
        • 表示する要素は絶対座標を計算して追加
      • scrollの検知
        • 不要な要素はunload
    • 事例とlibrary
  • なめらかな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
      • これらを使えない場合は仕方ない
    • layerの合成の最適化
      • translateZ hack
  • will-changeCSS propertyによる最適化
    • CSS property名を指定
      • opacity, transformのみ
    • scroll-positionを指定
      • 要素の移動(animation)や素早いscrollに対応
    • contentsを指定
      • animationや変更を予想
      • cacheの生成・維持を省ける
    • dynamicに利用
      • JavaScriptからのdynamicな利用が〇
      • CSSでの宣言は,その要素が常に変更されるときのみ
    • 使い方
      • 最適化においては,見かけほど有用ではない
  • 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で修飾もできる
    • JavaScriptSVG内の視覚的要素をanimationさせたり,event listenerを追加してinteractionを与えられる
    • HTMLのanimationの問題もいくつか回避している
    • JavaScriptでanimationを行う
      • 属性を操作
        • LayoutはSVG要素内に限定してくれる → 通常のDOM要素のanimationよりもperformanceの負荷小さい
      • CSS Transitionを使う
        • 通常のDOM要素のtransformCSS propertyの変化とは異なり,LayoutからRerendering
    • SMILによるanimation
      • SMIL: Synchronized Multimedia Integration Language
      • SVG animationは,SMILのanimationの要素を利用
      • SVG animationは,Web標準から外れる予定

『Web API: The Good Parts』学習メモ

Ch01 what's Web API

  • Web API: HTTP protocolを利用してnetwork越しに呼び出すAPI
  • API: Application Protocol Interface
    • target: XML over HTTP, JSON over HTTP
    • developerにAPIを公開することで,サービスに付加価値がつく
    • eco systemに参加
    • ProgrammableWeb: API directory service
    • third party JSのためのAPI
  • APIのpattern
    • 使用例
  • APIで公開するもの
    • serviceのcoreの価値のある部分すべてを利用可能にする
    • riskについて.
      • 公開しなくてもriskはある.
    • 利用規約で問題行動への対応を表明
    • 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
  • まとめ
    • [Good] Web APIが未公開なら,すぐ公開を検討
    • [Good] Web APIを美しく設計する
    • [Good] RESTという言葉にこだわり過ぎない

Ch02 endpointのdesignとrequestの形式

  • APIとして公開する機能をdesign
    • UCを考える
  • API endpointの考え方
    • endpoint: APIにアクセスするためのURI
    • 覚えやすく,どんな機能を持つURIか一目でわかる
      • 短く入力しやすい
      • 人間が読んで理解できる
        • ProgrammableWebで正しい英単語を確認
      • 大文字小文字が混在していない
      • 改造しやすい(Hackable)
      • server側のarchitectureが反映されていない
      • ruleが統一
  • HTTP methodとendpoint
    • URI: 操作するもの.method: 操作方法.
    • 1つのURIのendpointに異なるmethodでアクセス
      • resourceと扱いの分離 ← HTTPの本来の考え方に合致
    • POSTは指定したURIに従属,PUTはURIそのもの
    • PATCH: 一部のみ変更
    • GET, POSTしか使えないとき
      • X-HTTP-Method-Override
      • _method
        • Railsが使っている
      • X-HTTP-Method-Overrideの方が利用しやすい
        • 固有の形式となることや,メタ情報が増えてしまうため.
  • APIのendpoint design
    • Web APIの基本: あるデータの集合と個々のデータをendpointとして表現し,それに対してHTTPのmethodで操作を表す.
    • Foreigh keyをそのままidとして使うのが良い
    • resourceにaccessするためのendpoint designの注意点
      • 複数形の名詞を使う
      • 利用する単語に気を付ける
      • spaceやencodeを必要とする文字を使わない
      • 単語をつなげる必要がある場合はハイフン
        • 基本は,単語のつなぎ合わせではなく,パスで区切る/query parameterとする/なるべく短い表現にするのがよい
  • 検索とquery parameterのdesign
    • pagination: 取得数と取得位置を指定
      • per_page + page, or limit + offset
    • 相対位置の問題
    • → 絶対位置での取得
    • 絞り込みのためのparameter
      • qは部分一致〇
      • URIにSearchを入れるのは,検索という意味を強調するために有用である
      • 検索に主体があるserviceのAPIの場合
    • query parameterとpathの使い分け
      • 一意なresourceを表すために必要な情報で,省略不可能な場合はpath, そうでなければquery parameter.
  • loginとOAuth 2.0
    • 認証のAPIとして,Authが真っ先に検討できる標準仕様
    • 自社開発のClient Applicationにおいて,ユーザ名とパスワードをapplication内に入力して認証を行う場合
      • OAuthのGrant Typeのうち,Resource Owner Password Credentialsを使う
        • 扱い方
    • access tokenの有効期限と更新
    • other Grant Type
      • Client Credentials: User name, Password不要な認証.Clientの認証のみ行う.
    • 自分の情報へのalias
      • me, self
      • ほかのユーザの情報の処理とは,処理自体を分岐することでバグを防げる
  • hostnameとendpointの共通部分
  • SSKDsとAPI design
    • LSUDsに比べて,end userにとってのuser experienceがより重要になる.
    • 汎用的という点では美しくなくてもよいケースがある.
      • 1 screen 1 API call, 1 save 1 API call
  • HATEOASとREST LEVEL3 API
    • HATEOAS: Hypermedia As The Engine Of Application State
      • Hypermedia @ Web API: APIのresource
    • media typeで,アクセスしたデータがどんなデータか指示
    • merit
      • URIの変更が容易になる
      • Hackableでなくてもよくなる
    • SSKDs向けのAPIには〇.LSUDsにはまだ△.
    • Client, Serverともに自分で開発するようなsituationでは,検討できる
  • まとめ
    • [Good] 覚えやすく,どんな機能を持つか一目でわかるendpointにする
    • [Good] 適切なHTTP methodを利用する
    • [Good] 適切な英単語を利用.単複にも注意.
    • [Good] 認証はOAuth 2.0

Ch03 response dataの design

  • data format
    • APIが返す構造化データの表現. JSON, XMLなど.
      • JSONがdefault. XMLは必要があれば.
      • JSONの方がsimple, 同じデータを表すのにサイズが小さくて済む, JSとの相性〇
    • data formatの指定方法
      • query parameter ← 最も使われている
      • 拡張子
      • request header
  • JSONPの取り扱い
    • JSON with Padding
    • domainを超えたaccessのため
    • 作法
      • callback function nameのquery parameterでの指定
      • jQueryのe.g.
      • JSONPはJSなので,media typeはapplication/javascriptになる
    • error handling
      • 200を返し,response bodyでerrorの内容を示す
    • 不要ならJSONPは使わない
      • 同一生成元policyを回避してしまうため
  • dataの内部構造の考え方
    • response data: APIのアクセス回数がなるべく減るようにする
      • APIのUCを考える必要
      • Web APIは,DBのinterfaceではなくapplicationのinterface
      • × Chatty(おしゃべりな) API
    • すべてのAPIでできるだけ多くのデータを返す準備をしておき,利用者が取得する項目を選択する
      • response group
    • envelope: 冗長.HTTPがやっているため十分.
      • JSONPのときだけは使うと便利
    • 同じ構造なら階層構造,そうでなければできるだけflatにする.
    • response全体をObjectにして,中に配列を入れるのが〇
      • response dataが何を示しているかわかりやすい
      • response dataをObjectに統一できる
      • security
    • 配列の件数,続きがあるかどうかの取り方
      • 指定の件数+1件を取れているかどうかなどでよい.
      • HackableでないAPIでよければ,HATEOAS的な考えで,次のURIなどを返すのも〇
  • 各dataのformat
    • 名前
      • endpointのdesignと同じ.
      • JSONではcamel case ← JSと同じ
      • snake caseの場合もあり.snake caseの方が読みやすいらしい
      • 配列の場合は複数,それ以外は単数
    • 性別
      • genderで文字列
      • 生物学的な使い方ならsex
        • sexなら1/2もあり
    • 日付
      • RFC 3339形式が〇
      • SSKDs向けならUnix timestampも〇
      • HTTP日付はformatが異なる
    • 大きな整数とJSON
      • 大きな整数は文字列で返す
  • response dataのdesign
    • あるデータを返すときは同じ構造になるよう,それぞれのデータの構造を定義してしまうとsimpleで〇
  • errorの表現
    • proper status code
    • detail
      • bodyで〇.headerに入れるのも悪くはなさそう
      • detail code, detail information link
    • HTMLで返らないようにする
    • @maintenance
      • 503
      • Retry-After
    • 意図的に不正確な情報を返す
  • まとめ
    • [Good] JSON,あるいは目的に応じたdata formatを使用
    • [Good] dataを不要なenvelopeで包まない
    • [Good] responseをできる限りflatな構造にする
    • [Good] 各dataの名前が簡潔で理解しやすく,適切な単複が用いられている
    • [Good] errorのformatを統一し,Client側でerror detailを機械的に理解可能にする

Ch04 HTTPの仕様を最大限利用する

  • 意義
    • 不本意に独自仕様をいれてしまう危険性を下げる
    • HTTP protocolがenvelopeの役割という例
  • status codeを正しく使う
    • APIで使うcode一覧
    • 2xx: success
      • 204: No Contentは,是非あり
        • PUT, PATCHは,200とともに操作したデータを返す(POSTは201)
        • DELETEは204
    • 3xx: 追加で処理が必要
      • redirect: 301, 302, 303, 307
        • Locationを伴う
      • POSTによるデータ送信 → GETで別のページを表示のケースが多い
        • 302, 301はmethodの変更を許可
        • 308, 307は不許可
      • APIではできるだけredirectを避ける
      • 300: Multiple Choices
      • 304: Not Modified
    • 4xx: Clientのrequestに問題があった場合
      • 400: Bad Request
        • ほかのcodeでは表せない「その他」
      • 401: Unauthorized. Authentication(認証) error. ← 誰ですか?
      • 403: Forbidden. Authorization(認可) error. ← 許可がないよ.
      • ほかにも色々ある
    • 5xx: Serverに問題があった場合
  • cacheとHTTPの仕様
    • cacheのmerit. → 可能な限り利用するべき
    • proxy serverへの考慮必要
    • reverse proxy
    • Expiration Model
      • fresh ←→ stale
      • Expires
        • 特定の日時に更新されることがあらかじめわかっているdataに使う
      • Cache-Control
        • max-age
          • HTTP時間
            • RFC1123を使う
    • Validation Model
      • 条件付きrequest
        • Last-Modified, ETag (Entity Tag)
        • If-Modified-Since, If-None-Match
      • e.g. MurmurHash3
      • strong/weak Validation
        • weakなら,広告などの違いは無視できる
    • 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を返してよい秒数
  • 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
      • 前提知識なくても読めればtext, そうでなければapplication
    • 正しいmedia typeをContent-Typeで返す
    • x-で始まるmedia type
    • 自分でmedia typeを定義する
      • Registration treeで接頭辞が決まっている
        • vnd.を使うことが多い
    • JSONXMLを用いた新しいdata形式を定義する場合
      • 独自に別のHTTP headerを用意するのが折衷案として〇
    • media typeが正しくないと,security riskあり
    • media type @request
      • Content-Type
        • 複数dataのPOSTは,multipart/form-data
      • Accept
        • どんなmedia typeを受け入れ可能か
        • q: Quality Value. そのtypeの優先度.
        • → serverが配信するdata formatを決定: Server Driven Content Negotiation
        • ServerのresponseではVaryにAcceptを指定する必要
        • URIで形式を指定する方が手軽といえば手軽だが,HTTPの仕様に即しているのはAccept
  • 同一生成元policy(Same Origin Policy)とCross-Origin Resource Sharing
    • CORSはJSONPより安全で公式の仕様
    • ClientからOriginというrequest headerを送る
    • ServerはAccess-Control-Allow-Originというresponse headerを返す
    • pre flight request
    • Access-Control-Allow-Credentials
  • 独自の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で管理する
    • 新しいAPIを別のendpoint, または別のparameterをつけたURIなど,新しいaccess形式で公開が〇
    • 方法①: URIにversionを埋め込む
      • 最も一般的でわかりやすく,おすすめ
      • vを付けた方が分かりやすい
      • semantic versioning
        • APIではmajor versionのみパスに含めるのが一般的
      • path以外での指定
        • query parameter
          • 省略可能
          • 冗長だったり,省略したときに分かりづらいので,パスの方が〇
        • media type
          • HTTPの文法に則っており,パスのようにpresentation levelの指定がURIに含まれずに済む
          • Client libraryの解釈で問題がある可能性あり
          • → 独自のHTTP headerを定義して指定する方法がある
  • versionを変えるときの指針
    • security, authorityにアップデートは,後方互換なしで〇
    • 以降のバージョンアップの影響を小さくするために実施する
    • 常に最新版を返すaliasは不要
  • APIの提供を終了する
    • 終了日時の周知
    • Blackout Test
    • 予め提供終了時の仕様を盛り込む
      • 強制アップデート,ユーザのOSの調査
    • 利用規約にサポート期限を明記
      • applicationの性質による
  • Orchestration layer
    • LSUDs: one-size-fits-all(OSFA)
    • OSFAではなく,それぞれのClientに対応するために,ServerとClientの間にOrchestration layerを挟むようにする.
  • まとめ
    • [Good] APIのversionの更新は最低限にとどめ,後方互換性にも注意
    • [Good] APIのversionはmajor versionをURIに含める
    • [Good] APIの提供終了時は,すぐ終了するのではなく最低6か月は公開を続ける

Ch06 堅牢なWeb APIを作る

  • 安全性と安定性
  • Web APIを安全にする
    • riskのe.g.
  • Server-Client間での情報の不正入手
    • risk
    • HTTPS by TLS
      • URIのpath, query 文字列, header, bodyを暗号化
        • ↑やり取りに使われるほぼすべての情報
      • HTTP Strict Transport Security(HSTS)により,HTTPSの強制〇
      • HTTPSでもriskあり
        • Man-In-The-Middle attack(MITM): 不正な証明書を使用 ← 証明書の検証で回避
        • Clientでも対応が必要
      • 速度の問題
    • 認証局への攻撃
      • Certificate and Public Key Pinningで回避
        • OWASPに実装方法あり
  • browserでアクセスするAPIの問題
    • browserは汎用的で機能が豊富
    • XSS
      • JSON injection: 特にJSONについては,必ずJSONとしてbrowserに判断させる必要がある
        • Content-Typeの指定
        • Content Snifferingへの対応
          • X-Content-Type-Options: nosniff
            • JSONでデータを返す際には必ずつける
          • 追加のrequest headerのチェック
            • X-Requested-With: XMLHttpRequest
            • 追加のpre flight requestが必要になってしまうので,明示が必要
          • JSON文字列のescape
    • XSRF: Cross Site Request Forgery
      • Forgery: 偽造,捏造
      • 回避方法
        • methodを正しく使う
        • XSRF tokenを使う
        • X-Request-With
    • JSON hijack
      • 回避方法
        • JSONをSCRIPT要素では読み込めないようにする
          • X-Requested-With
            • XMLHttpRequest, browser以外からのClientからのアクセスのみを想定の場合は,必ずやる
        • JSONをbrowserが必ずJSONと認識するようにする
          • 正しいmedia typeを返す
        • JSONJavaScriptとして解釈不能,または実行時にデータを読み込めないようにする
          • JSONの配列ではなくObjectを返すようにする
          • 無限ループを仕込む e.g. Facebook
    • browserからのアクセスを想定しないAPIでは,browserからのSCRIPT要素を使ったアクセスを防ぐのが〇
  • 悪意あるaccessへの対策
    • どんなデータがやり取りされているか知られても,不正を働けないようにしておく必要がある
    • parameterの改ざん
      • 本来accessできない情報はServerでcheck → access禁止
      • rate limit
      • Server側でデータの整合性をチェック
        • minusのチェックなど(アイテムやポイントの数などの不正操作を防ぐ)
    • requestの再送信
      • stateを管理
      • 支払いの偽装
        • Consumable/Non-Consumable
  • security関係のHTTP header
    • X-Content-Type-Options
      • JSONJSON以外として解釈することを防ぐ
      • JSONAPIを配信する場合は必須
    • X-XSS-Protection
      • browserのXSSへの防御機能の有効化
    • X-Frame-Options
      • dataがFrame内で読み込まれるのを阻止
    • Content-Security-Policy
      • default-src 'none'
    • Strict-Transport-Security
      • HSTSのためのheader
      • HTTPSのみに限定
    • Public-Key-Pins
      • HPKPのためのheader
      • SSL証明書が偽造されたものでないかcheck
    • Set-Cookie headerとsecurity
      • Secure, HttpOnly
    • 実例
  • 大量accessへの対策
    • userごとのaccessを制限 ← 最も現実的
    • rate limit: 単位時間あたりの最大access回数
    • 決めること
      • ユーザの識別要素
      • limit value
      • limit valueの単位
        • UseCaseの考慮
        • APIのgroupごとに設定など
        • 1時間単位くらいが多い
      • limitのreset
        • rolling window
    • access制限緩和
      • 特定のapplicationや開発者
      • 課金
    • 制限値を超えたときの対応
      • 429 Too Many Request
      • 429以外のstatus codeが使われていることも多い
    • rate limitをuserに伝える
      • document + API利用者向けのdashboard
      • HTTPのresponseのheaderでrate limitを渡す
        • X-RateLimit-Limit
        • X-Rate-Limit-Resetは,resetまでの秒数をデルタ秒で表すのが〇
    • rate limitの実装
      • 実際は,RedisのKVSなどを使って記録する
      • そのほか,API公開をサポートするサービスにも機能がある
  • まとめ
    • [Good] 個人情報など特定のuser以外に漏洩したくない情報がある場合はHTTPSを使う
    • [Good] XSS, XSRFなど通常のWebと同様のSecurityだけでなく,JSON hijackなどAPI特有の脆弱性にも配慮する
    • [Good] Security強化につながるHTTP headerをちゃんとつける
    • [Good] rate limitを設けることで一部のuserの過度なaccessによる負荷を防ぐ

Appendix

  • Web APIを公開する際にできること
    • API documentの提供
      • 常に最新にしておく
      • API Blueprint
        • document公開補助tools: RSpec Api Blueprint, iglo, API Mock, apiary
    • sandbox APIの提供
      • e.g. PayPal, Gengo
      • hostnameのみ変えているcaseが多い
    • API Console
      • browser上で実際にAPIを操作して試せるtool
      • e.g. Graph API Explorer
      • 生成補助tools: Apigee
    • SDKの提供
      • maintenance cost大
  • Web API check list

『メタプログラミング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
    • 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回だけファイルを読み込む.
  • 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でラップ.
    • respond_to_missing?もあわせてoverride必要
    • const_missing
      • 古いクラス名が呼び出されたときに,警告を出して新しいクラス名を返す
    • 受付可能な引数以外はBasicObject#method_missingを呼ぶ必要がある
  • 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を呼び出す
  • 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を使う.
    • Method Object
      • blockやlambdaに似ているが,所属するObjectのscopeで評価
      • UnboundMethod
        • Active Supportのe.g.
        • 自分ではやらない方が〇
  • 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 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
  • 特異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.
  • 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との比較
  • 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も不要になる
  • 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の操作
  • 学んだこと
    • ActiveRecord::Baseは,究極的なopen Class
    • 疎結合,simplicity, 重複の排除という基本的な設計原則を実現するための技法が,ほかの言語と大きく異なる

Ch10 Active SupportのConcern Module

  • history
    • Rails 2では,VCRの例と同じ形だった: includeとextendのtrick
      • 欠点: 複雑 + 連鎖のために柔軟性down
  • ActiveSupport::Concern
    • Module#append_features
    • Concern#append_features
      • concern(ActiveSupport::ConcernをextendしたModule)のなかで,別のconcernをincludeしない
      • 依存を管理する.最小主義の依存管理system
  • 学んだこと
    • 柔軟性のためのmeta programming
      • codeが複雑になったり,排除しにくい重複が見つかった時に使う.
    • Moduleの相互作用のような基本的な部分でも,meta programmingで変更できる

Ch11 alias_method_chainの盛衰

  • problem
    • around aliasの問題
    • rename, shuffleが繰り返され,実際に呼び出しているmethodがどのversionか追跡がdifficult
    • そもそも,存在自体が不要
      • 別のModuleに定義して,includeすればよい.
      • Classのmethodへの機能追加には,Module#prependを使うのが〇
        • Ruby1.9との互換性の問題がなくなれば,Railsや周辺でもalias_method_chainを使う理由がなくなる
  • 学んだこと
    • 素直な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にするための対応
  • 学んだこと
    • 「最初から正しくやる」よりも「進化的設計」に傾いている.
      • 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

  • ←→ GSL(General)
  • e.g. UNIXのshell, VBA, make, Ant, ...
  • GPLを,自分の問題に特化したDSLにする.
  • 内部DSLと外部DSL
    • Markabyなどの,大きなGPLの内部にあるDSLは内部DSL.makeなどの独自のparserを持った言語は外部DSL
    • RubyGPLとしての構文の制約が小さい.
      • Rakeは内部DSL ←→ Ant(Java), make(C)は外部DSL

C 魔術書

  • 今までのものの短いsample

D から騒ぎ

  • nilについて
  • Null Object
    • 未初期化の参照をNull Objectにreplace
  • NilClassにmethod_missingを追加.
    • methodの連結にも対応可能
  • →black hole
    • nilを使ったNull Object
    • 未初期化の参照の問題を回避しつつ,method呼び出しを無限のNull Objectの穴に吸い込む
  • bugに気づきづらくなるというdemeritも考慮

『Webを支える技術』学習メモ

Part1 Web概論

Ch01 what's Web

  • Webの作用
    • clientと疎結合なWeb site
    • UIとしてのWeb
    • APIとしてのWeb
    • HTTP, URI, HTML
  • 非線形な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
  • IETFW3Cでのstandardize
    • especially HTML, CSS
  • Webのstandardize
    • RESTの起源,意味
      • HTTPはresourceのstateの表現を転送している
      • REpresentational State Transfer
    • Hyper Media Format: HTML, RSS, Atom, microformat, JSON
  • Web API
    • SOAP @RPC/distributed object
      • WS-*
    • mashupのためのREST
  • 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
  • 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のみを持つ
    • e.階層化system
      • 統一IFにより,load balancerやproxyを使用したsystemの階層化が容易になる
    • f.code ondemand
      • js, flash, java appletなど
      • merit: あとからclientを拡張
      • demerit: protocolの可視性down
    • a-fを組み合わせたarchitecture styleがREST
      • REST以外のarchitecture style: P2P
  • RESTの2つの側面
      1. RESTとHypermedia
      2. resourceをリンクで接続することで1つのapplicationを構成する
        • 接続性: RESTの基幹をなす
      1. RESTとdistributed system
      2. linkをたどってapplication stateを遷移することで性能劣化を抑える.
      3. 統一IFにより互換の問題が起こらない.

作用

  • RESTというdistributed network systemのための理論により,Webが機能する
  • RESTの制約に従っていること: RESTful

Part2 URI

Ch04 URIの仕様

目的

  • URI: Uniform Resource Identifier
    • resourceを統一的に識別するID

概要

  • URIのsimpleな構文
    • URI scheme: http → 一般にはprotocolを示す.「://」で区切る
    • host name: blog.example.jp → DNSで解決できるDNかIP address
    • path: /entries/1 → hostの中のresourceを一意に示す
  • URIの複雑な構文
    • URI scheme
    • user info: resourceにaccessする際のuser + pass 「user:pass」
    • host: user infoの後に「@」
    • port: hostにaccessするときのprotocolで用いるTCPのport number
      • 省略 → protocolのdefault. httpでは80
    • path
    • query parameter: 「path?query」となる. 「name=value」&「name=value
      • dynamicにURI生成
    • URI fragment: URIのresource内部の部分を指定

詳細

  • 相対URI
    • 相対URIの解決のため,base URIを指定
      • base URI: resourceのURI or 明示指定
        • html: \<head>内に\<base>
        • xml: xml:base=""でどこでも〇
  • URIと文字
    • ASCII以外の文字のための%encode
      • UTF-8の文字を構成するbyteそれぞれを「%xx(xxは16進数)」で表記
    • Web pageの文字encodingで%encodeを行う.基本はUTF-8
  • URIの長さ
    • 実装上は長さに制限あり
  • URI scheme
    • 既存のprotocol → 既存のscheme

まとめ

  • 相対URIの解決と%encodeが必要.
  • なるべく絶対URI & UTF-8

Ch05 URI design

目的

  • 変わらないURIがbest URI
    • called "cool URI"

概要

  • 変わりにくいURIの作成
    • 実装に依存した拡張子やpathを含めない
    • method nameやsession idを含めない
    • URIはresourceを表現する名詞にする

詳細

    1. Cool URI
    2. usability高まる
    1. URIの変更のためのredirect
    1. 拡張子でresourceの表現を特定
    2. 言語を指定する拡張子
      • → Content Negotiationのためのbrowserの設定不要
    1. matrix URIで複数の軸を;で区切る
    2. ;: 順不同
    3. ,: 順序アリ
    1. clientに対して不透明なURI疎結合

影響

  • URIは以下の点で重要
    • resourceの名前である
    • 寿命が長い
    • browser/address欄に表示
  • → Web ServiceやWeb APIのために最も重要なpart

Part3 HTTP

Ch06 HTTPの基本

目的

  • TCP/IPの基礎とHTTPの歴史を見る
  • HTTPは以下のRESTの重要な特徴を実現する,Webの基盤となるprotocol
    • 統一IF
    • stateless server
    • cache

概要

  • TCP/IPの観点
    • 階層型protocol → 層ごとに抽象化して実装
      • application layer
        • concreteなinternet application
          • mail, DNS, HTTP
          • socket(networkでのdataのやり取りを抽象化したAPI)と呼ばれるlibraryを利用して,HTTP serverやbrowserを実装
      • transport layer
        • dataの転送を保証.TCPに相当.
          • TCPで接続先とconnectionを構成し,1~65535のport numberでdataの転送先applicationを決定する
      • internet layer
        • IPでpacket単位でdataをやり取り.IPに相当.
        • 自分のnetwork IFでのdata送信の保証
      • network IF層
        • 物理的な部分

詳細

  • 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
    • response messageの構成
      • status line
      • header
      • body
  • stateless HTTP
    • application state = session state
      • statefulの欠点
        • client増 → scaleout difficult
    • stateless の利点
      • 自己記述的messageでscaleout easy
    • statelessの欠点
      • performance down
        • data量,冗長(認証など)
      • 通信エラー

作用

  • simple HTTPにより,Web ServiceとWeb APIが同じprotocolで表現

Ch07 HTTP methods

目的

  • 8 methodsのうち,主要な6つのmethodsの使い方を見る
  • and, HTTPの設計上の工夫を見る
  • method数が少ないからこそHTTPやWebは成功

概要

  • HTTP methodsの観点
    • CRUD
      • GET
      • POST: URIをserver側で自動決定するWeb Service
      • PUT: clientが決めたtitleがURIになる → PUTの方がserverと密
      • DELETE
    • HEAD
    • OPTIONS

詳細

  • 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

作用

  • 数少ない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と異なり双方向

概要

  • 観点
    • 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空間
      • Basic authentication: username & password
      • Digest authentication: with hash function
        • requestごとに401 responseがあるため普及しない
      • OpenID: single sign on
      • OAuth: 認可の以上
      • WSSE認証: serverは生password
    • 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を見る
    • HTML: HyperText Markup Language
      • Markup Language: Tagで文書構造を表現
        • 構造化文書
      • SGML base(text/htmlのHTML) → XML base(application/xhtml+xml)
    • htmは古い拡張子
    • XML(meta language)の仕様
      • 書き方-link
    • ! HTMLでのlinkの設計: linkをたどってapplicationのstate 遷移

Ch11 microformats

目的

  • microformatsによりlinkの細かい意味やevent informationを表現

問題

  • semantics(意味論)
    • program semantics
      • program languageのもつ意味を確定させる理論
    • Web semantics「semantics Web」
      • resourceの持つ意味を確定させる理論
  • RDFの問題とmicroformatsでの解決

概要

作用

  • microformatsで解決できない部分
    • RDFa(RDF-in-attributes)での解決
    • 可能性
    • microformatsによりWeb pageをそのままWeb APIとして提供
      • Web page/APIの機能差少ない
      • 保守・開発コスト小さい

Ch12 Atom

目的

  • Atom Syndication Format
    • XML format
    • Web serviceのWeb APIとして使用

概要

  • resource model
    • member resource
      • entry resource @XML
      • media resource
    • collection resource
      • plural member resource
    • media type: app/atom+xml
    • atom extension

詳細

  • 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: data formatの規定
    • Atom Publishing Protocol: Atomでのresource編集protocolの規定
      • Atomで表すresourceのCRUD操作のためのprotocol
  • Atom Publishing Protocolのresource model
    • 1つのresourceがmulti 表現
  • member resourceの操作
  • service document
  • Atom Publishing Protocolに向いている/いないWeb API

Ch14 JSON

  • JSON: hashや配列などのdata構造の記述
    • Notation
    • JSONとは
    • data type
    • Object: key-value
    • JSONP
      • cross domain communicationの制限
        • script要素での解決
        • Callback functionによるJSONP
    • Ajaxでは必須.

Part5 Web Serviceの設計

Ch15 Read Only Web Serviceの設計

目的

  • resource designの観点
    • client-server間IF: Web Service/APIの外部設計
      • resourceの分割
      • URIでの命名, 相互リンク
      • 設計の対象
    • Web Service/APIを区別しない

概要

  • resource指向のarchitectureのapproachの観点
    • ! 設計step
      • service dataの特定
      • dataをresourceに分ける
      • 各resourceに対して
        • resourceをURI命名
        • client向けのresource表現の設計
          • linkとformでresource間を結びつけ
        • eventの標準的なコースの検討
        • errorの検討
  • RESTfulなWeb Serviceの性質
    • addressability
    • stateless
      • 接続性
      • 統一IF

詳細

  • 各手順の観点
    • dataのresourceへの分割
      • dataそのもの, 構造data含む
      • 機能の結果
      • top level resource
    • resourceへのURIでの命名
      • parameterの{~}記法
      • 階層構造のための「/」
    • clientへのresource表現
    • linkとformでresource間をつなげる
      • resource間のリンク関係
    • event error

作用

  • 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

作用

  • 以下の観点でバランス
    • なるべく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つの革命
  • → Cloud Native with OS:Kubernetes
  • revolutionのhistory, 重要性を見て,ソフトウェア deliveryへの作用を考える
    • 想定される変化
  • Cloud Native DevOpsがtheme

概要

  • (1) クラウド
    • 処理能力を買う
    • SaaS
    • Iaas
      • Undifferentiated Heavy Lifting(UHL)
  • (2) DevOps
    • developmentとoperationsの連携
      • 信頼性と正確性の責任共有
      • 拡張性Up
    • 技術ではなく組織力,人間の問題
    • merit in ビジネス
    • Infrastructure as Code
      • クラウドをautomateするソフトウェアのdeveloperが運用エンジニア
    • collaboration型でコード中心 → コンテナ
    • development, operationsの統一
  • (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のみ
      • 分散 システムの設計パターンを開発
      • コンテナ orchestrator
    • Kubernetes
      • history @ Borg
        • コンテナをserverのpoolで実行するための割り当てとschedulingを行う集中管理システム
    • 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で構成
        • monolithusの方が理解しやすく,相互作用を追跡できる
          • but, monolithusは拡張difficult

作用

  • 運用の観点
    • 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 
          '''
        
  • (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の実践

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の高可用性の重要性
    • multi availability zoneへの分散
    • testの実施が重要

詳細

  • (1) self hosting Kubernetesのcost
    • buy or build
    • cost 大.engineerの給与約100万ドル
    • 初期セットアップから稼働を通してcareが必要
    • まずはmanaged service
  • (2) managed Kubernetes services
    • GKE
    • EKS
      • 後発&割高
    • AKS
    • OpenShift: PaaS
    • IBM Cloud Kubernetes サービス
    • HKs
  • (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
  • (6) clusterless コンテナ service

まとめ

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
  • (2) Kubernetes scheduler
    • DeploymentがKubernetes DBにPod リソースを作成 & Pod into cueue
      • → schedulerがPodを取り出してrunnabeなノードを見つける
      • ⇔ Podをノードにscheduling
      • → kubeletがPodが含むコンテナを起動
  • (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のグループにリクエストを転送
    • サービスの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
  • (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

作用

  • 何ができるかを理解
    • ↑ PodやDeploymentのメカニズム

Ch05 リソース 管理

目的

  • クラスタの最大活用
    • リソースの使用状況の管理と最適化など

概要

  • リソースの理解
    • Kubernetes schedulerの観点
      • Podが求めるリソースの量を把握
    • リソースの単位: CPU, milliCPU, MiB@memory
    • リソース要求: min
    • リソース制限: max
      • over commit〇: ノードのリソース総量を超えた制限可能
    • コンテナのminimize

詳細

  • (1) コンテナ lifecycle 管理
    • Liveness probe by HTTP
    • Probeの遅延と頻度
      • death loopの回避
      • initialDelaySeconds, periodSeconds
    • ほかのtypeのProbe
    • Readiness Probe: 「一時的にリクエスト処理不可能」を知らせる. → 常に「200 OK」を返す必要
      • zero downtime upgradeにeffective
    • file based Readiness Probe
    • minReadySeconds
    • Pod Disruption Budget: 失ってもよいPodの数
      • minAvailable, maxUnavailable
  • (2) Namespace
    • クラスタ横断でリソースの使用状況を管理
    • クラスタをpartition化
      • 別のnamespaceからは見えない
    • nest不可
    • kubectl get pods --namespace production
    • default namespaceは使わない
    • サービス間の通信
    • namespaceでのリソースのcontroll → ResourceQuota
      • kubectl get resourcequotas -n demo
    • LimitRangeでnamespaceないのdefaultを指定
      • ただし,基本はコンテナに設定する → コンテナを見ればわかるように
  • (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

Ch06 クラスタの運用

概要

  • (1) クラスタのsizingとscaling
    • クラスタのcostにはノードの数とサイズが作用する
    • capacity plan
    • ノードとinstance

      • ノード size ← providerが提供するcost performanceが良いものを選択
      • クラウド instanceのtype
        • 1つのvCPU + 3~4GiBのmemoryがmin
      • special typeのノード e.g. gpu, windows
      • bare metal server
    • クラスタのscaling

      • instance グループ, ノード pool
      • scale down
      • automatic scale → 基本は不要
  • (2) 適合性チェック
  • (3) 検証と監査
    • tool
      • (kubernete Guard: Kubernetes クラスタのcommon 問題 check)
      • Copper / instrumenta / Conftest
      • kube-bench: 不要なことも多い
      • Kubernetesの監査logging
  • (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・・・
  • (2) リソースを使った作業
    • 命令的(←→宣言的)なkubectl command (imperative(←→declarative))
      • kubectl createでリソースをexplicitlyに作成
      • kubectl deleteでリソースを削除
      • kubectl edit
    • 本番クラスタにはimperativeは×
      • 代わりにkubectl apply
    • kubectlでのmanifestの作成
    • リソースの差分チェック: kubectl diff -f dep.yaml
      • kubectl applyの前に行う
  • (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の仕様
    • 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に追加
      • → [( )]
  • (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を共有
      • コンテナ: オリジナル Namespace内にある分離されたプロセス(のグループ)を表現する
      • コンテナの内外ではプロセスは隠れる
    • コンテナの構成要素
      • 軽量VM
      • 1つのことのみ実行 e.g. 単純な自己完結型service
      • entry point: 起動時に実行されるコマンド
    • Podの構成要素
      • Pod: 相互に通信してデータを共有する必要がある
        • コンテナのグループを表現
        • ともにschedule. 起動終了も同時.同じ物理マシン上で実行
          • ⇔ 常に同じノード上で実行
        • 異なるマシンで動作しないコンテナをPodでグループ化する
  • (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
    • 環境変数の設定
  • (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で実行
  • (4) Volume
    • 同じPodの別のコンテナとのデータ共有 & restart後もデータを永続保持
    • emptyDir
      • download fileや生成データのcaching
      • データ処理ジョブ用のtmpworkspace
      • Pod内コンテナのファイル共有
      • コンテナへのマウント方法
        • PodのVolumes field
        • コンテナのvolumeMounts field
      • lockはない
    • 永続Volume
  • (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のみ
      • デプロイやkubectlなどの高度リソースは,高度なselector
      • e.g.
        • kubectl get pods -l app!=demo
        • kubectl get pods -l "環境 in(notin) (staging, production)"
    • Labelの使い方
      • staging/real
      • カナリアデプロイ track: stable/canary
    • Label: リソースを識別 ←→ Annotation: 外部toolやservice
      • どちらもk-v pair
  • (2) Node Affinity
    • schedulingの選好性の表現
      • hard: required ...
      • soft: preferred ...
      • schedule時のみ
    • Hard Affinity
      • Podを実行させたいノードの種類を述べる. @nodeSelectorTerms
    • Soft Affinity
      • weightの指定
  • (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指定
    • Job: Podを指定した回数だけ実行する
      • ←→ デプロイ Pod数を指定しcontinuousに実行
      • completions
      • parallelism
    • Cron Job
      • Jobのschedule
    • Horizontal Pod Autoscaler(HPA)
      • needsに応じてKubernetesがreplica数をautoscale
        • Vertical: replica自体を大/小化
      • CPU使用率などのメトリクス{での決定, の指定}
        • システム/service(← ユーザのdefinition) メトリクス
    • Pod Preset
      • admission controllerの一部
        • admission controller: objectへの変更を監視.変更の直前にaction
      • Pod Presetのconfigは,個々のPodのconfigとmergeされる
    • OperatorとCustom リソース Definition
      • ステートフル setを超えたcomplicateな管理が必要なアプリケーションのため.
  • (6) Ingress リソース
    • Ingress: サービスの前のload balancer
    • サービスはクラスタ内の内部trafficのルーティング
      • ←→ Ingressクラスタやmicroserviceへの入力となる外部trafficのルーティング
      • 異なるサービスへの転送: fanout
      • URL, HTTP Host headerでのルーティング
    • TLS(SSLと呼ばれていたもの)
      • 証明書の共有を単一のIngress リソースで管理: TLS終端と呼ぶ
      • KubernetesのSecretで証明書を保存
        • 既存証明書も〇
      • Cert-managerでLet's Encrypt証明書を自動取得
        • ↑ kube-legoの後継
    • Ingress Controller
      • Ingress Controllerが認識する特別なAnnotation
  • (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のManifest file
      • デプロイの設定
        • イメージ:のtag
        • enc: のfield
          • name-valueのpair
          • valueFromで,literalでなく別のところの値を取得
          • configMapKeyRef
      • デプロイは自身のspecが更新されたときのみPodを更新する
    • ConfigMapから環境全体を設定
      • encFromでConfigMapから全keyを取り込む
        • ←→ envがprior
    • command argumentで環境変数を使う
      • $(VARIABLE)は環境変数のVARIABLEの値で置き換える
        • → コンテナのentry pointにcommand line argumentとして与えられる
    • 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
    • secret データの保存のためのSecret
    • 環境変数としてSecretを使う
      • secretKeyRef ≒ configMapKeyRef
    • Secretのfileへの書き込み
    • Secretの読み取り
    • RBACによるaccess controll → 11.1.2
    • 保存データの暗号化
      • kubectl describe pod -n kube-システム -l component=kube-apiserver | grep encryption
    • HelmのAnnotationで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
    • SOPS(Secrets OPerationS): Mozilla projectによる
      • YAML, JSON, Binary fileと組み合わせて使用〇
      • 複数のencrypt backendが使える
    • secret データの値のみencrypt
    • helm-secrets pluginでSOPSを使える
    • DGP protocol with public key
    • GnuPGのinstall
      • key fingerprint
    • SOPSのinstall
    • decrypt check: sops --decrypt xxxx.yaml
      • デプロイではSOPSをdecrypt modeで使用
        • → 平文fileは使用後必ず削除. Not check in
    • KMS backendも可能

作用

  • 必要な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を探す
  • (2) Security Scan
    • Clair: OSSのコンテナ scanner
    • Aqua Security: 商用. free版もある.(Micro Scanner)
      • kube-hunterというOSS toolもある
    • Anchore Engine: OSS, コンテナ内すべての部品表を示す
  • (3) Backup
    • replication != backup
    • etcdのbackup: 重要
      • clustering, backup, replication
    • 必要なデプロイのためのInfrastructure as Code
      • YAML ManifestかHelm Chartをversion 管理
        • → 宣言的管理
      • Manifest fileから変更を適用
      • クラスタのsnapshotの作成
    • Veleno: OSS. クラスタのstateと永続データのbackupと復元
      • 使い方
      • 1つで完結したbackup
      • 手順書の作成と復元テスト at least once of month
      • scheduling
      • リソースとデータをクラスタ間で以降: lift&shiftもできる
  • (4) クラスタのstatusの監視
    • kubectl
      • kubectl get
        • componentstatuses → scheduler, controller-manager, etcd
        • nodes → describeでdetailを見る
        • pods { --all-namespaces, -A }
      • kubectl top { nodes, pods }
        • → CPUとメモリの使用率,capacityを見る
    • クラウド 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の内部校正
      • directory
      • Chart.yaml
        • Helm Chart名とversion: 必須
      • Values.yaml
        • ユーザが修正可能
        • 自由な形式
        • chart内のどこからでも参照
    • Helm template
      • deployment.yamlとservice.yamlがtemplateになっている
      • 二重の中括弧: Goのtemplate文法
      • 変数での補完
        • loop, 式, 条件, functionも〇
      • doublequote → {{ ~ | quote }}
    • 依存関係の指定 → helm 依存関係 update
  • (2) Helm Chartのデプロイ
    • 変数の設定
      • 追加の値file. releaseにおける値の指定: helm install ~ --values...
        • 値の確認: helm inspect values
      • Helmでのアプリケーションの更新.何度でも〇
        • helm upgrade \<既存のデプロイ>
    • 指定の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の管理
    • クラスタにinstallerする一式を単一のcommandでデプロイ
    • helmfile.yaml
      • repositoriesに参照するHelm Chart Repositoryのリストを定義
      • releasesでデプロイしたいアプリケーションを定義
      • 相対pathでdemo chartと値fileを指定
      • setで値の上書き
    • helmfileの適用: helmfile sync
      • CD パイプラインでhelm sync を自動実行
    • 個別/helmfileは統一
      • → a single source of truthを守る
  • (4) 高度なManifest 管理 tool
    • ksonnet: 計算やlogicが必要な大規模でcomplicateなデプロイに〇
      • → projectが中止
      • Jsonnet: JSONの拡張.KubernetesJSONも〇
      • prototypeの導入: よく使われるManifest pattern
    • Kapitan
      • 設定値の階層DB: inventory
        • → 環境やアプリケーションに合わせて異なる値でmanifest patternを再利用
    • kustomize
      • plainなYAML
      • overlayでパッチとして適用
      • kustomize build ~ | kubectl apply -f ~
    • kompose
      • docker-compose.yml: 連携して機能する一連のコンテナを定義, and デプロイ + コンテナの通信方法を定義
      • Kubernetes Manifestに変換するtool
    • Ansible
    • kubeval
      • Manifestの検証 to schema by version
      • CD パイプラインへの追加が〇
      • Conftestも〇

作用

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
  • (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で可能
    • Helmのhook: デプロイ中の処理準をcontroll
      • JobのAnnotationで指定
      • 失敗にも対応〇
      • pre-upgrade以外のhook
      • hookのchain化: 複数 hooks をchain化 by order
        • helm.sh/hook-weight propertyを使う

作用

  • Kubernetes アプリケーションの開発の高速化. by tools
  • 変更の本番環境へのrooloutが容易

Ch14 KubernetesでのCD

目的

  • CDとCDのKubernetes based クラウドネイティブ 環境での実現
  • Kubernetesと連携して動くCD パイプライン
  • コンテナ化されたアプリケーションのパイプラインの典型
      1. codeの変更をgit repositoryにpush
      1. build システムがbuild & test
      1. test ok → コンテナ イメージがコンテナ Registryに対してpublish
      1. new builded コンテナがautomatically デプロイ to staging 環境
      1. automatic acceptance test in staging 環境
      1. tested コンテナ イメージ tobe デプロイ to production 環境
  • デプロイの対象の成果物は〇コンテナ, ×Source Code

対応

  • (1) CD tool
    • 既存のCDでも〇
    • Jenkins: Docker, kubectl, Helmなど〇
    • Drone: simple & 軽量.個々のビルドstepは1つのコンテナの実行
    • Google Cloud Build with Google Cloud Platform
    • Concourse: Drone や Cloud builと同じく宣言的パイプライン + 公式Helm Chartあり
    • Spinnaker: ebook for freeあり, by Netflix
    • GitLab CI
    • Codefresh: to feature branch
    • Azure Pipelines
  • (2) CDのComponent
    • 既存のCDにコンテナ用Componentの追加のe.g.
      • Docker Hub
      • Gitkube: self hosting. simple + 可搬性〇.setupも間t何
      • Flux: with GitOps extended
      • Keel ≒ Flux
  • (3) CD Pipeline のe.g. by Cloud Build
    • Google CloudとGKEのセットアップ
      • demo Repositoryのfork
      • Cloud Buildの導入
        • 1つのコンテナの実行でbuild Pipelineの各stepが構成
      • Test用コンテナのbuild
        • YAMLの説明,構成
        • docker image build --target build -tag demo:test
    • test run
    • アプリケーション コンテナのbuild → アプリケーション コンテナの作成
    • Kubernetes Manifestの検証
    • イメージのPublish
      • Git SHA tag @成果物 → Codeのsnapshotになる
    • triggerの作成: 監視target Git Repository, active化の条件, パイプライン fileの指定
      • triggerのテスト
    • CD パイプラインからのデプロイ
    • デプロイ triggerの作成
      • tagのpushでtrigger
      • 代入変数
    • Build PipelineのOptimize
      • コンテナ based CD Pipeline toolは,各stepのコンテナをminimize
        • multi stage buildでオリジナル custom イメージをbuild

作用

  • アプリケーションのためにCD Pipelineをsetup → 一貫した方法と高い信頼性でソフトウェアを迅速にデプロイ

Ch15 オブザーバビリティと監視

目的

  • オブザーバビリティと監視の関係
  • Kubernetesでの監視,logging, メトリクス tracingの扱い

概要

  • (1) オブザーバビリティ
    • 監視を超えた概念
    • 監視
      • automatic 監視 @DevOps
    • blackbox監視
      • 複雑な分散 システムとなるクラウドネイティブ アプリケーションの監視の観点
      • blackbox監視の限界: 「なぜか」に答えられない
    • up/down test
      • up: アプリケーションの耐障害性と可用性をuptimeで測定
        • 99.9%: three nines
        • ユーザの視点の計測が必要 ←→ nineの数
        • クラウドネイティブ アプリケーションは完全にupにはならない
          • gray failures 問題
    • logging: 中央DBに集約 → 問題のtrouble shoot
      • limit: developerのjudgeで作成.query difficult, signal/noise比が△
      • scale difficult
      • logを超えた方法が必要 → Metrics
    • メトリクスの導入
      • @アプリケーション's メトリクス
        • 処理中のリクエストの数, 毎分リクエスト処理数
        • リクエスト proceed中のerror数, リクエスト処理に要したaverage time
      • @Infrastructure's メトリクス
        • プロセス/コンテナのCPU使用率
        • ノードやServerのdisc I/O activity
        • machine, クラスタ, load balancerのI/O network traffic
      • メトリクス: 「なぜか」の解決に有用
        • 予測にも使える
        • アプリケーションを内部から監視
          • 実際の動作に基づいてシステムの隠れた側面に関する重要 情報を外に伝えられる
          • → 〇内からの監視/ ×reverse engineering
    • tracing @分散 システム
      • 単一のユーザ リクエストのlifecycle全体を表す: リクエストの始点
    • メトリクスや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 劣化とする

作用

  • クラウドネイティブ環境で監視が目指すべき方向性
  • オブザーバビリティの価値 with メトリクス

Ch16 KubernetesにおけるMetrics

目的

  • Metricsの扱い方
  • Metricsとは
    • 特定の対象を測定した数値
      • → 特定の瞬間における状況のsnapshot + 変化を示す
    • 時系列データ by sampling
    • メトリクス値: Counter/Gauge
      • Counter: increment only or reset to 0.
        • 量の表現
      • Gauge: 増減〇. memory使用率など
        • 比率の表現
    • 異常やfailureの通知 + 機能状況の表示
      • → 「なぜか」の解決

概要

  • (1) 優れたメトリクスのchoice
    • メトリクスの一部へのfocus
    • 要件ごとのオブザーバビリティのためのメトリクス pattern
      • service: RED pattern
        • serviceの示す性能
        • ユーザの体験情報
        • ↑ これらの情報を得られる → 「オブザーバビリティ データ」のためのtop down 型の方法
        • REDは リクエスト駆動のシステム
          • Requestの数 → 1secあたりの受信リクエスト数
          • Errorの数 → エラーとなったリクエストの割合
          • リクエストの持続期間(Duration) ≒ レイテンシ
              • 飽和度(saturation) → 4大signal
      • リソース: USE pattern → 性能問題の分析とボトルネックの発見のためのbottom up型の方法 ←→ service
        • :システムの健全性のcheck, 高速で可視性高い
        • Utilization: 使用率
        • Saturation: 飽和度
        • Error
        • 対象は〇リソース/ ×Service
          • → システム 性能のbottleneckの発見
            • e.g. CPU, disc, networkのIFやLink
    • ビジネス メトリクス
      • 加入者についてのデータの把握
        • funnel analysis
          • 解約率
          • 収益/顧客
          • help, support pageの有効性
          • System Status pageへのtraffic量
      • 共通のdatalakeを使用 in two or more groups
    • Kubernetesのメトリクス
      • クラスタ healthのメトリクス
        • ノード数
        • ノードのhealth status
        • Pod数/ノード or Pod数 in all
        • リソース使用率, 割り当て by ノード or 全体
    • デプロイのメトリクス
      • デプロイの数
      • デプロイごとのreplicaの設定数
      • デプロイごとの利用不可のreplicaの数
    • コンテナに関するメトリクス
      • コンテナ/Podの数 by ノード or 全体
      • リソース使用率 to リソース要求/リソース制限
      • コンテナのLiveness/Readiness
      • コンテナ/Podのrestart 数
      • 各コンテナのnetwork I/O traffic and error
    • アプリケーションのメトリクス
      • アプリケーションの機能による
      • 性能や可用性の問題のため
      • アプリケーションの実行内容,頻度,処理時間
      • とりあえず不明なら記録する
      • SLOやSLAに対するアプリケーションの性能も知る
    • runtimeのメトリクス
      • プロセスのrun statusを知る
        • 6こ
      • 性能の劣化やcrashについての診断に〇
  • (2) メトリクスの分析
    • データ != 情報: 情報にするための統計処理
    • 単純な平均の問題: 大多数の人々の経験には不益
      • 外れ値の作用を受けやすい → アンスコムの通知例
        • ←→ 中央値
    • リクエスト ドリブン → レイテンシのworst値が重要 → persentile(百分位数): p90, p50(中央値), p95, p99(e.g. →p.321)
    • worstが重要
    • persentileの問題
      • averageのaverage 問題
      • 間違ったstateの監視が重要
  • (4) メトリクスのdashboardによるグラフ化
    • メトリクスのグラフ化 → dashboardにグループ化
    • すべてのserviceでstandard layout(e.g. → p.323)を使う
    • 全service横断でメトリクスを集約して表示するmaster dashboard
    • あくまで,折れ線グラフというシンプルなstyleにする
    • vitalな情報を情報 radiatorで表示
    • アラートにかからないで壊れていくものを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)
      • すべてのリソースに一意となる識別子(URI)があるという思想.
      • URIを通してリソースを操作する手段を提供
      • リソースを操作するための動詞を中心に考え,機能追加しやすい自然な設計にする
    • 自動テスト
    • まとめ
      • Web applicationをRailsが語る思想に沿ったarchitectureで作成することを,The Rails Way, レールに乗ると表現する.
  • 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とは個別のコマンドとして用意された単体スクリプトの実行
  • scaffold(足場)
    • CRUD操作を行うMVCそれぞれのコードと,テストやDBのテーブル定義を行うmigration fileなどを生成.
    • project作成→scaffold実行
    • DBの変更をmigrationファイルで管理
    • routesでURL設計を確認.
    • RESTfulな考え方がベースとなり作られる.
    • controller, routing
    • routingでURLとコントローラ内のメソッドを紐づけることでURLに対応するアクションを定義.アクションの中で,モデルを通じてデータを取得.そのデータをもとにテンプレートファイルを通じてHTMLを作成・描画している.

Ch02 Ruby on RailsMVC

目的

  • MVCの各要素に対してどのようなコードを書けばよいか見る.
  • MVCのそれぞれの基本的な機能を学ぶ.

内容

  • MVC architecture
    • Model
    • View
      • Modelの内容を参照し,視覚表現を行う
    • Controller
      • Modelのロジック呼び出し,必要なViewの選択など,ModelとViewをつなぐ部分
    • モデルの基礎と考え方
      • modeling: システムを作ることは,解決する問題に対して必要な概念を探して,命名・関係性の整理を行うこと.
      • ActiveRecordでのmodelのimplementation
      • modelとCRUDとの対応.
  • modelを扱う
    • modelを通じた検索
      • ActiveRecord::Relationクラスについて
        • ActiveRecordのQuery Interfaceによる操作結果をオブジェクトとして表現するもの
        • SQLの情報を保持し,実際に必要になったときのみDBにアクセス.
          • 明示的にSQLを発行するときは,to_a method
        • Scopeで,よく使う検索条件をまとめて命名
          • nilを返す必要があるときはクラスメソッドで定義する方が〇
        • default_scopeは安易には使えない
    • model同士のrelation
      • 関連付け
        • SQLite3のための対応必要.
      • has_many, has_one, belong_to
      • 多対多
        • 中間テーブルが必要.
    • dataの更新
      • create, save
      • validation
      • !をつけるとvalidation失敗時に例外発生
    • callback
      • callbackpoint
    • enum
      • !, ?
  • 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を取得できる
    • helper methodの活用例
      • url_for
      • link_to
      • form_with
      • stylesheet_link_tag, javascript_pack_tag
      • その他
      • 独自メソッド定義
        • app/helpers
    • escape 処理
      • XSS対応
        • そのまま表示 → raw
    • template engine
      • ERB
        • \%を使ってRubyのコードを評価
      • Haml
        • indentでHTMLの構造を表現できる
        • gem packageとして取得する
      • Slim
    • API server として振る舞うときのviewについて

まとめ

  • Model層について,ActiveRecordの基本的な操作,validation,callback
  • Controller層について,ModelとViewをつなぐこと,request objectやaction callback,脆弱性への対処
  • View層について,受け取ったModelを表示すること,template engine, helper method,様々なformatでの表示

  • applicationの主要なlogicはなるべくModelに書くべき

    • Fat Modelへの対応必要.
  • API専用のRails application

    • frontendのimportance高まり,描画を完全にJSに任せるケースあり.
    • rails new my_api --api

Ch03 Railsのbasic機能

  • testの種類と実行方法
    • 各ファイル・ディレクトリごとにテスト対象がある.
    • testの実行
      • bin/rails test (-v)
      • directory単位,ファイル単位,特定の行,テスト名の指定ができる
    • minitestをRailsで扱う
    • fixtureでテストデータを定義
      • modelname(:fixturename)
    • setup, teardown
    • Rails 6.0から,並列テスト可能になる
      • test/test_helper.rb
        • parallelize(workers: 1)とすると並列度が1になる
        • with::threadsとすると,processでなくthreadで並列実行できる
  • 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の上下関係の設定もできる
  • DBの管理
    • DB関連task
      • RAILS_ENV=productionで製品環境を指定できる
    • 定義の反映
      • db:rollback STEP=1
    • schema fileの取り扱い
    • 用意したデータを読み込む
      • db/seeds.rb
      • !をつけて,エラー発生にすぐに気づけるようにする.
    • table stateを扱う
      • reset = drop + setup
      • prepare: migration, or setup
    • 複数DBを扱う
      • config/database.yml
      • --database=sub
      • 書き込みと読み込みの分離
        • config/environments/production.rb
  • 秘密情報の管理
    • versionごとに管理方法が異なる
    • より開発プロセスにあった形になっている.
  • HTTPとRails application
    • Early Hints
      • 200 OKの前に,103 Early Hints
        • HTMLのパース中にアセットのロード可能
    • CSP(Contents Security Policy)
      • config/initializers/content_security_policy.rb
      • nonce
      • strict-dynamic

Part 2 Railsの周辺知識

Ch04 frontendの開発手法

  • Railsで利用するエコシステムの軸をfrontend開発の標準的な仕組みに移している.
  • JSを管理
    • CSSや画像の管理
    • 自動ビルド
    • ビルド方法の切り替え
    • libraryの統合
    • plugin, loaderの追加
  • CSSの管理
    • CSSを拡張した言語をCSSコンパイル,リクエスト数削減のために1つのファイルへ結合する処理など.
    • 本番環境向けビルド
      • file size削減
    • JSの機能 built in Rails
      • 画面の制御
      • Ajax通信
      • 画面遷移の高速化
        • body tagの中身を入れ替える
        • event の発火
        • Turbolinks
  • 控えめなJS framework
    • Stimulus: 規約をもたらすframework
      • server sideにbusiness logicの実装が寄る
        • HTMLはサーバから返す
        • server sideとfrontendを合わせたトータルの工数が少ない
        • frontendで表現できる幅が狭まる

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の作成と下準備
    • applicationの作成
    • Hamlの導入
    • 独自のtop pageの表示
      • top page用のcontrollerの作成
    • gemのversion up 戦略について
    • Bootstrapの導入
      • CSSの記述を最小限にしつつ,デザインを調整しながら開発できるようにする
  • OAuthを利用して「GitHubでログイン」機能を作る
    • GitHub applicationの登録
    • ログインのための機能の作成
    • user model作成
    • ログイン処理の作成
    • ログアウト処理の作成
  • event registration機能の作成
    • time zoneの設定
    • event用のmodelの作成
      • 文字数の制限
        • 正しいデザインで表示するため
    • ログイン状態を管理する処理の作成
    • event registration用のフォームの作成
    • validation error時の設定
      • SJR(Server-generated JS Responses)
    • i18nの設定をする
  • eventの閲覧機能を作る
    • l: localize
  • eventの編集・削除機能を作る
    • 関連を利用する
  • 登録されたeventへの参加機能,参加キャンセル機能を作る
    • N+1問題
    • helperの使い方.オブジェクト指向的な書き方にならない.多いときはプレゼンター.
    • 必ずredirect→インスタンス変数をビューに渡す必要なし→インスタンス変数を使わず可読性を上げる
    • has_manyにdependent: :destroyで,親オブジェクトのレコード削除時に子のレコードも削除.
  • 退会機能を作る
    • 基本の7つ以外のアクションを作りたくなったら別のコントローラを作る.
  • おわりに
    • なぜこのような機能があるのかが重要

Ch07 Rails applicationの test

  • test codeをどう書いていくか
    • システムテストから書く
      • reasons
        • 概要をつかんだ時点でテストを書き始められる
        • すべてを通るのでカバレッジを効率よく広げられる
        • applicationに対する理解が深まる
      • problems
        • ブラウザを使うためスピード遅い
        • モデルなどの部品ごとの仕様の検証は不可能
  • minitest, RSpec
  • test data作成
    • factory_bot
      • sequenceで,固定値を回避
      • 乱数を同じにする場合はseedをオプションで指定する.
  • system test
    • 環境の問題の解決が必要@wsl2
  • controller test
  • model test
    • stub, mock
    • ランダムな値で都合のいいデータを回避
    • validationのテストの扱い

Part4 Rails applicationの拡張・運用

Ch08 Rails application 拡張

  • file upload機能の作成
    • libvipsを使う
    • direct upload時のvalidationは注意点アリ
  • gemで機能拡張する
  • その他の機能
    • error handling
      • rescue_fromは後に登録したものから順番に判定
      • Rack Middlewareを使ったerror handling
        • 独自の例外でpublic/500.html以外を表示したい場合に設定する
        • dynamic error pageのdemerit
      • routingの制限
  • gemの選定

Ch09 コードの品質を上げる

  • CI
    • GitHub actions
      • Elasticsearchとplugin
  • 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のレコードとオブジェクトを対応付け
    • what's ActiveRecord
    • 単一table継承
      • あるクラスから派生するすべてのサブクラスを1つのtableに対応させる
        • type columnで,各レコードがどのクラスに属するか識別
          • 扱いがほかのカラムと異なる
      • 継承の是非の検討が必要
  • value object
    • entity: 属性の値にかかわらず一意に識別
    • 値objectに切り出す
      • composed_of
  • service object
    • 複数のobjectを組み合わせて表現するとき
    • eventで表現できる場合はeventで表現する
      • test doubleを使えないdemeritあり
    • 実装rule, interface

Ch12 複雑なUCを実現

  • UCとmodel
    • UC @ Rails
      • resources methodによるresource baseのroutingが基本
        • RESTに沿ったroutingを定義
      • URLで表されるresourceをDBのtableと1対1で対応させ,これらのCRUDの操作を通じてUserとやり取り
      • 1つまたは複数のCRUD操作によって,1つのUCを構成
    • Railsのレールの正体
      • modelのCRUD操作の前後に実行される処理を追加することでUCを実現するというapproach
        • e.g. validation, callback
      • UCのlogic: 対象のUCがなければ存在しない,付随するもの
        • domain logicとは異なる
    • レールの限界
  • 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の定義
  • 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
      • 参照系には利用できない

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の方がメインとなっていると思う。 ワークフローについて。