1. 總覽/簡介
由網頁、應用程式伺服器和資料庫組成的多層式應用程式是網頁開發的基礎,也是許多網站的起點,但成功往往會帶來擴充性、整合和敏捷性方面的挑戰。舉例來說,如何即時處理資料,以及如何將資料分配至多個重要業務系統?這些問題加上網際網路規模應用程式的需求,促使分散式訊息系統應運而生,並催生了使用資料管道來建構彈性即時系統的架構模式。因此,瞭解如何將即時資料發布至分散式訊息系統,以及如何建構資料管道,是開發人員和架構師都必須具備的技能。
建構目標
在本程式碼研究室中,您將建構天氣資料管道,從物聯網 (IoT) 裝置開始,利用訊息佇列接收及傳送資料,運用無伺服器函式將資料移至資料倉儲,然後建立顯示資訊的資訊主頁。Raspberry Pi 搭配氣象感應器將做為 IoT 裝置,而 Google Cloud Platform 的多個元件則會組成資料管道。雖然建構 Raspberry Pi 很有幫助,但這是本程式碼研究室的選用部分,串流天氣資料也可以替換成指令碼。

完成本程式碼研究室的步驟後,您將擁有串流資料管道,可將資料提供給顯示溫度、濕度、露點和氣壓的資訊主頁。

課程內容
- 如何使用 Google Pub/Sub
- 如何部署 Google Cloud 函式
- 如何運用 Google BigQuery
- 如何使用 Google 數據分析建立資訊主頁
- 此外,如果您建構 IoT 感應器,還會瞭解如何運用 Google Cloud SDK,以及如何確保對 Google Cloud Platform 的遠端存取呼叫安全無虞
軟硬體需求
- Google Cloud Platform 帳戶。Google Cloud Platform 新使用者享有價值 $300 美元的免費試用期。
如要建構本程式碼實驗室的 IoT 感應器部分,而非使用範例資料和指令碼,您還需要下列項目 ( 可在此訂購完整套件或個別零件)...
- Raspberry Pi Zero W (含電源供應器、SD 記憶卡和保護殼)
- USB 讀卡機
- USB 集線器 (可將鍵盤和滑鼠連接至 Raspberry Pi 上的單一 USB 連接埠)
- 母對母麵包板線
- GPIO 槌頭接頭
- BME280 感應器
- 烙鐵和焊錫
此外,我們假設您可存取具備 HDMI 輸入端的電腦螢幕或電視、HDMI 傳輸線、鍵盤和滑鼠。
2. 開始設定
自修實驗室環境設定
如果您沒有 Google 帳戶 (Gmail 或 G Suite),請先建立帳戶。無論您是否已有 Google 帳戶,請務必把握價值$300 美元的免費試用期!
登入 Google Cloud Platform 控制台 ( console.cloud.google.com)。您可以使用這個實驗室的預設專案 (「My First Project」),也可以選擇建立新專案。如要建立新專案,請使用「管理資源」頁面。專案 ID 在所有 Google Cloud 專案中不得重複 (下方顯示的專案 ID 已被使用,因此不適用於您)。記下專案 ID (即「您的專案 ID 為 ____」),後續步驟將會用到。


完成這篇程式碼研究室的費用不應超過數美元,但如果您決定使用更多資源,或是將資源繼續執行,則可能會增加費用。請務必完成程式碼研究室結尾的「清除」一節。
3. 建立 BigQuery 資料表
BigQuery 是無伺服器式企業資料倉儲系統,兼具高擴充性和成本低廉的特性,是儲存物聯網裝置串流資料的理想選擇,同時也允許分析資訊主頁查詢資訊。
我們來建立資料表,存放所有物聯網天氣資料。從 Cloud 控制台選取 BigQuery。BigQuery 會在新視窗中開啟 (請勿關閉原始視窗,因為您需要再次存取)。

按一下專案名稱旁的向下箭頭圖示,然後選取「建立新資料集」

輸入「weatherData」做為資料集,選取儲存位置,然後按一下「確定」

按一下資料集旁的「+」號,即可建立新資料表

在「Source Data」(來源資料) 中,選取「Create empty table」(建立空白資料表)。在「Destination table name」(目的地資料表名稱) 中,輸入 weatherDataTable。在「結構定義」下方,按一下「新增欄位」按鈕,直到總共有 9 個欄位為止。如以下畫面所示填寫欄位,並為每個欄位選取適當的「類型」。完成所有步驟後,按一下「建立資料表」按鈕。

您應該會看到類似以下的結果:

您現在已設定好資料倉儲,可以接收天氣資料。
4. 建立 Pub/Sub 主題
Cloud Pub/Sub 為串流分析和事件導向運算系統提供簡單可靠的可擴充式基礎架構。因此非常適合處理傳入的 IoT 訊息,並允許下游系統處理這些訊息。
如果您仍在 BigQuery 視窗中,請切換回 Cloud 控制台。如果關閉了 Cloud 控制台,請前往 https://console.cloud.google.com
在 Cloud 控制台中,選取「Pub/Sub」,然後選取「Topics」。

如果看到「啟用 API」提示,請按一下「啟用 API」按鈕。

按一下「建立主題」按鈕

輸入「weatherdata」做為主題名稱,然後按一下「建立」

您應該會看到新建立的主題

您現在擁有 Pub/Sub 主題,可發布 IoT 訊息,並允許其他程序存取這些訊息。
安全地將訊息發布至主題
如果您打算從 Google Cloud 控制台以外的資源 (例如 IoT 感應器) 將訊息發布至 Pub/Sub 主題,就必須使用服務帳戶更嚴格地控管存取權,並建立信任憑證,確保連線安全。
在 Cloud Console 中,依序選取「IAM 與管理」和「服務帳戶」

按一下「建立服務帳戶」按鈕

在「角色」下拉式選單中,選取「Pub/Sub 發布者」角色

輸入服務帳戶名稱 (iotWeatherPublisher),勾選「提供一組新的私密金鑰」核取方塊,確認「金鑰類型」設為 JSON,然後按一下「建立」

系統會自動下載安全金鑰。只有一個金鑰,因此請務必妥善保管。按一下 [關閉]。

您應該會看到已建立服務帳戶,且該帳戶已與金鑰 ID 建立關聯。

為方便日後存取金鑰,我們會將金鑰儲存在 Google Cloud Storage。在 Cloud Console 中,依序選取「Storage」和「Browser」。

按一下「建立值區」按鈕

選擇儲存空間 bucket 的名稱 (名稱必須在整個 Google Cloud 中是唯一的),然後按一下「建立」按鈕

找出自動下載的安全金鑰,然後拖曳/放置或上傳至儲存空間 bucket

金鑰上傳完成後,應該會顯示在 Cloud Storage 瀏覽器中

請記下儲存空間 bucket 名稱和安全金鑰檔案名稱,以備後續使用。
5. 建立 Cloud 函式
雲端運算能讓您的運算作業完全以無伺服器的模型執行,因此您能隨時調整處理邏輯來因應其他位置發布的事件。在本實驗室中,每當訊息發布至天氣主題時,Cloud Function 就會啟動、讀取訊息,然後將訊息儲存在 BigQuery 中。
在 Cloud 控制台中選取 Cloud Functions

如果看到 API 訊息,請按一下「啟用 API」按鈕

按一下「建立函式」按鈕

在「Name」欄位中,輸入 function-weatherPubSubToBQ。在「觸發條件」中選取 Cloud Pub/Sub 主題,然後在「主題」下拉式選單中選取「weatherdata」。如要查看原始碼,請選取內嵌編輯器。在 index.js 分頁中,將下列程式碼貼到現有程式碼上。請務必變更專案 ID、資料集 ID 和資料表 ID 的常數,以符合您的環境。
/**
* Background Cloud Function to be triggered by PubSub.
*
* @param {object} event The Cloud Functions event.
* @param {function} callback The callback function.
*/
exports.subscribe = function (event, callback) {
const BigQuery = require('@google-cloud/bigquery');
const projectId = "myProject"; //Enter your project ID here
const datasetId = "myDataset"; //Enter your BigQuery dataset name here
const tableId = "myTable"; //Enter your BigQuery table name here -- make sure it is setup correctly
const PubSubMessage = event.data;
// Incoming data is in JSON format
const incomingData = PubSubMessage.data ? Buffer.from(PubSubMessage.data, 'base64').toString() : "{'sensorID':'na','timecollected':'1/1/1970 00:00:00','zipcode':'00000','latitude':'0.0','longitude':'0.0','temperature':'-273','humidity':'-1','dewpoint':'-273','pressure':'0'}";
const jsonData = JSON.parse(incomingData);
var rows = [jsonData];
console.log(`Uploading data: ${JSON.stringify(rows)}`);
// Instantiates a client
const bigquery = BigQuery({
projectId: projectId
});
// Inserts data into a table
bigquery
.dataset(datasetId)
.table(tableId)
.insert(rows)
.then((foundErrors) => {
rows.forEach((row) => console.log('Inserted: ', row));
if (foundErrors && foundErrors.insertErrors != undefined) {
foundErrors.forEach((err) => {
console.log('Error: ', err);
})
}
})
.catch((err) => {
console.error('ERROR:', err);
});
// [END bigquery_insert_stream]
callback();
};
在 package.json 分頁中,將下列程式碼貼到預留位置程式碼上
{
"name": "function-weatherPubSubToBQ",
"version": "0.0.1",
"private": true,
"license": "Apache-2.0",
"author": "Google Inc.",
"dependencies": {
"@google-cloud/bigquery": "^0.9.6"
}
}
如果「要執行的函式」設為「HelloWorld」,請改為「subscribe」。點選 [建立] 按鈕

函式部署完成後,大約需要 2 分鐘才會顯示

恭喜!您已透過函式將 Pub/Sub 連線至 BigQuery。
6. 設定 IoT 硬體 (選用)
組裝 Raspberry Pi 和感應器
如果超過 7 個,請將標題縮減為 7 個。將排針焊接到感應器板。

小心地將槌頭接腳安裝到 Raspberry Pi 上。

按照這裡的步驟格式化 SD 卡,並安裝 NOOBS (New Out Of Box Software) 安裝程式。將 SD 卡插入 Raspberry Pi,然後將 Raspberry Pi 放入保護殼。

使用麵包板電線,按照下圖將感應器連接至 Raspberry Pi。

Raspberry Pi 針腳 | 感應器連線 |
針腳 1 (3.3V) | VIN |
接腳 3 (CPIO2) | SDI |
針腳 5 (GPIO3) | SCK |
接腳 9 (接地) | GND |

依序連接螢幕 (使用 mini-HDMI 連接器)、鍵盤/滑鼠 (使用 USB 集線器) 和電源變壓器。
設定 Raspberry Pi 和感應器
Raspberry Pi 開機完成後,選取 Raspbian 做為所需作業系統,確認所需語言正確無誤,然後按一下「Install」(視窗左上方的硬碟圖示)。

按一下 Wi-Fi 圖示 (畫面右上角),然後選取網路。如果是安全網路,請輸入密碼 (預先共用金鑰)。

按一下樹莓派圖示 (畫面左上角),選取「Preferences」,然後選取「Raspberry Pi Configuration」。在「Interfaces」分頁中啟用 I2C。在「本地化」分頁中,設定語言代碼和時區。設定時區後,允許 Raspberry Pi 重新啟動。

重新啟動完成後,按一下「終端機」圖示開啟終端機視窗。

輸入下列指令,確認感應器已正確連線。
sudo i2cdetect -y 1
結果應如下所示,請確認讀取到的值為 77。

安裝 Google Cloud SDK
如要使用 Google Cloud 平台上的工具,必須在 Raspberry Pi 上安裝 Google Cloud SDK。這個 SDK 包含管理及運用 Google Cloud Platform 所需的工具,並支援多種程式設計語言。
開啟 Raspberry Pi 上的終端機視窗 (如果尚未開啟),並設定與 Raspberry Pi 作業系統相符的 SDK 版本環境變數。
export CLOUD_SDK_REPO="cloud-sdk-$(lsb_release -c -s)"
現在請新增 Google Cloud SDK 套件的儲存位置,這樣安裝工具在要求安裝 SDK 時,就會知道要從何處尋找。
echo "deb http://packages.cloud.google.com/apt $CLOUD_SDK_REPO main" | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list
從 Google 的套件存放區新增公開金鑰,讓 Raspberry Pi 在安裝期間驗證安全性並信任內容
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
確認 Raspberry Pi 上的所有軟體都是最新版本,並安裝核心 Google Cloud SDK
sudo apt-get update && sudo apt-get install google-cloud-sdk
出現「確定要繼續操作嗎?」的提示訊息時,請按下 Enter 鍵。
使用 Python 套件管理工具安裝 tendo 套件。這個套件是用來檢查指令碼是否多次執行,並安裝到天氣指令碼的應用程式。
pip install tendo
使用 Python 套件管理工具,確認 Google Cloud PubSub 和 OAuth2 Python 套件已安裝並為最新版本
sudo pip install --upgrade google-cloud-pubsub
sudo pip install --upgrade oauth2client
初始化 Google Cloud SDK
SDK 可讓您透過驗證,遠端存取 Google Cloud。在本程式碼研究室中,這項服務將用於存取儲存空間值區,方便您將安全金鑰下載至 Raspberry Pi。
在 Raspberry Pi 的指令列中輸入
gcloud init --console-only
系統提示「Would you like to log in (Y/n)?」時,請按下 Enter 鍵。
當畫面顯示「在瀏覽器中前往下列連結:」時,後面會接續以 https://accounts.google.com/o/oauth?... 開頭的長網址。請將滑鼠游標懸停在該網址上,按一下滑鼠右鍵並選取「複製網址」。然後開啟網路瀏覽器 (畫面左上角的藍色地球圖示),在網址列上按一下滑鼠右鍵,然後點選「貼上」。
看到「登入」畫面後,輸入與 Google Cloud 帳戶相關聯的電子郵件地址,然後按下 Enter 鍵。然後輸入密碼,並按一下「下一步」按鈕。
系統會提示 Google Cloud SDK 想要存取您的 Google 帳戶。按一下「允許」按鈕。
系統會顯示驗證碼。使用滑鼠醒目顯示該網址,然後按一下滑鼠右鍵並選擇「複製」。返回終端機視窗,確認游標位於「Enter verification code:」右側,然後按一下滑鼠右鍵並選擇「貼上」。按下 Enter 鍵。
如果系統要求「Pick cloud project to use:」,請輸入與您在本程式碼實驗室中使用的專案名稱對應的數字,然後按下 Enter 鍵。
如果系統提示您啟用 Compute API,請按下 Enter 鍵啟用。接著,系統會要求您設定 Google Compute Engine 設定。按下 Enter 鍵。系統會顯示可能的區域/可用區清單,請選擇您附近的區域/可用區,輸入對應的數字並按下 Enter 鍵。
稍後畫面會顯示一些額外資訊。Google Cloud SDK 設定完成。你可以關閉網頁瀏覽器視窗,因為之後不需要使用。
安裝感應器軟體和天氣指令碼
在 Raspberry Pi 的指令列中,複製從輸入/輸出接腳讀取資訊所需的套件。
git clone https://github.com/adafruit/Adafruit_Python_GPIO
安裝下載的套件
cd Adafruit_Python_GPIO
sudo python setup.py install
cd ..
複製可啟用天氣感應器的專案程式碼
git clone https://github.com/googlecodelabs/iot-data-pipeline
將感應器驅動程式複製到下載軟體的其餘部分所在的目錄。
cd iot-data-pipeline/third_party/Adafruit_BME280
mv Adafruit_BME280.py ../..
cd ../..
輸入文字即可編輯指令碼...
nano checkWeather.py
將專案變更為專案 ID,主題變更為 Pub/Sub 主題名稱 (這些內容已記錄在本程式碼實驗室的「設定」和「建立 Pub/Sub 主題」一節中)。
將 sensorID、sensorZipCode、sensorLat 和 sensorLong 值變更為所需值。如要取得特定地點或地址的經緯度值,請參閱這篇文章。
完成必要變更後,按下 Ctrl-X 鍵即可退出 nano 編輯器。按下 Y 鍵確認。
# constants - change to fit your project and location
SEND_INTERVAL = 10 #seconds
sensor = BME280(t_mode=BME280_OSAMPLE_8, p_mode=BME280_OSAMPLE_8, h_mode=BME280_OSAMPLE_8)
credentials = GoogleCredentials.get_application_default()
project="myProject" #change this to your Google Cloud project id
topic = "myTopic" #change this to your Google Cloud PubSub topic name
sensorID = "s-Googleplex"
sensorZipCode = "94043"
sensorLat = "37.421655"
sensorLong = "-122.085637"
安裝安全金鑰
將安全金鑰 (位於「安全地發布至主題」部分) 複製到 Raspberry Pi。
如果您使用 SFTP 或 SCP 將安全金鑰從本機複製到 Raspberry Pi (位於 /home/pi 目錄中),則可以略過下一個步驟,直接跳到匯出路徑。
如果將安全金鑰放入儲存空間值區,請務必記住儲存空間值區名稱和檔案名稱。使用 gsutil 指令複製安全金鑰。這項指令可以存取 Google 儲存空間 (這就是指令名稱為 gsutil,且檔案路徑以 gs:// 開頭的原因)。請務必變更下列指令,加入您的 bucket 名稱和檔案名稱。
gsutil cp gs://nameOfYourBucket/yourSecurityKeyFilename.json .
畫面上會顯示檔案正在複製的訊息,然後顯示作業已完成。
在 Raspberry Pi 的指令列中,匯出安全金鑰的路徑 (變更檔案名稱以符合您的需求)
export GOOGLE_APPLICATION_CREDENTIALS=/home/pi/iot-data-pipeline/yourSecurityKeyFilename.json
您現在已完成 IoT 氣象感應器,可以將資料傳輸至 Google Cloud。
7. 啟動資料管道
可能需要啟用 Compute API
從 Raspberry Pi 串流資料
如果您建構了 Raspberry Pi IoT 氣象感應器,請啟動指令碼,讀取氣象資料並推送至 Google Cloud Pub/Sub。如果不在 /home/pi/iot-data-pipeline 目錄中,請先移至該處
cd /home/pi/iot-data-pipeline
啟動天氣指令碼
python checkWeather.py
終端機視窗每分鐘應會回傳一次天氣資料結果。資料開始流動後,請跳至下一節 (確認資料流動)。
模擬資料串流
如果您沒有建構 IoT 天氣感應器,可以使用儲存在 Google Cloud Storage 中的公開資料集,並將資料饋送至現有的 Pub/Sub 主題,模擬資料串流。我們會使用 Google Dataflow,以及 Google 提供的範本,從 Cloud Storage 讀取資料並發布至 Pub/Sub。
在過程中,Dataflow 需要暫存儲存位置,因此請建立儲存空間 bucket。
在 Cloud Console 中,依序選取「Storage」和「Browser」。

按一下「建立值區」按鈕

為儲存空間 bucket 選擇名稱 (請注意,名稱在整個 Google Cloud 中不得重複),然後按一下「建立」按鈕。請記下這個儲存空間 bucket 的名稱,稍後會用到。

在 Cloud Console 中選取 Dataflow。

按一下「依據範本建立工作」(畫面頂端)

填寫工作詳細資料,如下所示,並注意下列事項:
- 輸入 dataflow-gcs-to-pubsub 的工作名稱
- 系統應會根據專案的代管位置自動選取區域,因此您不需要變更。
- 選取「GCS Text to Cloud Pub/Sub」的 Cloud Dataflow 範本
- 在「Input Cloud Storage File(s)」(輸入 Cloud Storage 檔案) 中,輸入 gs://codelab-iot-data-pipeline-sampleweatherdata/*.json (這是公開資料集)
- 輸出 Pub/Sub 主題的確切路徑取決於專案名稱,看起來會類似「projects/yourProjectName/topics/weatherdata」
- 將「臨時位置」設為您剛建立的 Google Cloud Storage bucket 名稱,並加上「tmp」的檔案名稱前置字串。格式應為「gs://myStorageBucketName/tmp」。
填妥所有資訊後 (如下所示),請按一下「執行工作」按鈕

Dataflow 工作應會開始執行。

Dataflow 工作大約一分鐘就能完成。

8. 確認資料正在流動
Cloud Functions 記錄
確認 Cloud Function 是由 Pub/Sub 觸發
gcloud beta functions logs read function-weatherPubSubToBQ
記錄應會顯示函式正在執行、收到資料,以及資料正在插入 BigQuery

BigQuery 資料
確認資料是否正在流入 BigQuery 資料表。前往 Cloud 控制台的 BigQuery (bigquery.cloud.google.com)。

在專案名稱下方 (視窗左側),依序點選「資料集」(weatherData) 和資料表 (weatherDataTable),然後按一下「查詢資料表」按鈕

在 SQL 陳述式中加入星號,讓陳述式顯示為 SELECT * FROM...,如下所示,然後按一下「執行查詢」按鈕

系統提示時,請按一下「執行查詢」按鈕

如果看到結果,表示資料流動正常。

資料串流設定完成後,即可開始建構數據分析資訊主頁。
9. 建立數據分析資訊主頁
Google 數據分析可將您的資料轉變成資訊豐富的資訊主頁與報告,既便於閱讀、容易共用,更具有完整的可自訂性。
使用網路瀏覽器前往 https://datastudio.google.com

在「開始建立新報表」下方,按一下「空白」,然後按一下「開始使用」按鈕

按一下核取方塊接受條款,然後按一下「下一步」按鈕,選取您感興趣的電子郵件,然後按一下「完成」按鈕。再次點按「建立新報表」下方的「空白」

按一下「建立新資料來源」按鈕

按一下「BigQuery」,然後按一下「授權」按鈕,接著選擇要與數據分析搭配使用的 Google 帳戶 (應與您在程式碼研究室中使用的帳戶相同)。

按一下「允許」按鈕

選取專案名稱、資料集和資料表。然後按一下「連線」按鈕。

如下所示變更類型欄位 (除了 timecollected 和 sensorID 以外,所有欄位都應為數字)。請注意,timecollected 會設為「日期時間」(而不只是「日期」)。如下所示變更「匯總」欄位 (露點、溫度、濕度和壓力應為平均值,其他所有項目應設為「無」)。按一下「建立報表」按鈕。

按一下「加入報表」按鈕確認

如果系統要求選取 Google 帳戶,請選取帳戶,然後按一下「允許」按鈕,讓 Google 數據分析將報表儲存在 Google 雲端硬碟中。

畫面上會顯示空白畫布,供您建立資訊主頁。從頂端列的圖示中選擇「時間序列」。

在空白工作表的左上角繪製矩形。應佔總空白頁面的約 1/4。

在視窗右側選取「樣式」分頁標籤。將「缺少資料」從「線條至零」變更為「線條中斷」。在「左側 Y 軸」部分,刪除「軸最小值」中的 0,將其變更為「自動」。

按一下工作表上的圖表,然後複製/貼上 (Ctrl-C/Ctrl-V) 3 次。將圖表對齊,讓每個圖表各占版面配置的 ¼。

按一下每個圖表,然後在「時間序列屬性和資料」部分下方,按一下現有指標 (露點),選擇要顯示的其他指標,直到所有四個天氣讀數 (露點、溫度、濕度和壓力) 都有自己的圖表為止。


現在您已擁有基本資訊主頁!

10. 恭喜!
您已建立完整的資料管道!您已瞭解如何使用 Google Pub/Sub、部署無伺服器函式、運用 BigQuery,以及使用 Data Studio 建立分析資訊主頁。此外,您也瞭解如何安全地使用 Google Cloud SDK,將資料匯入 Google Cloud Platform。最後,您已實際體驗過重要的架構模式,這種模式可處理大量資料,同時維持可用性。

清除
完成天氣資料和分析管道的實驗後,即可移除正在執行的資源。
如果你是自行建構物聯網感應器,請關閉感應器。在終端機視窗中按下 Ctrl-C 鍵停止指令碼,然後輸入下列指令,關閉 Raspberry Pi 電源:
shutdown -h now
前往 Cloud Functions,點選 function-weatherPubSubToBQ 旁的核取方塊,然後按一下「Delete」(刪除)。

前往 Pub/Sub,按一下「主題」,然後點選「weatherdata」主題旁的核取方塊,再按一下「刪除」

前往「儲存空間」,點選儲存空間值區旁的核取方塊,然後按一下「刪除」

前往 bigquery.cloud.google.com,按一下專案名稱旁的向下箭頭,然後依序按一下 weatherData 資料集右方的向下箭頭和「刪除資料集」。

系統提示時,請輸入資料集 ID (weatherData),完成資料刪除作業。
