---
title: 【Serverless 應用案例賞析筆記】02. Serverless 在 API 經濟中的應用
date: 2020-04-02
is_modified: false
disqus: cynthiahackmd
categories:
- "雲端網路 › 雲端運算"
tags:
- "其他課程平台"
- "Serverless 應用案例賞析"
- "Fass/Serverless"
- "網站與雲端平台"
- "OpenWhisk"
---
{%hackmd @CynthiaChuang/Github-Page-Theme %}
<br>
<p class="illustration">
<img src="https://i.imgur.com/EXCq2WM.png" alt="投影片封面">
投影片封面(圖片來源: <a href="https://github.com/dWChina/ibm-opentech-ma/blob/master/serverless-use-cases/Serverless-01.pdf">課程講義</a>)
</p>
本堂課程為此系列的第一講,主要來探討 Serverless 在 API 經濟中可以產生怎樣的作用。
<!--more-->
<br>
:::warning
**文中的IBM 文件連結**
如果文中附上的 IBM 文件連結無法顯示或不存在,試著把 doc 語系換成英文後,再重新連結一次試試看。
發現 IBM 的多語系文件沒做好,如果沒有相對應的翻譯內容,不會直接導向英文頁面,而是直接顯示不存在。
:::
## 回顧
開始前先來複習一下 **Serverless要點** 與 **OpenWhisk 程式編輯模型**。
### Serverless 要點
- [第一堂課程筆記 - Serverless](/@CynthiaChuang/Serverless-Use-Cases-Study-Notes-01#Serverless-%E8%A6%81%E9%BB%9E)
<br>
上一堂課有介紹到 Serverless 存在兩種類型的服務: Function-as-a-Service(FaaS) 與 Backend-as-a-Service(BaaS)。
兩種類型的服務存在著相同特點:
<div class="blockquote-center">
<p>
無需管理、按需執行、按需擴展、按使用來計費
</p>
</div>
依照講師的說明,只要其實只要滿足上述特點的的服務都可以被視為 Serverless 。
不過如同上一堂課所說的,Serverless 雖然包含了兩種服務概念,但因為實做複雜度的偏向,因此一般在討論 Serverless 時多集中在 FaaS。
<br>
Function-as-a-Service FaaS,中文翻譯為**函式即服務**,...恩...函式就是一般會在程式碼裡面寫的函式。不過需要注意的是這些函式是
==無狀態==、==短暫的==、且是==有限制的==。
除此之外,FaaS 的另外一個設定要點是 ==API Gateway==,它可以將 Serverless 中的函式做為服務暴露出來,讓客戶端可以直接調用這個服務。
### OpenWhisk 程式編輯模型
在本堂課主要會利用 Serverless 無狀態、短暫的、有限制的特點,來看看它在 API 經濟中的作用。
- [第一堂課程筆記 - OpenWhisk 程式編輯模型](/@CynthiaChuang/Serverless-Use-Cases-Study-Notes-01#OpenWhisk-%E7%A8%8B%E5%BC%8F%E7%B7%A8%E8%BC%AF%E6%A8%A1%E5%9E%8B)
<p class="illustration">
<img src="https://i.imgur.com/lZP3G5P.png" alt="Apache OpenWhisk 程式編輯模型">
Apache OpenWhisk 程式編輯模型(圖片來源: <a href="https://github.com/dWChina/ibm-opentech-ma/blob/master/serverless-use-cases/Serverless-0.pdf">課程講義</a>)
</p>
另外在上一講中還提到了 OpenWhisk 程式編輯模型。
OpenWhisk 是一個典型的事件驅動型的程式編輯模型,其中有幾個主要的概念:觸發器(Trigger)、動作(Action)、規則(Rule)與套件(Package)。
我們可以定義規則,通過規則將觸發器與動作關聯起來,因此當某個事件被觸發時,就會執行相對應的動作。
而套件就是把一系列相關的觸發器、動作和規則關聯在一起。例如:Apache OpenWhisk 的 [alarms package](https://github.com/apache/openwhisk-package-alarms) 就是一個還滿好用的套件。
## 典型應用場景
由於它的技術特點,因此存在一些典型的應用場景:
1. **資料庫的增刪查改的事件響應**
對於資料的變更,做出相應的反應與更新。
2. **感測器的資料分析**
在 IoT 的應用中,可對收回的資料做分析,又或者是資料更新後的路徑重新規劃等。
應該在下一章 [Serverless 在物聯網領域中的應用](/@CynthiaChuang/Serverless-Use-Cases-Study-Notes-03)會有更仔細的討論,先把連結建立起來。
3. **定時任務**
定期回收資料、定期運算...等。
4. **後端 API**
本堂課重點!! 可以去實現大量的後端 API,並將這些功能曝露出來供使用者使用。
5. **系統之間交互的橋樑**
因為其輕量的特性,可以用來作為系統間的溝通橋樑。例如:程式更新去觸發 Jekyll 的更新。
## API
既然本堂課的副標題叫 **《Serverless 在 API 經濟中的應用》**,當然得稍微介紹下 API。
### API 經濟
什麼是 API 經濟?
講師提到,現在開發功能有種用==搭積木==來實現功能趨勢。換句話說,自己寫的程式越來越少,更多是採用第三方服務。
這樣的開發趨勢,會使得開發人員直接面向整個生態圈打交道 - 不是需要用調用別人的 API ,就是我們實做的 API 被調用。
而所謂 API 經濟,指的是通過 Open API 把後臺的資料、資源...等能力,開放提供第三方人員有償或是無償使用,這樣的開放可以直接對企業利潤帶來引響,或是擴大自身在生態圈影響力,並且很快的完成創新。
### 開放 API
開放 API = 公開 API = Open API = 共通性資料存取應用程式介面
上面四個名詞我最熟悉的是第三個,不過它們指得同一件事:
:::info
**Open API**
服務的提供者將專有軟體、應用程式或是 web...等服務,通過網路,向服務使用者提供訪問的interface,且這樣的服務必須是安全且穩定的。
:::
<br>
在 API 經濟之下,越來越多的企業通過 API 將自己企業的功能和數據開放出去供別人調用,從而給企業本身帶來直接的價值。可是很多情況下,企業已有的功能不適合直接暴露給外部使用戶,需要考慮相關認證的機制以及隱私資料遮蔽,做一定的限制和修改。
### Serverless 平台實現 Open API
若不採用 Serverless 來實現 Open API,必須先分配個 VM 或 container,然後設定操作系統、執行環境,並上傳程式碼,接下來 7 * 24 等待著。等待前端調用,如果前端調用來了,處理資料丟到後端,再等待後端返回後,增加處裡丟還給前端。
除機器必須 7 * 24 運轉外,上線必須花費時間設定相關作業,這些都造成相關服務的提供者開發及維運上的困難。
<p class="illustration">
<img src="https://i.imgur.com/8GXYW5F.png" alt="Serverless 平台實現 Open API 架構">
Serverless 平台實現 Open API 架構(圖片來源: <a href="https://github.com/dWChina/ibm-opentech-ma/blob/master/serverless-use-cases/Serverless-1.pdf">課程講義</a>)
</p>
上圖是使用 Serverless 平台實現 Open API 的架構,從左向右看,分別是互聯網、防火牆、API Gateway、 FaaS 與要存取的內部系統。
互聯網的部份代表的是使用者的存取,而因為要將 interface 暴露給使用者,所以中間在架個防火牆,防火牆後面才是 API Gateway。
API Gateway 這邊主要負責安全性、流量管理、拜訪與響應的策略及監控、統計、分析...等。
而在 API Gateway 後面則是接 Serverless 中的 FaaS 服務,在這邊就依照你的開發需求去撰寫程式,例如:輸⼊輸出格式轉化、隱私數據屏蔽、加密與解密...等。
<br>
簡單來說, FaaS 這邊存放的是,當開放給外部使用時所有需要使用程式來處理的內容。這部份的內容可用任何語言實作。
接下來,通過 API Gateway 曝露出來一個 URL,再將這個 URL 發布出去就可以了。
使用 Serverless 用的話,可以節省了資源(至少不用 7 * 24 運轉?)
## 場景示例
<p class="illustration">
<img src="https://i.imgur.com/4rc6ZLU.png" alt="數據訪問 API">
數據訪問 API(圖片來源: <a href="https://github.com/dWChina/ibm-opentech-ma/blob/master/serverless-use-cases/Serverless-1.pdf">課程講義</a>)
</p>
課程這邊講師舉了好幾個場景示例,不過有點懶沒有將它們一一打出來。
不過基本上就是藉由網路通過 API Gateway 去請求 FaaS,而 FaaS 接到請求後執行相對應的程式,再將結果返回給使用者。
## 操作示範
這節我能做的操作跟講師不太一樣,她在這章節所使用的是 **OpenWhisk CLI**,但這部份在 IBM 上的操作文件整個不見了!
因此就算從 github 把 [OpenWhisk CLI](https://github.com/apache/incubator-openwhisk-cli/releases) 下載下來,我也不清楚該如何將 wsk CLI 跟 IBM Function 做連接,再加上有考慮自己架個 OpenWhisk 來試試看,所以 wsk CLI 的使用就決定向後推了 XD
### 環境準備
1. IBM cloud 帳號
2. 安裝 IBM Cloud Developer Tools
3. 配置 CLI
<br>
**IBM Cloud Developer Tools**
前面提過課程中安裝的是 wsk CLI,但因為我在 IBM 找不到文件的關係,所以先改用 IBM 的 CLI。
為了快速試用,所以選擇現成的 Docker Container 來使用,[安裝步驟](https://cloud.ibm.com/docs/cli/reference/bluemix_cli?topic=cloud-cli-using-idt-from-docker#idt-docker-prereq)如下:
1. **從 Docker hub 拉回 Image**
```shell=
$ docker pull ibmcom/ibm-cloud-developer-tools-amd64
```
2. **啟動並進入 Docker Container**
```shell=
$ docker run -ti ibmcom/ibm-cloud-developer-tools-amd64
```
<br>
:::warning
**Docker Container 環境**
IBM 所提供的 Container 作業系統環境是 Alpine Linux。所以一些操作指令需要注意一下。
:::
<br>
記錄一下,在 Docker Container 中我需要反覆查詢的指令:
1. **安裝**
如要安裝其他程式,如 vim ,用的指令不是 `apt-get`
```shell=
$ apk update
$ apk add vim
```
2. **重新進入 Container**
如果按照往常慣例,使用
```shell=
$ docker exec -ti [ID] bash
```
但會出現下列錯誤訊息:
```shell=
OCI runtime exec failed: exec failed: container_linux.go:345: starting container process caused "exec: \"bash\": executable file not found in $PATH": unknown
```
依照 [appleboy](https://github.com/appleboy/gorush/issues/319#issuecomment-353721167) 的建議改用 `alpine` tag
```shell=
$ docker exec -ti [ID] /bin/sh
```
<br>
**配置 CLI**
依照[教學文件](
https://cloud.ibm.com/functions/learn/cli)配置就行了
1. **登入 IBM Cloud**
```shell=
$ ibmcloud login -a cloud.ibm.com -o [名稱空間] -s "dev"
```
不過用這個方式登入的話它會請你輸入帳號密碼,所以我會用右上角頭像中的**登入 CLI 及 API**,裡面有個一次性密碼的指令
```shell=
$ ibmcloud login -a https://cloud.ibm.com -u passcode -p [一次性密碼]
```
在此步驟之後,會請你設置區域之類的,我記得我是設**美南**(我知道有美中、美西、美東這些說法,但有美南這個說法嗎?)就是 us-south。
2. **安裝 Cloud Functions 外掛程式**
```shell=
$ ibmcloud plugin install cloud-functions
```
安裝的時候忘了記錄,我記得會出現一些安裝與升級的提示,依照提示的指令裝一裝就好了。
3. **目標名稱空間**
```shell=
$ ibmcloud target -o [名稱空間] -s dev
```
再列出可用的資源群組
```shell=
$ ibmcloud resource groups
```
將此名稱空間的資源群組設定為目標
```shell=
$ ibmcloud target -g [name of resource group]
```
4. **測試**
執行清單指令以顯示現行目標名稱空間中的所有實體。
```shell=
$ ibmcloud fn list
```
### CLI 操作
這堂課主要是在說 API 操作的部份,所以我也依照講師的授課內容,先找相對應的指令。至於其他的指令,我在酌情要貼測試結果還是文件就好。
<br>
**action**
在開始前先準備一段 action 的程式,課程中的範例是關於資料庫的操作,不過我這邊為了偷懶直接印出來假裝有 insert XD
另外,因為我不想預先編譯,所以挑了==直譯式語言==來實做,而在 Python 與 JavaScript 兩者之間,我挑了比較熟悉的 Python。
```python=
def main(args):
name = args.get("name", "stranger")
color = args.get("color", "white")
command = "INSERT INTO catdb VALUES( {} , {} )".format(name,color)
print(command)
return {"command":command}
```
<br>
依照 [教學文件](https://cloud.ibm.com/docs/openwhisk?topic=cloud-functions-actions) 來 Creating actions
1. **建立 action**
```shell=
$ ibmcloud fn action create catapi catapi.py --kind python:3.7 --web true
ok: created action catapi
```
<br>
**kind**
因為我是挑 python 所以 `kind` 參數需要設置為 `python:3.7` ,如果是其他語言撰寫請查詢相對應的 [tag](https://cloud.ibm.com/docs/openwhisk?topic=cloud-functions-cli-plugin-functions-cli#cli_action_create)。
如果你的 python 檔案必須依賴第三方套件或是有多份 Python 檔案請查詢 [Packaging 的方法](https://cloud.ibm.com/docs/openwhisk?topic=cloud-functions-prep#how_to_package_python)。
<br>
**web**
因為我要直接使用 url 呼叫所以,這邊將 web 設為 true 方便後面直接呼叫。
2. **刪除 action**
恩,第一次建立的時候打錯字了,先把錯誤的 action 刪掉
```shell=
$ ibmcloud fn action delete cayapi
ok: deleted action cayapi
```
3. **查詢 action 細節**
如要查詢 action 的細節可以用 `action get` 來查看。
```shell=
$ ibmcloud fn action get catapi
ok: got action catapi
{
"namespace": "[名稱空間]_dev",
"name": "catapi",
"version": "0.0.1",
"exec": {
"kind": "python:3.7",
"binary": false
},
"annotations": [
{
"key": "web-export",
"value": true
},
{
"key": "raw-http",
"value": false
},
{
"key": "final",
"value": true
},
{
"key": "exec",
"value": "python:3.7"
}
],
"limits": {
"timeout": 60000,
"memory": 256,
"logs": 10,
"concurrency": 1
},
"publish": false,
"updated": 1586324682689
}
```
4. **試著調用 action**
```shell=
$ ibmcloud fn action invoke catapi --blocking -r --param name Cynthia --param color black
{
"command": "INSERT INTO catdb VALUES( Cynthia , black )"
}
```
如果想看調用紀錄可以下 `list` 來查看
```shell=
$ ibmcloud fn activation list catapi
Datetime Activation ID Kind Start Duration Status Entity
2020-04-08 06:07:21 e07e2378302245f1be2378302255f1f5 python:3.7 warm 2ms success Cynthia_Ch...com_dev/catapi:0.0.1
2020-04-08 06:07:11 5ce7fafa63364e64a7fafa6336ce64d3 python:3.7 warm 1ms success Cynthia_Ch...com_dev/catapi:0.0.1
2020-04-08 06:06:53 440e81cfb43a455d8e81cfb43a955d07 python:3.7 warm 2ms success Cynthia_Ch...com_dev/catapi:0.0.1
2020-04-08 06:06:36 47fb4b61be884b62bb4b61be88ab62c1 python:3.7 cold 183ms success Cynthia_Ch...com_dev/catapi:0.0.1
2020-04-08 05:44:20 aa2b3be4990f479bab3be4990fb79b1f python:3.7 warm 1ms success Cynthia_Ch...com_dev/catapi:0.0.1
2020-04-08 05:44:01 4b698055804240ada98055804270aded python:3.7 cold 175ms success Cynthia_Ch...com_dev/catapi:0.0.1
2020-04-08 05:43:36 741d9ac2f43d448d9d9ac2f43d848dd7 python:3.7 cold 162ms developer error Cynthia_Ch...com_dev/catapi:0.0.1
```
5. **api 設定**
```shell=
$ ibmcloud fn api create /catapi /insert post catapi --response-type json
ok: created API /catapi/insert POST for action /_/catapi
https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/b0aa51c2e269fe5f451e1a50345b0bb86f711854511ee59e834395c2f375e57b/catapi/insert
```
如此會拿到 api 的 url,就可以從外部使用 curl 呼叫 API 了!
```shell=
$ curl --request POST \
--url https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/b0aa51c2e269fe5f451e1a50345b0bb86f711854511ee59e834395c2f375e57b/catapi/insert \
--header "Content-Type: application/json" \
--data '{"name":"CC", "color":"black"}'
{
"command": "INSERT INTO catdb VALUES( CC , black )"
}
```
### 高級 API gateway
不過使用 Openwisk 沒有流量控制、安全性...等功能,必須依賴安裝其他第三方 API 來控管。
不過 IBM Function 倒是另外提供這些功能,但必須從 UI 來控制就是了。
<p class="illustration">
<img src="https://i.imgur.com/9MZkFFQ.png" alt="高級 API gateway">
</p>
## 其他連結
1. Serverless 應用案例賞析筆記:[目錄](/@CynthiaChuang/Serverless-Use-Cases-Study-Notes-Contents) / [另開書籍模式閱讀](/@CynthiaChuang/Serverless-Use-Cases-Study-Notes)
2. 課程內容:影片([IBM片源](https://mediacenter.ibm.com/media/1_u1ucwcoh) 、[youku教育片源](http://v.youku.com/v_show/id_XMzg2MzU5MDY4NA==.html))/ [講義](https://github.com/dWChina/ibm-opentech-ma/blob/master/serverless-use-cases/Serverless-01.pdf) / [Blog](https://mp.weixin.qq.com/s/XElPa20WYxdXnprh3ygEiQ)
## 參考資料
1. (2020-03-26)。[Using IBM Cloud Developer Tools from a Docker Container](https://cloud.ibm.com/docs/cli/reference/bluemix_cli?topic=cloud-cli-using-idt-from-docker) 。檢自 IBM Cloud Docs (2020-04-08)。
2. appleboy (2017-12-23)。[not able to use docker exec shell · Issue #319](https://github.com/appleboy/gorush/issues/319#issuecomment-353721167) 。檢自 Github (2020-04-08)。
3. [IBM Cloud Functions - CLI](https://console.bluemix.net/openwhisk/learn/cli) 。檢自 IBM Cloud (2020-04-08)。
4. (2020-01-17)。[Preparing apps for actions](https://cloud.ibm.com/docs/openwhisk?topic=cloud-functions-prep#how_to_package_python)。檢自 IBM Cloud Docs (2020-04-08)。
5. (2020-01-15)。[Creating actions](https://cloud.ibm.com/docs/openwhisk?topic=cloud-functions-actions)。檢自 IBM Cloud Docs (2020-04-08)。
6. (2020-03-09)。[Cloud Functions CLI](https://cloud.ibm.com/docs/openwhisk?topic=cloud-functions-cli-plugin-functions-cli#cli_action_create)。檢自 IBM Cloud Docs (2020-04-08)。
<br><br>
> **本文作者**: 辛西亞.Cynthia
> **本文連結**: [辛西亞的技能樹](https://cynthiachuang.github.io/Serverless-Use-Cases-Study-Notes-02) / [hackmd 版本](https://hackmd.io/@CynthiaChuang/Serverless-Use-Cases-Study-Notes-02)
> **版權聲明**: 部落格中所有文章,均採用 [姓名標示-非商業性-相同方式分享 4.0 國際](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en) (CC BY-NC-SA 4.0) 許可協議。轉載請標明作者、連結與出處!