[研討會] Modern Web 2016 - Day2 上台日

第一天的心得

我的演講: 利用 Golang 架設 Line 機器人,作為網站的推廣大使

Modern Web 2016: Using Golang to build a smart IM Bot from Evan Lin

演講心得

  • 之前 COSCUP 講得太快,所以不自主地把投影片的數量又加大不少.不過就變得太長.
  • 太多部分在著墨 Golang,這也是因為這個場子沒有講解 Go 的人.會想要推廣 Golang
  • 花太少來著墨 BOT 與 LUIS ,不少同學都是會後才來詢問.

Tuning NGINX for High Performance

投影片所有相關鏈結

Apache will handle whole service before response it, it might have problem for 10k connection. Nginx focus how to handle more usere in one server.

To improve whole performance from architecture, please consider CACHE in any layer starting from Appliation.

Basic Nginx placement:

Host Nginx as load balancer or reverse proxy.

Client <-- HTTP/2 --> NGINX <-- HTTP/1.X, FastCGI, UWSGI, etc --> Servers

OS Tuning for Nginx

Refer this link.

  • net.core.somaxconn
  • net.core.netdev_max_backlog
  • net.ipv4.ip_local_port_range
  • sys.fs.file_max
  • /etc/security/limits.conf, nofile setting

One connection will open two files open, when you receive 2000 connections it mean at least you need open file limit over 4000.

Overcoming ephemeral port exhaustion (短暫的 port 耗盡)

  • include local port range ( net.ipv4.ip_local_port_range )

NGINX Core Features

Use correct number of worker_processes

Nginx will refer CPU limit of your container limit to arrange resource.

HTTP Caching

Conclusion:

  • Plan for scale early
  • Tuning from low level (OS level)

Questions

  1. Why not follow sendfile and accept mutex setting default?

當當網 - 電商基礎架構之路

投影片

當當網: 中國最大圖書銷售平台,沒有自己的物流系統,同時也在淘寶有設攤位.

鐵公基: 鐵路,公路,基礎建設.

基礎架構: 這邊指的是

為何要建設基礎架構

  • 充實基礎,事半功倍
  • 隔離代碼
  • 降低技術債

數據庫管理

需要能夠跨資料庫管理 ( MySQL, Oracle, MongoDB … )

緩存 (Redis) 集群管理

統一管理 Redis 的用法,並且可以了解各個部門的使用狀況.

系統監控

Nagios -> Zabbix

開源 Elastic-Jobs

Github

總結:

  • 自動代替人工
  • 小技術驅動大團隊
  • 基礎平台上支撐上層應用

搜狗 - 移動開發的銀彈 – React Native 探索與實踐

投影片

移動開發技術的發展

  • 2006 Symbian WML
  • 2009 ios Android
  • 2011 Hybrid PhoneGap
  • 2012 插件化
  • 2014 HTML5
  • 2015 React Native 動態化

安裝痛點:

  • npm 安裝緩慢 -> 架設私有 npm server

平台復用準則

  • 邏輯重複使用
  • 不同平台組建,分開實現 (tab.ios.js, tab.android.js)

調試踩坑

  • Debug work, 手機 crash
    • A: 在 Windows 開發,使用到 JS Windows library.封裝 Native Library
  • MVC 分離測試
    • A: 透過 Mock 來調適

騰訊 - 移動娛樂直播下監控與極限優化

投影片

對於機器的優化

  • 先計算機器效能 (透過最高 fps 的播放測試)
  • 選擇相關可以播放的 profile
  • 對於直播業務,測試該使用者的上傳效率. (下傳可以 buffer )

直撥優化

GOP (Good Of Picture)

  • i, p, b frame (9 frame only include one i frame)
  • Each frame take 5 second, wait at least 3 frame ( 15 seconds)
  • Make sure user(viewer) first get i-frame

只有下載播放的部分

  • 優化 H5 需要 3 HLS frame to playback
    • 優化 GOP (補幀)
  • 有互動播放的部分(強調 low latency)
    • 透過 RMTP

錄播優化

  • 動態調整 GOP

心得:

主講人速度很快,但是內容相當的充實有料. 並且充分顯示出主講人對於整個娛樂直播的優化有著相當程度的瞭解. 在會後的討論下,講者充分顯示出對於互動與非互動直播的狀況下,都有相關的處理經驗可以來進行優化.相當建議把投影片好好的閱讀.

參考鏈結:

[研討會] Modern Web 2016 - Day1

前提:

之前想好好的宣傳 Golang ,於是乎一次投了兩個研討會.其實本來問題是不大的,只是剛好是同個禮拜(一個週日,一個週四).真是太棒了 (昏倒…)

不過今天相當的開心的跟了碼天狗的幾位作者 ( 同時也是講者 ) LY ,海總理還有特地趕來聚會的 Tim Kuo . 還有新認識的一堆講者. 難怪不少研討會都說,想要認識講者最好的方式就是… 成為講者.

Douglas Crockford (Paypal) - Typing

投影片

  • History of Typing:
    • Language
    • Alphabet (upper)
    • Alphabet (lower for writing)
    • Typing
      • The indent of key is to avoid key collision.
      • The arrange also to avoid collision.
      • “0” should come before “1”, all keyboard arrangement still wrong for now.
    • ASCII code original use to for “writer” not “computer”
  • Old typewriter history:
    • One key combine with two word (upper/lower), Shift key to machanical shift the key to another one.
    • Ctrl key is to call key control charactor if exist. (TAB is control part in “i” key.
    • Return key to return to the begin of line (just like 0x0a)
    • Line feed key to scroll papper line (just like 0x0d )

心得:

從一開始語言的起源,到了字母的發明,最後到了打字 (Typing) . Douglas 說許多科技其實其來有自,你必須要好好了解科技的源頭,了解許多事情的原因,你才會了解為什麼會有這些相關科技的產生.

舉例而言,拿很古老的打字機上面的鍵盤排列來說:

  • Shift key
    • 一開始打字機為了要能顯示大小寫,其實一個按鍵黏著大寫與小寫的字母.而 Shift 就是要能夠機械式地移動( shift it ) 那個硬件去切換大小寫.
  • Control key
    • 現在已經越來越少使用了,其實一開始鍵盤上面是沒有 Tab 按鍵的.而 Tab 按鍵是使用 “I” 的按鍵.如果要使用 Tab 需要按下 Ctrl + “I”. 所以叫 Ctrol key
  • 關於換行:
    • 以前在打字機,要換行需要打兩次.一次是 Return 來將你的打字機頭移回最左邊,再來需要打一個 Line Feed 去將白紙向下移一個.
    • 這也就是為什麼許多電腦裡面. LFCR 其實是兩個字母 LF(Line Feed) 0x0A 與 CR(Carriage return) 0x0d 的原因.

Programa

是 Douglas 製作出來的字型,根據他的一些偏好.比如說:

  • l 1 太相似,於是小寫的 L 就是比較小的 L
  • \/ 可以替代 Logical OR (   ) , /\ 可以替代 Logical AND (&&) .

Ian Matthew - Building and Deploying Scalable Microservice with Go & Kubernetes

投影片

  • Pod:
    • A local view of docker container (one pod for one image)
    • It could be handled by Resource Controller
  • Service:
    • Combine with one or several pods replica, with one “virtual IP” and port.

快快樂樂學會 Angular 2 網站開發框架 (保哥 / 多奇創意技術總監)

投影片

  • Angular 2 is not compatible with Angular1
  • Angular 2 setup might not easy and strantforward..
  • Angular 2 serve by ng serve and it is onfly (no need for refresh).
  • Some modification:
    • Event: OnClick -> (click)
  • Use ng g COMPONENT to generate new component. (similiar with Rails)
  • Only one js file, webpack will injection all related code.

電子商務 Audience Marketing, Growth Hacking 自動化設計及成效報告

投影片

Growth Hacking Model - AARRR

  • Acquisition
    • Facebook Id / Line mid / Google ID /… 識別不同平台的使用者 將資料綁定於UID
    • 追蹤單一 user 在不同平台上的行為
  • Activation
    • Searched Keywords
    • Active Interest
    • Product Catalog
    • Purchase history
    • Browser history
  • Retention
  • Referral
  • Revenue

Model 1: People v.s. Product

  • 產品身上有帶標籤 (lable1, lable2 ….)
  • 當使用者購買商品後,標籤會從產品身上帶到使用者身上.
  • 如果使用者將訊息傳遞給其他使用者,標籤也會做稍微的轉移.

標籤過多並沒有太多好處,大多數狀態標前只要有七組就足夠

Model 2: 加上 Facebook 興趣

如同第一個 Model 只是會由臉書反饋興趣回來.

結果

  • CTR up 200%
  • CPC reduce 50%
  • ROI up 30%

海總管 - StreetVoice 自動化部署演進

投影片

格言:

  • 做喜歡的事,讓他有價值
  • 繁瑣的事情,讓他自己動

演進:

  • FTP
  • Fabric
  • Saltstack
  • Ansible

通知

  • Hubot + slack

讓你的 PHP 開發流程再次潮起來

投影片

PHP 為何不潮?

  • 版本很難更新
  • 難導入 Laravel ( PHP 版本要求高,新版的 5.3 要求 PHP 5.9 )

環境導入:

如何將舊有網站導入 Laravel

  • 新的放 Laravel
  • 舊的放在 Laravel public
  • 從後台開始導入
  • 使用 Route 舊版轉址

ANT - 恰如其分的 MySQL 設計技巧

投影片

  • 架構先決:
  • 架構先行:
    • 先行探討整體架構與 License
    • License:
      • GPL 具有感染性,如果公司產品有用到 GPL 也會被感染到.就必須 Open Source
    • 欄位設計思考:
      • is_deleted, is_modified –> status 可以做更多延伸
    • 需求的思考:
      • 1 天不要看到 -> 半天不要看到 -> 半天不要看到同類廣告 (X)
      • 在 M 小時內不要看到 N 類廣告 (O)

限制

High Throghput

  • 演唱會

Low Latency

  • RTB (30ms), 高頻交易 (0.5~3ms) NFV??

MySQL Support

  • 5.5 (16 cores)
  • 5.6 (64 cores)

Connection Poll 缺點

  • 不是所有 App 都支援
  • 發生錯誤,需要整體資源清理
  • 經常狀況下,容易被 keep 而不會釋放.

Scale

  • Scale up -> Improve CPU, Memory, HD
  • Scale out -> Added more machines

參考鏈結:

[研討會心得][COSCUP] COSCUP 2016 上台初體驗

前提:

今年是第三年參加 COSCUP ,其實也有些時候沒有參加任何的研討會.大概是因為已經給自己立定想法,必須要有想辦法當講者才能參加的信念.

而今年 COSCUP 我覺得議題都很不錯,可惜我因為要顧小孩只能參加第二天的場次(也是因為自己的場次在第二天).

參與場次:

Evan Lin - Project 52 每週一個小專案來學習Golang

Slide:

COSCUP 2016: Project 52 每週一個小專案來學習 Golang from Evan Lin

詳細的 Hackpad 在這裡,不少同學有做了一些筆記 .

影片:

鏈結在這裡

講者心得:

第一次參與大型研討會,加上是 H0 有點大 XD ,說不緊張是不可能的. 一緊張就容易講得快,所以大概在 25 分鐘就把所有 slide 都講完了. 後面的時候還好有 appleboy 的救援與講解一些心得.

以下整理一些心得:

  • 盡量準備多一點的 slide ,往往一張 slide 很難講到一分鐘.所以基本上應該要兩倍以上.
  • 每張 slide 之間需要讓自己喘一口氣,避免讓台下的人也吸收不良.
  • 如果想講一些 “木更” 也請記得慢慢講,讓台下的人有時間笑 (或是不笑 orz )

身為講者,其實都會很希望能跟聽眾互動.如果沒有辦法提問題,就算是結束後,你來講一句話也好.也期勉自己以後參加任何研討會都要想辦法跟講者互動.

Appleboy - 用 Golang 寫 Microservice

slide:

Write microservice in golang from Bo-Yi Wu

影片:

鏈結在這裡

心得:

這場是我當主持的, Appleboy 幫我把許多 Golang 的概念與基礎介紹都講得相當清楚.如果你想了解如何寫 Golang ,很建議好好的閱讀他的 slide .

Jason Lin, Sas Chen - A High Scale ML Platform Using SPARK and KAFKA

內容:

擷取自 Hackpad (其實不少都是我打的 :p )

Batch Processing

  • Recommendation
    • Alternating Least Sq
    • Log Regression
    • GBDT
    • Clustering
    • Top-k rank
  • Text mining
    • naive bayes
    • latent dirichlet allocation
    • word2vec

  • Streaming Data
    • Original:
      • product id -> get inventory -> update inventory
    • Using multiple thread:
      • Cannot promise the threading ordering.
  • Kafka also requires key partitioning
    • Using product ID hash as key
  • How to determine if your Kafka scalable

ML

  • Synchronous:
    • Get w, update back w’
  • Asynchronous
    • Get w, update delta w.

Davide Casali / Tammie Lister - Designing Inclusive Open Source Communities

影片:

鏈結在這裡

心得:

兩位來自 WordPress 公司的人來講解如何建立一個開源程式碼社群. 裡面提到很多的概念,都相當的棒. 不過聽的人不太多,真是可惜.

主要內容都是當你的開源專案慢慢受到注意的時候,你該如何的分別主要開發者 (core lead team) 還有貢獻者 (contributors) .

如何參與開源專案的貢獻:

  • 先了解每個專案的指南
  • 可以試著問 issue 或是直接幫忙寫文件(應該會是最受歡迎的 PR :p)
  • 幫忙翻譯
  • 對於開源專案的貢獻絕對不僅僅是程式碼.可以是文件,可以是幫忙行銷.幫忙推廣都算是貢獻的一種.

並且如何去鼓勵每個參與者來積極的供獻你的開源專案,關於這部分有提到一些:

  • 建立良好的指南,讓每個貢獻者覺得簡單並且受到重視.
  • 對於每個貢獻者,絕對不要客氣地提到並且誇獎他們.
    • 可以透過 Badge
    • 當有任何 Release ,記得提到所有貢獻者.(就算只是問問題,寫個 README 的)
    • 針對不同團隊來提到每個貢獻者.(如果有幫忙推廣的,也請記得提到)
    • 不論如何,只要有幫助開源專案的人,都得想辦法提到他們讓他們有參與感.

以下部分截自 Hackpad (其實是我寫的)

  • Culture Problem
    • Timezone
  • Power Problem
    • Decision problem is in the code
    • Decision making
    • Personalities
  • Diversity
    • Kinds of diversity (age, gender …)
  • Persona
  • Core team growth
  • Delegate
  • Onboarding
    • Feel welcome
    • Encourage how to contribute
  • Many ways to contribute
    • Most easy way : write documentation
    • Improve existing ticket (make it more valuable)
    • Translation
  • Transparency
    • Discussion in the open
    • Meeting etiqutte
      • Call for topic
      • Archive whole discussion
  • Credit
    • Not only commit, but also contribution.
    • Profile Badges (coder, translator…)
    • Show contribution history.
  • Open to Failure
    • Admin your failure
    • Show people who failure but still can participate

Q&A:

  • Q1: Who has the right the apply huge change?
    • A:
      • Depends on project side, could be project leader.
      • Vote could be leading team who has bigger view of project.
  • Q2: How to reject some PR you may not want to (nicely)?
    • A:
      • Some PR may wrong but come from great institute. Try to understand it.
      • Try to understand the PR

參考鏈結

[TIL] 關於 Docker Remote API 的學習

什麼是 Docker Remote API

每個 Docker Daemon 其實都有提供 Remote API .其工作主要都是提供一個介面可以讓 Docker Client 透過 API 來控制. 舉凡大家日常使用的指令 docker images 或是 docker ps 其實都是使用 Docker Remote API 的方式來連接本地端的 Daemon 來對 Docker Daemon Service 下指令.

此外, docker-machine 對於遠端的機器也是透過 Docker Remote API 的方式.

如何在 Mac OSX for Docker 使用 Docker Remote API

尋找 Docker-Machine Certificate

當你使用 Docker-Machine 來建置機器的時候,其實你的 Certificate 會存放在 /Users/YOUR_USERNAME/.docker/machine/machines 裡面.

該 Certificate 就是存放著讓 Docker Client 與 Docker Daemon 能夠相互溝通的金鑰資訊.

舉個例子:

如果你有建立一個 Docker-Machine 的機器名稱為 default,那麼 Certificate 檔案就會存放在:

/Users/YOUR_USERNAME/.docker/machine/machines/default

裡面.

透過 curl 連接 Docker Remote API

以我的名稱 Evan 的作為一個範例的話:

### Set your environment variable 
> export DOCKER_CERT_PATH=/Users/Evan/.docker/machine/machines/default
 

### Get Docker Machine IP
> docker-machine ip default
192.168.99.100

## Use CURL
> curl https://192.168.99.100:2376/images/json --cert $DOCKER_CERT_PATH/cert.pem --key $DOCKER_CERT_PATH/key.pem --cacert $DOCKER_CERT_PATH/ca.pem

curl: (58) SSL: Can't load the certificate "/Users/Evan/.docker/machine/machines/default/cert.pem" and its private key: OSStatus -25299

如果出現以下的錯誤:

curl: (58) SSL: Can't load the certificate "/Users/Evan/.docker/machine/machines/default/cert.pem" and its private key: OSStatus -25299

代表你沒有 cert.pem 需要執行額外的 key 轉換的動作

> cd /Users/Evan/.docker/machine/machines/default

# key transfer
> openssl pkcs12 -export \
-inkey key.pem \
-in cert.pem \
-CAfile ca.pem \
-chain \
-name client-side \
-out cert.p12 \
-password pass:mypass

接下來再來執行:

> curl https://192.168.99.100:2376/images/json --cert $DOCKER_CERT_PATH/cert.p12 --pass mypass --key $DOCKER_CERT_PATH/key.pem --cacert $DOCKER_CERT_PATH/ca.pem

[
  {
    "Id": "sha256:d38beda529d3274636d6cb1c9000afe4f00fbdcfa544140d6cc0f5d7f5b8434a",
    "ParentId": "",
    "RepoTags": [
      "arungupta/couchbase:latest"
    ],
    "RepoDigests": null,
    "Created": 1450330075,
    "Size": 374824677,
    "VirtualSize": 374824677,
    "Labels": {
      
    }
  }
]

就會回傳 Docker Machine 中的 Docker Daemon 的狀態.

查詢 Docker Container 的執行狀態,使用率

docker stats 是一個很方便的指令,可以顯示出目前在執行的 Container 的狀態與使用率.

這邊舉出一個簡單的例子:

>docker stats

CONTAINER           CPU %               MEM USAGE / LIMIT       MEM %               NET I/O               BLOCK I/O           PIDS
fb5435a83a96        0.00%               48.76 MiB / 1.954 GiB   2.44%               117.5 kB / 76.08 kB   19.86 MB / 0 B      9

透過 Docker Remote API 查詢 Docker stats

如果前面的設定都已經設定好了,你也可以透過 Docker Remote API 來查詢遠端機器

## 假設在 docker-machine default 裡面跑有兩個 container
> docker-machine ssh default

> docker ps

CONTAINER ID        IMAGE                   COMMAND                  CREATED             STATUS              PORTS               NAMES
66ee7abb2a12        instavote/vote:latest   "gunicorn app:app -b "   5 days ago          Up 5 days           80/tcp              voteV.1.3u2i8gnttseibckfsnqr9dp58
e510fa405940        instavote/vote:movies   "gunicorn app:app -b "   5 days ago          Up 5 days           80/tcp              vote.1.3hozslyep7al27u35zb24o6mp

## 查詢該 Container 66ee7abb2a12 的狀態
> curl https://192.168.99.100:2376/containers/66ee7abb2a12/stats --cert $DOCKER_CERT_PATH/cert2.p12 --pass mypass --key $DOCKER_CERT_PATH/key.pem --cacert $DOCKER_CERT_PATH/ca.pem

{
  "read": "2016-08-15T05:10:49.404713534Z",
  "precpu_stats": {
    "cpu_usage": {
      "total_usage": 0,
      "percpu_usage": null,
      "usage_in_kernelmode": 0,
      "usage_in_usermode": 0
    },
    "system_cpu_usage": 0,
    "throttling_data": {
      "periods": 0,
      "throttled_periods": 0,
      "throttled_time": 0
    }
  },
  "cpu_stats": {
    "cpu_usage": {
      "total_usage": 26505881978,
      "percpu_usage": [
        26505881978
      ],
      "usage_in_kernelmode": 1690000000,
      "usage_in_usermode": 5730000000
    },
    "system_cpu_usage": 110834160000000,
    "throttling_data": {
      "periods": 0,
      "throttled_periods": 0,
      "throttled_time": 0
    }
  },
  "memory_stats": {
    "usage": 56270848,
    "max_usage": 75644928,
    "stats": {
      "active_anon": 55996416,
      "active_file": 274432,
      "cache": 286720,
      "dirty": 4096,
      "hierarchical_memory_limit": 9223372036854771712,
      "hierarchical_memsw_limit": 9223372036854771712,
      "inactive_anon": 0,
      "inactive_file": 0,
      "mapped_file": 0,
      "pgfault": 363243,
      "pgmajfault": 0,
      "pgpgin": 318130,
      "pgpgout": 306436,
      "rss": 55984128,
      "rss_huge": 8388608,
      "swap": 0,
      "total_active_anon": 55996416,
      "total_active_file": 274432,
      "total_cache": 286720,
      "total_dirty": 4096,
      "total_inactive_anon": 0,
      "total_inactive_file": 0,
      "total_mapped_file": 0,
      "total_pgfault": 363243,
      "total_pgmajfault": 0,
      "total_pgpgin": 318130,
      "total_pgpgout": 306436,
      "total_rss": 55984128,
      "total_rss_huge": 8388608,
      "total_swap": 0,
      "total_unevictable": 0,
      "total_writeback": 0,
      "unevictable": 0,
      "writeback": 0
    },
    "failcnt": 0,
    "limit": 1044246528
  },
  "blkio_stats": {
    "io_service_bytes_recursive": [
      
    ],
    "io_serviced_recursive": [
      
    ],
    "io_queue_recursive": [
      
    ],
    "io_service_time_recursive": [
      
    ],
    "io_wait_time_recursive": [
      
    ],
    "io_merged_recursive": [
      
    ],
    "io_time_recursive": [
      
    ],
    "sectors_recursive": [
      
    ]
  },
  "pids_stats": {
    "current": 5
  },
  "networks": {
    "eth0": {
      "rx_bytes": 648,
      "rx_packets": 8,
      "rx_errors": 0,
      "rx_dropped": 0,
      "tx_bytes": 648,
      "tx_packets": 8,
      "tx_errors": 0,
      "tx_dropped": 0
    },
    "eth1": {
      "rx_bytes": 648,
      "rx_packets": 8,
      "rx_errors": 0,
      "rx_dropped": 0,
      "tx_bytes": 648,
      "tx_packets": 8,
      "tx_errors": 0,
      "tx_dropped": 0
    }
  }
}

透過 Golang Code 來直接查詢

Docker 官方有提供一個很方便的 Golang 套件 engine-api

如果想要找到其他語言的套件,可以到這個地方去找 Docker Remote API client libraries

package main

import (
	"fmt"
	"io/ioutil"
	"log"

	"github.com/docker/engine-api/client"
	"github.com/docker/engine-api/types"
	"golang.org/x/net/context"
)

func main() {
	defaultHeaders := map[string]string{"User-Agent": "engine-api-cli-1.0"}
	cli, err := client.NewClient("unix:///var/run/docker.sock", "v1.22", nil, defaultHeaders)
	if err != nil {
		panic(err)
	}

	options := types.ContainerListOptions{All: true}
	containers, err := cli.ContainerList(context.Background(), options)
	if err != nil {
		panic(err)
	}

	for _, c := range containers {
		fmt.Println(c.ID)
		body, err := cli.ContainerStats(context.Background(), c.ID, false)
		defer body.Close()
		if err != nil {
			log.Println(err)
		}
		
		//顯示 Container 資訊
		content, err := ioutil.ReadAll(body)
		log.Println("Container:", c.ID, string(content))
	}
}

透過這樣查詢,可以得到類似以下的資訊:

2016/08/15 15:57:55 Container: fb5435a83a96a753e61b3020d6478650158ae9382f41f3119e3feafb65d2e07d

{
  "read": "2016-08-15T07:57:55.652878954Z",
  "precpu_stats": {
    "cpu_usage": {
      "total_usage": 709001154,
      "percpu_usage": [
        428133113,
        31262531,
        45274798,
        204330712
      ],
      "usage_in_kernelmode": 50000000,
      "usage_in_usermode": 590000000
    },
    "system_cpu_usage": 185639070000000,
    "throttling_data": {
      "periods": 0,
      "throttled_periods": 0,
      "throttled_time": 0
    }
  },
  "cpu_stats": {
    "cpu_usage": {
      "total_usage": 709001154,
      "percpu_usage": [
        428133113,
        31262531,
        45274798,
        204330712
      ],
      "usage_in_kernelmode": 50000000,
      "usage_in_usermode": 590000000
    },
    "system_cpu_usage": 185643040000000,
    "throttling_data": {
      "periods": 0,
      "throttled_periods": 0,
      "throttled_time": 0
    }
  },
  "memory_stats": {
    "usage": 51126272,
    "max_usage": 60538880,
    "stats": {
      "active_anon": 30945280,
      "active_file": 1474560,
      "cache": 19976192,
      "dirty": 0,
      "hierarchical_memory_limit": 9223372036854771712,
      "hierarchical_memsw_limit": 9223372036854771712,
      "inactive_anon": 36864,
      "inactive_file": 18386944,
      "mapped_file": 15933440,
      "pgfault": 12593,
      "pgmajfault": 153,
      "pgpgin": 16899,
      "pgpgout": 6530,
      "rss": 30867456,
      "rss_huge": 4194304,
      "swap": 0,
      "total_active_anon": 30945280,
      "total_active_file": 1474560,
      "total_cache": 19976192,
      "total_dirty": 0,
      "total_inactive_anon": 36864,
      "total_inactive_file": 18386944,
      "total_mapped_file": 15933440,
      "total_pgfault": 12593,
      "total_pgmajfault": 153,
      "total_pgpgin": 16899,
      "total_pgpgout": 6530,
      "total_rss": 30867456,
      "total_rss_huge": 4194304,
      "total_swap": 0,
      "total_unevictable": 0,
      "total_writeback": 0,
      "unevictable": 0,
      "writeback": 0
    },
    "failcnt": 0,
    "limit": 2097557504
  },
  "blkio_stats": {
    "io_service_bytes_recursive": [
      {
        "major": 254,
        "minor": 0,
        "op": "Read",
        "value": 19857408
      },
      {
        "major": 254,
        "minor": 0,
        "op": "Write",
        "value": 0
      },
      {
        "major": 254,
        "minor": 0,
        "op": "Sync",
        "value": 0
      },
      {
        "major": 254,
        "minor": 0,
        "op": "Async",
        "value": 19857408
      },
      {
        "major": 254,
        "minor": 0,
        "op": "Total",
        "value": 19857408
      }
    ],
    "io_serviced_recursive": [
      {
        "major": 254,
        "minor": 0,
        "op": "Read",
        "value": 559
      },
      {
        "major": 254,
        "minor": 0,
        "op": "Write",
        "value": 0
      },
      {
        "major": 254,
        "minor": 0,
        "op": "Sync",
        "value": 0
      },
      {
        "major": 254,
        "minor": 0,
        "op": "Async",
        "value": 559
      },
      {
        "major": 254,
        "minor": 0,
        "op": "Total",
        "value": 559
      }
    ],
    "io_queue_recursive": [
      
    ],
    "io_service_time_recursive": [
      
    ],
    "io_wait_time_recursive": [
      
    ],
    "io_merged_recursive": [
      
    ],
    "io_time_recursive": [
      
    ],
    "sectors_recursive": [
      
    ]
  },
  "pids_stats": {
    "current": 9
  },
  "networks": {
    "eth0": {
      "rx_bytes": 117457,
      "rx_packets": 393,
      "rx_errors": 0,
      "rx_dropped": 0,
      "tx_bytes": 76077,
      "tx_packets": 261,
      "tx_errors": 0,
      "tx_dropped": 0
    }
  }
}

參考鏈結

[TIL] 搞清楚三種 Docker SWarm 的差異

原文

Comparing Swarm, Swarmkit and Swarm Mode

名詞解釋:

  • Docker Swarm: 最原始的 Docker Swarm 需要透過 docker --swarm 來呼叫
  • Docker SwarmKit: 使用 Github 另外一個 Open Source Project docker/SwarmKit 做 Clustering orchestration.
  • Docker SwarmNext: 也就是 Docker 1.12 之後系統內建的 Docker Swarm Mode (或稱為 Docker Swarm V2)

TL;DR (直接告訴我差異)

  Docker Swarm Swarm Kit Swarm Next (Swarm V2)
額外 K/V DB 需要 (progrium/consul) 內建 內建
Security None 內建 內建
額外安裝 不需要 需要額外安裝 binaries 不需要
Extra Service None Noone Routing Mesh, Load Balancer, Service Discovery
Docker-Compose, Docker-Machine 支援 支援 支援 不支援 (目前)

關於最原始的 Docker Swarm

建立 Key-Value Service

#Create Docker Machine
docker-machine create -d virtualbox mh-keystore

#Switch to taret docker-machine
eval "$(docker-machine env mh-keystore)"

#Start Consul Service
docker run -d \
    -p "8500:8500" \
    -h "consul" \
    progrium/consul -server -bootstrap

關於 SwarmKit 使用流程

請參考我的這篇文章,[TIL][Docker] Docker SwarmKit 學習紀錄

關於 Docker Swarm Next

請參考我的這篇文章,[TIL] Learning note about Docker Swarm Mode

參考鏈結

[TIL] Docker Live Restore: Docker 1.12 讓人驚艷的新功能

What's New in Docker 1.12 by Nishant Totla for Docker SF Meetup 08.03.16 from Docker, Inc.

Docker 官方在 1.12 正式 Release 之後也放出了新的 Slide 來講解 1.12 新的功能:

Docker Swarm Mode 無疑是最大的亮點,裡面的Routing Mesh可以讓任何節點都可以找到有 deploy 的 service

除此之外 Live Restore: (p.30) 這大概是 DockerCon 2016 之後新的功能,今天看到同事 Demo 後覺得相當有趣. 只要你在啟動 daemon 的時候加上 –live-restore 的參數.

Docker Daemon 啟動的 Container 就可以把 Docker Daemon 殺掉,但是可以確保自己不會一併消失.

這樣就可以來 Container 來更新 Docker Daemon