­

OpenFaaS實戰之五:大話watchdog

歡迎訪問我的GitHub

//github.com/zq2599/blog_demos

內容:所有原創文章分類匯總及配套源碼,涉及Java、Docker、Kubernetes、DevOPS等;

OpenFaaS實戰系列文章鏈接

  1. 部署
  2. 函數入門
  3. Java函數
  4. 模板操作(template)
  5. 大話watchdog
  6. of-watchdog(為性能而生)
  7. java11模板解析
  8. OpenFaaS實戰之八:自製模板(maven+jdk8)
  9. OpenFaaS實戰之九:終篇,自製模板(springboot+maven+jdk8)

本篇概覽

  • 作為《OpenFaaS實戰》系列的第五篇,咱們需要一起面對OpenFaaS的關鍵技術:Watchdog,不了解它後面就沒法繼續了;
  • 標題為大話watchdog說明本文以理論為主,這也是作者的弱項,但我會努力把關鍵點說得簡潔明白,如果您發現問題請務必及時指出,謝謝!
  • 整篇文章由以下段落構成:
  1. 從faas-netes談起
  2. OpenFaaS的資源
  3. watchdog分析
  4. 小結
  5. java程式設計師的擔憂

接下來一同開啟這段旅程吧,OpenFaaS開發之路上最重要的一站!

從faas-netes談起

  1. 先看Kubernetes下OpenFaaS的整體架構,如下圖,外部請求由Gateway轉發到faas-netes組件:

在這裡插入圖片描述
2. 再來看官方描述,如下圖紅框,在K8S環境,faas-netes就是服務提供者,它提供的服務支援REST API、客戶端、WEB等多種對接方式,另外,還可以用kubectl命令對其進行管理,實現K8S的operator模式(關於K8S的operator,可以先學習Controller,再想像著高度訂製CDR和Controller就可以了):

在這裡插入圖片描述

  1. 雖然faas-netes很強大,但是在本文咱們只要關注一點:faas-netes提供了函數服務,也就是說,咱們前面寫過的python、java的Hello world函數,都和faas-netes有關;
  2. 說了一大堆,主角watchdog還不出來?再等等,因為此刻大家都有同樣的疑問:我不就是寫了個python腳本嗎,裡面只有個Hello world方法,怎麼就成了faas-netes對外提供的函數了呢?
  3. 對上面的疑問,官方內部架構圖應該是最合理的答案,如下圖,API Gateway的請求會到達faas-provider的8080埠,如果是調用已經發布的函數,就在左上角的紅框內處理,如果是對資源的增刪改查,就交給右下角的綠框處理:

在這裡插入圖片描述

OpenFaaS的資源

剛才提到了上圖右下角的綠框,其責任是處理資源,這不是本文的重點,但作者好歹算是Kubernetes愛好者,覺得有必要科(xuan)普(yao)一下資源相關的知識點

  1. 在K8S中,Pod、Deployment、Service都是資源,也有對應的Controller根據etcd中保存的期望狀態來調節和控制這些資源;
  2. 對K8S環境的OpenFaaS來說,它也有自己定義的資源類型(第一篇《安裝》裡面提到過yaml文件夾,那裡面有個crd.yml文件,記錄了OpenFaaS的資源定義);
  3. OpenFaaS怎麼控制自己的資源呢?faas-netes提供CRUD介面給外面調用,而這些介面的內部實現,就是上面圖中你們看到的綠框了,顯然,經典的K8S Controller模式不能滿足OpenFaaS對資源控制的需求,於是就採用了目前流行的Operator模式:更複雜的資源定義、更複雜的資源控制邏輯
  4. 至於OpenFaaS的資源具體有哪些,那要詳細去看crd.yml文件,以及OpenFaaS Operator的程式碼了,不過上圖還是給我們指明了方向:Secret、Deployment、Service,想想也是如此,咱們把業務功能發布到OpenFaaS,最關注的不就是安全(Secret)、部署配置(Deployment)、對外暴露(Service)這些東西嘛;
  • 經過欣宸的一番梳(chui)理(niu),現在對faas-netes的了解是否更進一步了呢?函數的發布、後期的資源控制和調節,都是faas-netes的Operator在負責,接下來是不是該回到正題了:函數調用
  • 主角watchdog已經哭暈了吧…

watchdog分析

  • 還是前面那幅圖,咱們聚焦右上角那部分,我把它截出來如下圖所示:

在這裡插入圖片描述

  • 如果咱們用nodejs模板開發函數,寫了個index.js文件,那麼響應外部請求時會走到下圖紅框位置,進入Watchdog的8080埠,此時Watchdog會新建node進程,該進程執行index.js文件:

在這裡插入圖片描述

  • 上面說得不夠清楚么?那就再詳細一些,咱們開發函數時會做成docker鏡像,這個鏡像里有些啥?再來一副官方圖如下,真相大白:鏡像里有個Watchdog,監聽8080埠,收到請求後fork一個進程,通過stdin把請求參數傳給這個進程,進程調用咱們自己寫的函數方法,並且把參數傳給此方法,等方法執行完畢後,返回值通過stdout給到Watchdog

在這裡插入圖片描述

  • 現在,相信您在寫完一個函數後,對於外部請求如何調用到您寫的那段程式碼應該瞭然於胸,但是,依然有個小小的盲點:我知道了Watchdog能幹啥,但是Watchdog具體是個啥?咋就進了docker鏡像呢?
  • 上述問題,在模板的Dockerfile文件中可以找到答案(Dockerfile是製作docker鏡像的腳本文件),咱們打開node模板的Dockerfile看看;
  • 如下,一開始就從基礎鏡像openfaas/classic-watchdog:0.18.18里把文件fwatchdog複製過來了:
FROM --platform=${TARGETPLATFORM:-linux/amd64} openfaas/classic-watchdog:0.18.18 as watchdog
FROM --platform=${TARGETPLATFORM:-linux/amd64} node:12.13.0-alpine as ship

COPY --from=watchdog /fwatchdog /usr/bin/fwatchdog
RUN chmod +x /usr/bin/fwatchdog
  • 這個Dockerfile的結尾如下,也就是說該鏡像的容器一啟動就會執行fwatchdog
CMD ["fwatchdog"]
  • 至此,您對Watchdog是否有了足夠的了解,如果前面的資訊量太大,咱們來做個小結;

小結

  1. 開發函數時,當函數文件編寫完成後,就開始製作docker鏡像;
  2. 製作的鏡像中,包含有fwatchdog文件,以及咱們編寫的函數,如果是python、nodejs等腳本語言,就會將腳本和nodejs或者python都複製到鏡像中,如果是java類型的,還會涉及到編譯構建;
  3. 部署好函數後,Kubernetes環境會根據此鏡像創建pod,而pod啟動後,就會運行fwatchdog文件,也就是啟動了watchdog進程;
  4. 外部訪問函數時,請求先到API Gateway,再到上一步創建的pod的8080埠;
  5. 這個pod裡面,是watchdog在監聽8080埠,收到請求後,創建一個node進程,把請求參數通過stdin傳給node進程;
  6. node進程會執行咱們開發函數時編寫的函數,並且將收到的參數作為函數的入參;
  7. 咱們編寫的函數執行完畢後,node進程將返回值寫入stdout,這時候watchdog通過stdout就會收到函數的返回值;
  8. watchdog將收到的返回值返回給API Gateway,最終返回給用戶;
  • 這回終於說清楚了吧,如果您還意猶未盡想繼續深入,請移步watchdog的源碼吧,地址是://github.com/openfaas/classic-watchdog ,這是golang編寫的,作者欣宸因為是Java背景,就不敢多說了,怕被打;

java程式設計師的擔憂

  1. 如果您是一位java程式設計師,看完以上內容是否和作者一樣湧起一絲擔憂?
  2. 咱們先看看tomcat的架構,如下圖:
    在這裡插入圖片描述
  3. 看完上圖重點就來了,對比如下:
    tomcat:監聽8080,收到請求後,從執行緒池中指定執行緒處理;
    watctdog:監聽8080,收到請求後,啟動一個進程去處理;
  4. 如果您是java程式設計師,應該能感受到這種擔憂:啟動進程意味著創建JVM實例,再創建執行緒,這些相對於業務邏輯都更消耗系統資源(CPU、記憶體),如果通過大量fork進程去處理高並發的話,其代價可想而知,另外連接池、JIT、GC等各種優化手段更無從談起了;
  5. 所以,真相是什麼呢?在OpenFaaS上開發java函數,會不會走watchdog + fork進程那一套?咱們下一篇細說吧,本文沒有貼程式碼,純手動打字,真的太累了…
  6. 先劇透:OpenFaaS很優秀,上述問題已經解決,就看Alex Ellis大神的具體手段了;

你不孤單,欣宸原創一路相伴

  1. Java系列
  2. Spring系列
  3. Docker系列
  4. kubernetes系列
  5. 資料庫+中間件系列
  6. DevOps系列

歡迎關注公眾號:程式設計師欣宸

微信搜索「程式設計師欣宸」,我是欣宸,期待與您一同暢遊Java世界…
//github.com/zq2599/blog_demos