MR SHIH

必幸施

微服務架構Container篇,幫助業務面對未知挑戰

| Comments

2018-04-29-docker-container-design-principle.jpg

業務應用系統為什麼要導入新架構微服務與Container?這些技術具備怎樣特性去解決以往哪些較難克服的情境問題?而當我們在設計一個Container時又有什麼原則我們該考慮才能真的解決上述的情境問題呢?我們可以先把一個Container想像成機械公敵裡面的單一機器人來理解:

啟動簡單迅速、消耗品、Scalable

  • 需要時可以立即啟動
  • 消耗品,壞掉了也無所謂,丟掉再啟動一個新的就是了
  • 一個不夠就派兩個,可以依此類推透過無限增加數量來完成任務

而微服務架構Container設計原則的另一端就可以想像成是環太平洋裡面的巨型機器人:

  • 啟動的前置時間很長,作業繁複危險,需要有專門的維運團隊負責
  • 每個機器人都是傾全國力量打造,數量稀少,壞掉一個就有大麻煩了
  • 一個不夠後面也沒有幾個能支援了,一但遇到之前沒遇過的新強度容易全軍覆沒,打掉重練

IT容易因應業務的快速變化與多樣需求

以上幾點,最重要的就在於沒遇過的挑戰。現在的業務應用發展非常迅速,變化的幅度也相當大,面臨的挑戰多樣化,有的可能是流量上的挑戰,有的是服務介面或流程上的多樣性調整或其他各式各樣不同應用情境下面臨的新挑戰。

而微服務架構下的Container最大優點即是容易因應變化。引用反脆弱這本書的想法來解釋,未來的變化越來越不可預測,而因為事前的預測不可行,所以避免被未知變化打敗的策略不是變得更堅強(ex:造巨型機器人),而是變得可以因應變化(ex:透過各種容易打造,靈活改變與量產的微型機器人)

以Netflix全球線上影音播放龍頭來說,它們每日面臨的流量變化是無法預估的,服務遍及全球,所以哪個地方的網路突然不穩定也是不可預測的,但只要透過微服務架構,流量一大即可透過立即增加微服務數量來彈性因應,服務預期外下線只要讓其他服務Fail-over接手即可。

引用到金融業,為來可能與APP業者合作推出行銷方案,因活動所帶來流量的不確定性與方案的多樣性就很適合用微服務架構來因應。

所以今天不管海底冒出什麼變種怪物,都可以透過靈活快速改變迭代微型機器人的功能與增加數量來對付。

技術實作要與微服務基礎架構配合

在談實作之前要先釐清,Contaienr本身不能夠決定自己容不容易快速啟動、是否具備消耗品特性、與scalable,要具備以上能力不僅Container設計時要考慮,更重要的前期階段整個微服務基礎設施架構設計上就要考慮進去。也就是說如果沒有一個良好在背後運籌帷幄自動調配的為微服務基礎設施架構,Container是沒有辦法發揮1+1>=2的效果。

打個簡單比方,前方戰線吃緊但後方的大本營卻狀況外,遲遲不開啟新機器人出去應戰那也是沒有用的。

Container生命週期

典型的Container設計對外是透過RestAPI來提供服務,所以內部是一個Web Service,其中包含了必要的業務邏輯,啟動後會有systemd自動把服務帶起並運作,啟動後Container加入Service Discovery就可以開始處理業務請求了。

整個啟動時間以Tomcat應用來說是可以在1秒內啟動完成。而一但這個Container不再需要即可透過微服務基礎設施進行刪除來結束生命週期。

檢康檢查機制

每個Container都要盡可能避免自己出現Fatal Error,也就是會出現導致服務中斷不回應的例外錯誤。systemd在這裡可以發揮適當的進程守護機制,如監控Tomcat健康狀態如發現進程掛掉自動重啟等。

而微服務基礎設施也有責任透過協調好的Health Check API或Ping去發現回應不如預期的Container,並作出適當回應機制如Fail-Over。畢竟不能夠相信有 100%1不會掛掉的Container存在。

錯誤復原與Root Cause分析

一但發生錯誤,第一時間的錯誤復原很簡單可讓基礎設施透過Docker特性,重啟整個Container來達到恢復狀態。但這個事件必須要被Log給記錄下來。包含呼叫的Container與Image版本、呼叫的AP、時間、帶入的參數等等。在事後才能透過以上資訊來找出Root Cause並升級Container Image來防止再次發生。

Image版本控管

Contaienr通常是會不斷迭代的

  • 基礎設施升級並提供新功能,Container配合升級以提供新功能
  • Container bug fix 或 feature add

因為不同類型的Container常會以功能劃分並模組化管理,而隨著不斷迭代,基礎設施與Image版本也幾乎必定會有向下相容的議題產生,特定版本的基礎設施要搭配特定幾版以上的Image。所以長期來看版本控制就特別重要。所以導入Git與做好文件是系統能不能長期穩定提供服務與發展的重要關鍵。

而如果基礎設施版本與Image版本之間有Dependence的關係一定要特別註明。

資料保存

Container能夠快速重起的特性帶來一個重要議題:重啟後Container內的資料是會不見的。所以如果Container內的資料是很重要的,如資料庫檔案等請參考Docker Volume把重要的資料掛載一個鏡像在Host。這樣一但程式有問題,重啟後資料還在,才可以繼續維持服務。

這部分典型應用如把MySQL做成Container,這時候MySQL版本進行升級只要替換Image版本,就可以在資料保存不丟失的狀態下升級MySQL。

結論

一開始從談論導入微服務架構與Container對業務的好處是什麼開始,因為IT能夠長期有效並從容迅速的去解決未來可能面臨的各種業務需求問題,才能最大化IT價值。接著從此架構的特性來談為甚麼能解決上述問題,最後再跑過一次整個細部技術實作上會遇到的議題。

實務上除了微服務基礎設施一定要自己全部掌握與了解,其實就Container單一服務只要考慮好:

  • 把API接口input/output定義
  • performance與壓力測試要求
  • 啟動時間
  • scale的方式是否能跟微服務設施搭配
  • 錯誤處理機制
  • 文件撰寫規範
  • 版本控制

上述幾點考慮好其實就單個特定需求的Container服務來說是可以透過外包的方式來實作也沒有問題的。

可以發現的是Container設計起來相對於微服務基礎設施簡單,需要考慮的議題除了版本控管與Scale之外都偏向於單點技術的實作。而這也是符合避免打造一台巨型機器人的原則。

附錄

附錄裡介紹Netflix在全球有上萬Container去服務數百萬觀眾,而這只需要10多個維運工程師,令人印象深刻。

技术顶牛的公司为啥没有CTO?

微服務架構Service Discovery篇

| Comments

2018-04-21-service-discovery

想像一下來到一個陌生國度,你既沒有地圖也不會說當地語言,你不知道要買生活用品要去哪家店,你也不知道餓了哪裡有餐廳可以吃飯,什麼事情也不能做。

沒錯,一個沒有Service Discovery機制的微服務架構就如上面的情境,什麼事情都做不了,可以說Service Discovery機制是談微服務架構必備的基礎設施也不為過。

為什麼要Service Discovery?

簡而言之,一個微服務架構底下可能有數十到數萬個微服務,彼此之間是解耦合的,不會留存各自的組態資訊,所以需要一個熟門熟路的總機,要找誰、需要什麼問它就對了。

它要解決以下情境:

  1. 一個服務請求(如HTTP Post)進來
    1. 有沒有微服務可以支援這個請求?
    2. 有的話,只有一個嗎?如果有多個我要請誰來執行呢?
  2. 一個微服務上線
    1. 我該如何讓別人知道我這個微服務能做什麼?
    2. 如果微服務不正常或下線了,要怎麼讓別人知道?

如何解決情境問題?

而為了以上情境問題,一個Service Discovery透過實現以下兩個邏輯層來解決問題

Query

維護一份可用服務的清單。可以想像成一個數位電話簿,可以回答這件事情現在誰可以做。

不過這裡先留個伏筆,注意剛剛提到的兩個字眼維護現在。這兩個字眼代表現在的清單需要知道當下所有微服務的狀態,有沒有服務其實已經掛掉了?這部分是由另一個邏輯層Registry負責提供接口,等等會提到。

Query這裡具體實現可以用資料庫的方式來實現清單的保存。一般來說單一MySQL就已足夠應付數千同時查詢請求,透過實體橫向 Read Scale來擴展。如再進一步有效能方面要求,可引入Cache機制,但狀態一致性就會增加空窗時間,這時候就是與業務需求之間的Trade off了。

而如果有多個微服務可提供要Pass給哪一個呢?簡單做法就是Round-robin,所以Service Discovery也會有Load balance角色存在。

Registry

這裏就是用來維護當前裝態了。大致上會有Registry與Unregistry。

Registry,以Docker實現的微服務來說,就是紀錄Container IP與 ID等資訊。還有這個Container能夠提供那些接口API Path可使用。

Unregistry則就是把這個服務標示為無效,讓查詢時不要把這個Service也列入可用名單內做挑選。

誰像誰註冊(Registry)?

而實際在實現註冊功能時會遇到一個問題,是Service Discovery主動對新服務做註冊,還是新服務來主動對Sercice Discovery做註冊。

Service Discovery主動對新服務做註冊有以下優點

  1. 讓Container對Service的存在一無所知,解偶。
  2. 服務只當被動元件。只需要專心對Request產生Response即可。

但缺點就是

  1. Service Discovery負擔已經繁重,還需要做掉其實可以由Container來負責的主動註冊這個動作。
  2. 因為每個Container啟動有快有慢,但Container需要等待統一秒數才能被註冊,比如7秒。這也意味著不能有低於7秒的,而對Container做啟動優化低於7秒也沒有任何意義。所以關於啟動時間會有7秒的限制,而一般來說啟動一個Container掛載一個普通Tomcat提供服務,整個時間是可以壓到1秒左右的。

而新服務來主動對Sercice Discovery做註冊的優缺點,把上面反過來看就是了。兩個比較起來,新服務來主動對Sercice Discovery做註冊以長期來看則會是一個較好管理彈性也較高的做法。

如何知道服務狀態是否正常?

這裡大致上分主動與被動做法:

主動作法如既然已經有一份清單,就可以定期對每個服務發送健康狀態檢查的請求,粗略的可以是Ping,而如果對於Container掌控度較大,則可以協調出一個專門的API接口來進行狀態檢查。

被動做法則是當選出一個服務並對其呼叫時,如果沒有回應則標示此服務為下線並報修,同時在從其餘可用服務中挑一個出來呼叫,依此類推一直到沒有服務可用為止。

兩種做法各有優缺點。主動做法來說,Service-Discovery責任已經很重,再加上要定期對眾多微服務做定期檢查責任已顯吃重,如要採用主動方式,建議切出一個獨立邏輯的服務運行。主動式的優點當然就是發現故障服務的時間會迅速許多,尤其當微服務增多時更明顯,不會有服務已經掛掉卻躲在那裡的情況產生。

兩種方式宏觀上來說,被動是可用的方案,而主動則算是好還可以再更好的方案。長期而言應在架構上選擇主動方式,而被動可應用在初期應用系統或規模較小微服務數量低於100的自建系統。

Server-side Discover與Clint-side Discovery

Service Discovery這個主題其實還有分Server-side Discover(下面簡稱ssd)y與Clint-side Discovery(下面簡稱csd)。不過絕大多數方案如k8s都採行ssd作法,而我認為csd只是做了一半的ssd,實在也沒有什麼非用不可的應用情境,所以就沒多做介紹,想了解可參考附錄。

結論

只要談到微服務架構就必定會談到Service Discovery,這算是整個架構的核心基礎設施了,在上面幾個Section大致上把幾個實作時需考慮的架構問題談過一輪,看下來會發現在註冊Registry那一塊,Service與微服務不管採行什麼做法都是需要有幾個共同溝通的API來合作,如服務可呼叫的API Path與健康狀態檢查API,所以需要考慮兩者之間溝通的標準Protocol如何制定與導入,長期來看可能還有向下兼容的議題,而對外查詢方面則須考慮效能需求來決定服務清單儲存方式,而上面所說也全都要建立在業務需求上來做最後設計決策。而業務需求會一直變,架構上也就會一直演進。

所以全面了解Service Discovery的眉角可以才能依據業務需求設計架構,讓微服務系統達到容易使用維護與擴充升級的架構目標,最後更好的去支持業務面的需求。

附錄

安德魯的部落格-微服務基礎建設 – Service Discovery

Day 4 Service discovery 和 Service registry

模式: 客户端服务发现

專案談判與協商

| Comments

2017-12-18-project-negotiate

錨定對方,立於不敗而後求勝

談判的目標即是達成合作,要達成合作就必須雙方都同意接受,這時候如議價即是找出雙方對某物價格的交集區間,也就是ZOPA(Zone of Possible Agreement)

比如合約議價這件事,甲方預算上限如果是100萬,乙方最低賣價為80萬,則議價上ZOPA即為80~100萬,乙方要盡可能逼近100萬合約價,甲方則是能盡可能逼近80萬合約價。

這邊有一種策略叫做錨定:人在估計數值時,容易將他人提供的數據當作起始值來進行推測,也就是身為乙方,一開始可以開出自己底價的150%,來讓雙方的起始談判價從120開始談起,爭取40萬的緩衝空間給對方殺價。同樣策略甲方也可以開出低於自己預算的50%從50開始出價,來讓整個談判起始點從50萬開始談。

如何避免被錨定

一但錨定對方成功,就是所謂的立於不敗而後求勝了,因為無論怎麼退,你都是贏的,贏多贏少的問題。但當然人在江湖飄哪有不挨刀,有一天你被錨定了?其實要找出對應方法,從另一個角度看問題答案就呼之欲出了:你為什麼會被錨定?不外乎以下幾點:

  1. 對於市場行情不熟悉,你可以google,也可以問
  2. 沒有備案(BATNA),所以不知道底線如何定,什麼時候就不繼續buy-in,所以有備案就有底氣

課堂Case2的檢討

  1. 一開始就要錨定對方,喊出一個很低的天數。
  2. 緩衝一開始就要抓多一點。立即要爭取20%~30%的緩衝天數。
  3. 準備備案。心裏預定最壞狀況找外包,先拿到外包預估的天數當底線(Reservation Price)。
  4. 發現Target沒有交集,要用其他資源去交換,而非在我方關鍵資源上退讓。如用加班費與獎金去換取與R&D沒有交集的天數降低。

發現Target沒有交集ZOPA,要用其他資源去交換,突破僵局

這裡就是說當對同一個議題沒有交集ZOPA時,比如錢與天數,嘗試引入其他資源進入這個局,來突破僵局。比如議價上有可能對方的底價跟你的預算真的沒有交集,那是不是嘗試用保固或者產品特色公司特色,未來折扣等方式來讓交易能談成。

這裡則又帶入了一個新議題,我該如何帶入正確的外部資源?這可以靠事前做功課,也可以透過對對方提案來遲是了解。比如工程師說期限內無法完成,但假設工程師缺錢,那很有可能可以為了錢來替你加班趕工縮短工期,那這時候加班費與專案獎金就是可以拿來交換工期的其他資源。

工作價值衡量

| Comments

2017-12-12-work-performance.markdown

年終又到了,過去一年你是如何評價自己的工作產出?

今天你是一位專案經理,你在一場同業聚會上自我介紹上說:『我平時會協助客戶進行需求評估,給予專業之專案規劃說明書,並且跨部門溝通協調專案在時間內完成』。ok,這樣乍聽之下沒有問題,但盲點在於如果這時你的另一位同業說:『我今手的專案總金額達3000萬以上,客戶皆為台灣知名銀行,並且都能提前交件,節省成本達10%,其中60%為人力成本。處理過10個專案,並且都成功如期結案』。如果你是老闆你要用那一位呢?

第一位只是敘述了他的職位說明,任何一位差不多年資的專案經理,工作內容應該都是差不多的,大家都做了差不多的事,你有什麼不同?而第二位則把重點擺在具體的亮點與實際的貢獻,比如知名公司、專案規模大小與總結案金額等。Let me put it in this way,讓對方自動從你做過的豐功偉業中去得出你有能力且很專業的結論。

這讓我們學到什麼呢?平時工作上要一直問自己,我正在做的事的實際貢獻是什麼?成果、績效 、里程碑。對業務來說就是你的業績與合約金額、成交數與客戶數等。對技術來說就是你的專案規模、複雜度與金額。這些都是可以用數字很明確的衡量出得價值。

定期的去把這些事情記錄下來,比如負責某專案,其時間、金額與你在這個專案中貢獻等。能數字化就數字化。如果你整理不出來呢?那就要好好檢視一下自己是否能去主動爭取相關機會,如爭取有實際可量化貢獻或成就的事情來做。

又到了實際行動的時間,從現在開始定期盤點自己的職涯成就吧,2 month basis。格式就如以下,一筆一筆的記錄下來:

  • 期間:2017-5 ~ 2017-10
  • 公司/職位/專案:xx科技/專案經理/xx銀行xx案
  • tag
  • 成就/貢獻/產出:
    • 帶領2位工程師以及1業務人員完成專案,金額400萬
    • 戰略專案,幫助公司獲得該銀行資安主要系統地位
    • 成功複製沿用產品,達到資源重複使用,利潤提高50%
    • 幫助公司排除競爭者,繼續獨家提供設備給予廠商

職場做好事情的判斷力

| Comments

判斷力的缺乏

公司現在正在進行產業升級,要從硬體跨足軟體平台,老闆很重視軟體,認為是未來提升營收的成長動能,也是公司在市場攻城掠地擴大市佔率的重要戰略工具,但合作的同事或底下的部署尚不清楚公司目標,把軟體研發的工作視為‘額外’的工作,認為原本硬體工作做好就好,學習軟體的部分是多餘的,為什麼我要學?

但是硬體部份其實賣出去剩下都是維護,在老闆眼中只是例行性工作,就算出狀況要聯絡原廠也只算是緩衝工作,把大部分時間挪去聯絡原廠解決問題,然後覺得自己不被重視(可能硬體維護的錢公司常常公開說很重視,導致認為此事在老闆眼中很重要,但老闆只在意業務有沒有談高維護合約的錢而已,技術部你處理維護好只是領薪水份內的事)。

應用

上了課之後,學會以後跟部署說明工作有分緩衝工作跟核心工作,不要只是把時間都拿去處理緩衝工作,高風險低報酬,然後覺得自己明明努力在做維護,公司還虧待自己。

老闆常常說維護很重要,是指維護的錢老闆覺得很重要,所以在業務部那是核心工作或根本是形象工作,在技術部,維護偏向緩衝工作。

所以大家要把時間跟精力,放在研發新軟體上,這樣老闆對你的態度自然會變,會重視你。薪水 職位 尊重那些自然會來。

對局的不認識

自己之前常常搞不懂老闆一直逼我們pre-sales出去簡報的時候,為什麼要積極的去換名片?不就簡報完叫業務去問有沒有興趣就好了,真的出問題再找業務去聯絡技術窗口,接著我們再來接手。我們技術人員就還是趕快簡報完回去開發程式比較重要。

應用

跟我有同樣想法的技術人員幾乎是全部,都覺得跟客戶換名片沒什麼意義。但上了這次課之後搭配以前的情境恍然大悟,也知道以後怎麼跟同事講換名片(搞懂title, 搞懂對方在這個案子力扮演的角色)的重要性了。

就技術面來說,產品賣出去真的出問題,第一時間要是可以找到working-level的人,那就能很快地了解狀況。說不定對方還能幫我們現場做一些除錯,問題就直接解決了。

業務面來說,而我們pre-sales成案也是有獎金,如果我能搞懂可能那些人是真正要使用的人(常常業務對口只是負責採購設備的單位),並與他建立關係,會後直接附上更多參考訊息,並且看對方的回饋態度,其實有沒有機會成案搞不好很容易就觀察出來,不用事後還白忙很多場,甚至因為主動聯絡真正要使用的人,成案的機會都會提升。

以後我就完全知道出去換名片的意義,因為能對整個局更加了解,找出真正重要的關係人!以後部署出去做pre-sales也才好說服他們換名片,知道出去簡報重點在哪裡,搜集問題,搜集人的資訊,搞懂局!

我也可以分享給老闆怎麼讓底下的人了解交換名片認識人的重要性,這樣他們才會實際去做!

對上位者需求的不理解

常常老闆會莫名其妙跑出不可行的idea,我都會直接說為什麼不可能,雖然老闆事後會理解不可行(應該吧…因為沒再提了),但當下都會有一些爭論。

應用

了解應該去滿足老闆有效掌控的慾望後就知道,先思考老闆背後動機是什麼,比如業績提升(感覺是TOC核心目標),他心裡面想被滿足什麼,產品支援度提升,自己得意見被思考(感覺是TOC內心需求),然後第一時間不急著反駁老闆的對外訴求,表示對於大方向,比如支援度提升認同,然後再說我們會去研究老闆的對外訴求。

上完課後第一個工作日老闆來跟我產品應該增加A功能,我就學乖了,先說『沒錯,應該要提升對於這個功能的支援度,這樣才有辦法做xxx,我們會去研究看看A功能整合上有沒有問題』,當下老闆就沒有再打斷我們工作了。事後我們再提其他解法就可以了(如果老闆還記得…),畢竟滿足內心需求有很多種做法!

心中沒有指南針,浪來會亂飄

自己對於工作與產出是個很有責任感的人,對於專案的輕重緩急因為有上過專案管理啟蒙也有判斷力,公司業務都很喜歡與我合作。但有時日常生活的消耗時間,專案或技術或市場推行碰到阻力,一陣子沒有進展,或是不明原因,有時會有種好像不小心庸庸碌碌不知道自己在幹嘛的感覺。

應用

像今天在猶豫要不要跟大家出去買飯吃,平常大家會揪但我心裡是不太想的,中午時間喜歡快速解決,然後繼續工作。但今天轉念想到老師上課三不五時就會指的『你想從工作中獲的什麼』的那面牆,馬上就覺得我有我的理想與目標,不是來這裡交朋友,而是在工作上能與人愉快的合作建立自己得專業品牌才是我要的,這時候心裡立刻就不猶豫,自己去買飯火速解決。

以後又有不知道自己在幹嘛的感覺時,就會提醒自己那三個目標,幫我做出較為正確的選擇。真的很實用。莫忘初衷。

結尾:不只雪中送炭,更錦上添花

還有很多的情境,但不算是問題,但依然可以應用課程的知識去做強化。比如對於客戶安全感的管理,之後定期主動的提供消息(明確計畫與專業態度),主動去管理他們的不安全感。並且之後比如產品如何上線等情境也都提供選項,一方面我們可以收斂想法,一方面可以滿足客戶的掌控慾。

至於適度地提供壞消息並隨後擺平之,我把它定義為先說這個功能很難,要花多功,但我們可以做到,之後再完成,讓客戶提升安心感與風險免疫能力。

關於日後練習

  • 同理心的練習:找到關注利益與主要憂慮,才能找對策(參考一般性通則與職場人際對策速查表)
  • 緩衝工作的判斷(比如客戶說不出明確時程,判定沒什麼成案機會是緩衝工作XD)
  • 練習看懂局:找出關鍵人物,模擬他要什麼(同理心練習),加入時間因子(上過專案管理啟蒙後覺得時間很重要,而且常常是最重要的),最後理出頭緒。
  • 人際關係計劃表:多跟有關的客戶窗口多聊天,在合作愉快得前提下,聊是否結婚,有沒有小孩,有沒有要出去旅行,有什麼興趣等等,只要記得客戶就會keep in mind。

最後謝謝姚老師Bryan把這麼抽象的知識概念系統化的傳授給我們!

『大人學英文』對我未來日常生活的影響

| Comments

2017-09-03-learn-speak-english

缺乏做法讓我知道如何改變

大家學了這麼久的英文,一定有個願望是可以說英文。第一份工作時我擅長看國外的技術文章,簡單英文書信往來也沒有問題,但我就是無法用嘴巴說。問題在於如果我們今天認識了火星人,我們想學學看怎麼說,最有效的方式應該就是去偷聽他們對話,並且去模仿他們如何說,但我們通常不那麼做。

要說這堂課對我的影響,很簡單。如果我現在要說英文,流程不再是想法->中文->翻譯->英文。慢慢的我有感覺到中間的過程不見了,變成是想法->英文。

我其實不把這門課定調為『英文課』,而是定義為如何改變自我日常行為,進而達成有效提升英說能力的日常習慣改造課程。

我認為學英文需要時間,也需要方法。但大部分的方法無法讓時間在學習說英文上成為朋友,這門課珍貴的地方在於有能力讓時間變成你學習英文的盟友,but,同時也需要耐心與毅力。

這就我最愛的部分,因為我很清楚知道,能夠與人拉大差距能讓人稱羨的事情,一定需要時間耐心和毅力。所以我知道我走在對的路上。

關於日後練習

  • 每日聽Podcast一小時,當背景音聽,有辦法分神時注意聽內容。並挑五分鐘跟著說。
  • 每日根據老師最常用100字去造句並說出來,並想像情境,讓自己講的有感覺。
  • 看Suits,學Mike講話,每天就一句,錄下來並與影集做比較,做到越來越像。自己給自己回饋。

最後謝謝Joy老師囉,也就是上面照片集美麗與智慧於一身的女神! 英文說得練習做到現在也邁入第三個月了,就如健身一樣,這需要時間,但方法對了堅持下去成果就很驚人, we will see.

怎麼用簡報有效傳達訊息與說服對方

| Comments

2017-08-12-make-a-good-presentation

這個月初因為朋友建議去上了孫治華老師的【SmartM 菁英商學院】成功提案!打造商務簡報說服力課程。上完課後火速改了簡報內容並去跟客戶簡報,真的發現客戶聽得異常專心,對於我要表達的重點也能夠真的抓住,實在是又驚又喜。在這裡把一些實戰後的心得記錄一下,以供自己與別人參考。

做簡報的第一步想的不是自己的產品有什麼優點,或自己產品的任何事情,而是想想看別人可能會問我們什麼問題?針對這些問題我們的產品有那些優點可以來解決對方的疑惑。

開場吸引力

第一階段重點在於要讓對方有興趣。而要讓對方有興趣你的簡報就要有吸引力,吸引力來自於讓對方感覺這個簡報真的跟我有關係。立即針對對方的痛點提出解法是一個好的開場。

想像兩個圓,分別是對方的問題,還有我們產品的優勢,中間交集的地方就是我們要讓對方一開始就清楚知道的。所以做簡報前先開一個會前會,業務與技術一起加入,主題就是猜想對方現階段遇到的前三大問題。並且針對這三個問題提出我們產品的對應解法。業務負責依照在客戶端搜集的情報來提供問題,技術負責共同提出可行的解法。

而在開場部分你所提出的解法,不要太囉唆,這裡解法著重在結果,也就是效益的部分WHAT。至於技術的細節比如你如何做到的HOW,在這裡先不要提。比如客戶擔心效能問題,就先展現出強大的壓測數據,至於你如何做到,開場這邊先不用提。

其實只要你有辦法一開始就說出對方心中大部分的疑慮,你就可以初步贏得對方的信任感,因為對方會覺得你懂我。

中場專業力

第一階段說了一大堆效益,開了一堆支票,那這時候一般人都會想真的嗎?

所以在這個階段你要證明你不是在唬爛。有可能你已經有實際上線成功案例可以拿來講,可能你有數據可以顯示,重點在於這個階段因為前面你說了太多的好,人性會不自覺懷疑,所以這裡需要透過幾頁來證明你有經驗有能力試做得到的。

再來就可以談談技術面的細節,比如你如何做到你前述的那些優點,這裡你可以依照自己的狀況,用自己的方式來讓對方瞭解,如果你有讓對方上了一課的感覺那更好,更能增加聽者對你的信任。這裡的難處會在於一般技術細節表達上會過於死板生硬,所以需要小組腦力激盪用流程圖、對比圖或是表格等讓聽者容易了解。

終場執行力

這時候依照對方的狀況加上時間以及做法,給對方一個藍圖去知道接下來要怎麼做。這裡如果是系統可以分批分階段汰換,如果是元件開發則可以列出從需求分析到驗收的時間表。

這裡重點在於讓對方理解你有執行這方面的經驗,可以依照他們的需求帶領他們。

換個順序說說服力道就不一樣

曾經聽過一個笑話

女大學生晚上會去酒店陪酒 →社會觀感不佳。酒店小姐白天堅持去大學聽課 →充滿正面能量好勵志!

當然上面這個笑話聽起來不一樣單純是因為語意關係,而簡報順序換個順序說服力道會不一樣是因為我們順著人被說服時的邏輯去編排簡報順序。嘗試依照吸引、專業、執行三個階段去簡報內容,更能夠抓到重點說服客戶達成簡報目標。而且依照問題導向去製作簡報,時間真的也短很多,也證明好的簡報不要花太多時間做,通常會花太多時間都是在空想。

Production系統的穩定機制

| Comments

2017-08-05-high-availability-production-environment-issu

要上線一個系統,或更新一個系統的版本,首先最重要的就是系統穩定度。有些系統比如在銀行,上線後出了問題都是非常緊急的,一但系統上線開放給別人來使用,背後需要考慮的完善,才不會上線之後一直在救火救不完。

底下從底層的Exception的機制、Log的紀錄方式、整體功能的完整性驗證、系統如何維持總是不死的狀態,到最後如果還是發生持續性錯誤如何處理,依序來談談資訊系統上到Production前,需要先考慮到的議題。

底層的Exception機制

最重要就是有錯誤產生就一定要在程式碼有catch到,並請定義好這個狀況搭配的錯誤代碼為何。有時會看到工程師在catch裡面不做任何事情,這是不被允許的,一旦出了問題大家都一頭霧水無法在第一時間了解狀況,影響到處理問題的黃金時間。而設計系統架構時就把錯誤回傳方式定義好,比如以下例子,後端程式只要判斷result為0,就可以知道有錯誤產生,並且讀取errorCode做相對應的處理。

1
2
3
4
{
    "result": 0,
    "errorCode": 13057
}

Log的紀錄方式

Log最終是要拿來分析的,不管是程式分析還是人眼分析,都需要一個清楚固定的格式,尤其是第一時間往往要靠人眼去分析,這時候Log寫的工整與完整,絕對有助於除錯。一個好的格式必定要包含時間When,是誰Who,發生了什麼事What,錯誤代碼或錯誤訊息。

整體功能的完整性驗證與壓力測試

上線或更版之前,必定要做兩件事,功能性驗證與壓力測試。功能性驗證我常用的做法是寫自動測試,把所有預期狀況都寫成一個case,上線前的版本都要掃過並驗證功能正常。再來壓力測試就是測試針對大量併發連線,大量持續呼叫,服務是不是依然回應正常。

維持總是不死的狀態

服務如果持續回應,但是回應一樣的錯誤怎麼辦?這時候系統要能判讀錯誤並自我修復,比如re-try機制,如果socket連線斷掉等等,系統要能夠自我偵測並且主動重新連線。另一種狀況則是如果系統遇到fatal error,要使用守護進程,讓作業系統保護這個程式,一但偵測到結束訊號,要主動重啟服務。

如果還是發生持續性錯誤如何處理

第一時間要通知維運人員,常見做法是發送Email,並包含足夠的錯誤訊息資訊,如果環境開放一點的可以串接Slack API。因為這個時候已經發生系統沒有考慮到的狀況,才會導致服務停擺。第一時間常是手動重啟系統,再來看Log找錯誤,加入開發排程,緊急的話開一個Hotfix branch出來,修正後把錯誤的狀況寫入文件中把狀況、原因、如何處理寫清楚,避免再次發生。

不斷的進化的過程

如何開發一套系統能在各種狀況下穩定的提供服務,是需要開發團隊透過敏捷開發方式加上完善的文檔與強烈的責任感共同來達成,不是一個容易的目標但一但達成是非常有價值的經驗也能提供很高的自我成就感。以上僅是列出部分議題,還有更多HA機制比如多台互為備援等,等待日後去實踐。

多人異步開發產品的基礎設施

| Comments

2017-07-22-tec-infrastructure

長期開發並維護一個產品跟短期衝刺生產出一個專案,最大的差別在於開發流程。負責小元件或小專案在開發上是同步進行的,而產品或大系統在開發上是異步進行的。開發元件可以用土法一路衝到最後,但開發系統沒有完善的基礎設施,案子很快就會出現許多問題導致開發窒礙難行。

如果以往是開發小系統,但突然有一天有機會接觸大系統的開發或規劃,沒有這些概念先Keep in mind,開發路上就會很辛苦了。

同步進行

小專案需求訪談後產生工作說明書然後簽字畫押好,只要規格寫的好範圍是可以被確定的,也不可以隨意亂改,改了可以再收錢。所以開發者一開始就能清楚界定專案的範圍,大部分未知的風險比如技術瓶頸可以被事先預知,開發時間可以被事先規劃。所以實務上從撰寫規格書界定專案範圍,再來實際開發最後到測試與驗收,流程上是以同步(sync)的方式進行。

異步進行

而大部分產品會給多個客戶使用那就會有多重意見和偏好,再來因為想做的功能多,甚至很多功能是要做但現在還沒辦法做,一開始也就是先畫出WBS圖來大略上界定範圍,很難一開始就寫好完整版規格書,界定所有API。而是隨著時間發展,常常是先寫好幾個客戶緊急需要的模組,然後就出貨給客戶,之後陸續再Release新版補給客戶其他沒有那麼緊急或重要的功能。而一但把時間因素拉長並考慮進去,開發上很多問題就會浮現了。

緊急事件

有緊急狀況發生比如出貨的產品臨時被要求在上線前要提供弱掃報告與修正,那這時後原先預定的下一個版號要新增的功能就要被置換成修正弱掃缺點。原本要被Merge回來的Feature支線就要暫緩,並且火速開一個Feature來修改弱點並發布成一個版本。

Feature要不要Release的抉擇

如果有很多新功能都接近完成,這時候要Release那些到下一版?通常第一個要考慮的是客戶的安心感。比如新功能要犧牲效能來換取穩定度,這時候要犧牲多少效能?這數字是客戶可以接受的嗎?客戶搞不好寧願犧牲穩定度來換取效能?如果客戶有多個有的可以有的不行呢?

上述沒有考慮到就貿然Release出去,如果驚嚇到客戶,讓客戶對我們信心感和安全感下降這都是很嚴重的損失。

本版間的關係管理

隨著時間迭代,A客戶是0.8版,B客戶是0.9版,這時候怎麼從0.8升級到0.9?兩個版本之間又有什麼差別?如果是好幾10個版本分散在各地有辦法處理嗎?如果沒有搭配文件、程式碼版本控管、環境印象檔化,不用多久整個案子就會無法維護。

文件記錄各版本的Release note,並且要有規範,標明新功能和已知問題等。版本控管Git要有Git Flow如Release branch在程式標明版本號,和Tag標註方便切換不同版本。運用Docker把運行環境標準化Infrastructure as Code,除了確保開發時與上線的反應相同,也避免環境升版降版時遺漏了設定造成的錯誤。

眾多協同開發會遇到的協作工具

Product version control document、Git、Auto test、CI Server、Project Management Know How(WBS etc…)、Document Guideline、Issue tracking等,以上這些就像是現代產品開發所必備的基礎設施,少了這些要開發大型系統或隨著時間迭代成長的產品是不可能的事情,沒有這些整個技術Team無法持續成長,也會欠下一堆技術債,累積到最後整個產品開發寸步難行,而對風險的忍受度也會異常的低,比如一個關鍵開發人員走了整個產品開發就無以為繼了。

從開發元件與小APP到現在開發產品,遇到的問題很多已經不是單一技術面,更多是如何管理這堆技術生老病死的問題,僅記錄一些最近遇到的實際問題與想法。

Letsencrypt在nginx與centos環境下實作tips

| Comments

基本上我認為現在HTTPS的功用只是用來加密連線,在CA亂發或誤發的時代,不能指望CA這樣的盈利民間機構能盡責的做到驗證申請者的角色。 但然而能做到加密Server與Clint之間的通訊內容其實也就已經足夠了。

與其繳錢給盈利CA,現在你有更好的選擇-letsencrypt,免費開源自動化更新的CA。

網路上的教學文章不少,而我這邊整理幾個好用的tip,主旨在於自動化與降低維運的難度。

Step0. CentOS+Nginx

因為自己的Server是用這樣的環境,加上這個環境也非常普遍可靠穩定,所以本文章就以這個環境當做基底。

Step1. Nginx強制指定/.well-known/acme-challenge/檔案路徑

1
2
3
4
5
6
7
8
9
10
/etc/nginx/nginx.conf

server {
  listen       80;
  
  location ^~ /.well-known/acme-challenge/ {
      default_type    "text/plain";
      root    /var/www/letsencrypt;
  }
}

你必須向letsencrypt證明DNS指向的這台server是你host的,等等letsencrypt會去你domain下的/.well-known/acme-challenge/path查找文件,如果找得到就能證明是你host,也才能簽發證書給你。

而這裡統一指向/var/www/letsencrypt是因為有可能你現在用單純的html環境,有可能之後換成proxy_pass反向代理到node.js等,這都會使得/.well-known/acme-challenge/這個url路徑指向的檔案在你host的server上產生變動,這種業務上變動跟HTTPS是無關且可以切開來降低兩邊的耦合度,而隨著日後的domain變多,統一指定路徑這樣的做法也能夠降低後續維運的難度。

Step2. 申請憑證

去下載官方的驗證tool certbot並安裝,下面例子自行把abc代換成你的domain

1
certbot certonly --webroot -w /var/www/letsencrypt/ -d abc.com.tw -d www.abc.com.tw

成功的話會出現包含Congratulations!一大段話,憑證會被存在/etc/letsencrypt/live/abc下

Step3. 安裝憑證到Nginx

/etc/nginx/conf.d/abc.conf

1
2
3
4
5
listen       443 ssl;
server_name  www.abc.com.tw;

ssl_certificate      /etc/letsencrypt/live/abc/fullchain.pem;
ssl_certificate_key  /etc/letsencrypt/live/abc/privkey.pem;

Step4. 強制導流HTTP連線到HTTPS

/etc/nginx/nginx.conf

1
2
3
4
5
server {
  listen 80;
  server_name _;
  return 301 https://$host$request_uri;
}

Step5. 把更新任務加入crontab自動化更新憑證

以下為更新腳本,我是命名為renewCerts.sh,並存放在/etc/letsencrypt/下

1
2
3
4
5
6
7
8
9
#!/bin/sh
# This script renews all the Let's Encrypt certificates with a validity < 30 days

if ! /usr/bin/certbot renew > /var/log/letsencrypt/renew.log 2>&1 ; then
    echo Automated renewal failed:
    cat /var/log/letsencrypt/renew.log
    exit 1
fi
nginx -t && nginx -s reload

Step6. 把sh加入crobtab

打開crontab設定檔

1
sudo crontab -e

加入sh設定每日自動執行然後儲存

1
@daily sh /etc/letsencrypt/renewCerts.sh