簡介

在本教程中,您將學習如何使用現代工具最佳實踐來監控您的Javascript應用程式。

探索分散式追蹤的力量,並了解如何無縫整合和利用 Odigos 和 Jaeger 等工具來增強您的監控能力。

您將學到什麼:✨

  • 如何在 Javascript 中建立微服務🐜。

  • 為微服務設定 Docker 容器📦。

  • 配置 Kubernetes ☸️ 以管理微服務。

  • 整合追蹤後端以可視化追蹤🔍。

您準備好成為監控 JS 應用程式的專家了嗎? 😍 說是的,先生!

我聽不到你說話。大聲點說。 🙉

大聲點 GIF


讓我們設定一下 🦄

🚨 在部落格的這一部分中,我們將建立一個虛擬的 JavaScript 微服務應用程式並將其部署在本地 Kubernetes 上。如果您已經有一個並且正在跟進,請隨意跳過這一部分。

為您的應用程式建立初始資料夾結構,如下所示。 👇🏻

mkdir microservices-demo
cd microservices-demo
mkdir src
cd src

設定伺服器 🖥️

👀 出於演示目的,我將建立兩個相互通信的微服務,最終我們可以使用它來視覺化分散式追蹤。

  • 建置與 Dockerize 微服務 1

在「/src」資料夾中,建立一個新資料夾「/microservice-1」。在資料夾內初始化 NodeJS 專案並安裝所需的依賴項。

mkdir microservice-1
cd microservice-1
npm init -y
npm install --save express node-fetch

建立一個新檔案“index.js”並新增以下程式碼:

// 👇🏻/src/microservice-1/index.js
const express = require("express");
const fetch   = require("node-fetch")

const app = express();
const PORT = 3001;

app.use(express.json());

app.get("/", async (req, res) => {
  try {
    const response = await fetch("http://microservice2:8081/api/data");
    const data = await response.json();
    res.json({
      data: "Microservice 2 data received in Microservice 1",
      microservice2Data: data,
    });
  } catch (error) {
    console.error(error.message);
    res.status(500).json({ error: "Internal Server Error" });
  }
});

app.listen(PORT, () => {
  console.log(`Microservice 1 listening on port ${PORT}`);
});

伺服器正在偵聽連接埠“3001”,並且在對“/”發出請求時,我們從“microservice2”請求資料並將回應作為 JSON 物件返回。 📦

現在,是時候對這個微服務進行 docker 化了。在“/microservice-1”資料夾中建立一個新的“Dockerfile”並新增以下程式碼:

// 👇🏻/src/microservice-1/Dockerfile
FROM node:18

# Use /usr/src/app as the working directory
WORKDIR /usr/src/app

# Copy package files and install production dependencies
COPY --chown=node:node package*.json /usr/src/app
RUN npm install --production

# Copy the rest of the files
COPY --chown=node:node . /usr/src/app/

# Switch to the user node with limited permissions
USER node

# Expose the application port
EXPOSE 3001

# Set the default command to run the application
CMD ["node", "index.js"]

將我們不想推送到容器的文件加入到“.dockerignore”總是很好。使用我們不想推送的檔案的名稱來建立一個“.dockerignore”檔案。

// 👇🏻/src/microservice-1/.dockerignore
node_modules
Dockerfile

最後,透過執行以下命令來建構 🏗️ docker 映像:

docker build -t microservice1-image:latest .

現在,這就是我們第一個微服務的完整設定。 ✨

  • 建置與 Dockerize 微服務 2

我們將有一個類似於“microservice1”的設置,只是在這裡和那裡進行了一些更改。

在「/src」資料夾中,建立一個新資料夾「/microservice-2」。在該資料夾內,初始化 NodeJS 專案並安裝所需的依賴項。

mkdir microservice-2
cd microservice-2
npm init -y
npm install --save express node-fetch

建立一個新檔案“index.js”並新增以下程式碼:

// 👇🏻/src/microservice-2/index.js
const express = require("express");
const fetch   = require("node-fetch")

const app = express();
const PORT = 3002;

app.use(express.json());

app.get("/api/data", async (req, res) => {
  const url = "https://jsonplaceholder.typicode.com/users";

  try {
    const response = await fetch(url);
    const data = await response.json();
    res.json(data);
  } catch (error) {
    console.error(error.message);
    res.status(500).json({ error: "Internal Server Error" });
  }
});

app.listen(PORT, () => {
  console.log(`Microservice 2 listening on port ${PORT}`);
});

伺服器正在偵聽連接埠 3002,根據對“/api/data”的“GET 請求”,我們從“jsonplaceholder”獲取資料並將回應作為 JSON 物件傳回。 📦

現在,是時候對這個微服務進行 docker 化了。複製並貼上「microservice1」的整個「Dockerfile」內容,然後將連接埠從 3001 變更為 3002。

另外,新增一個「.dockerignore」檔案並包含我們在建立「microservice1」時新增的相同檔案。

最後,透過執行以下命令來建構 🏗️ Docker 映像:

docker build -t microservice2-image:latest .

現在,這也是我們第二個微服務的完整設定。 ✨

  • 設定 Kubernetes

確保已安裝 Minikube

透過執行以下命令建立新的本機 Kubernetes 叢集。我們在設定 Odigos 和 Jaeger 時將需要它。

啟動 Minikube:🚀

minikube start

現在我們已經準備好並 Docker 化了兩個微服務,是時候設定 Kubernetes 來管理這些服務了。

在專案的根目錄下,建立一個新資料夾「/k8s/manifests」。在此資料夾中,我們將為兩個微服務新增部署和服務配置。

  • 部署設定📜:用於在 Kubernetes 叢集上實際部署容器。

  • 服務配置📄:將 Pod 暴露給叢集內部和叢集外部。

首先,我們為「microservice1」建立清單。建立一個新檔案「microservice1-deployment-service.yaml」並新增以下內容:

// 👇🏻/k8s/manifests/microservice1-deployment-service.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: microservice1
spec:
  selector:
    matchLabels:
      app: microservice1
  template:
    metadata:
      labels:
        app: microservice1
    spec:
      containers:
        - name: microservice1
          image: microservice1-image
          # Make sure to set it to Never, or else it will pull from the docker hub and fail.
          imagePullPolicy: Never
          resources:
            limits:
              memory: "200Mi"
              cpu: "500m"
          ports:
            - containerPort: 3001
---
apiVersion: v1
kind: Service
metadata:
  name: microservice1
  labels:
    app: microservice1
spec:
  type: NodePort
  selector:
    app: microservice1
  ports:
    - port: 8080
      targetPort: 3001
      nodePort: 30001

此配置部署了一個名為「microservice1」的微服務,其資源限制為 200MB 記憶體 🗃️ 和 0.5 個 CPU 核心。它透過部署在連接埠 3001 上公開微服務,並透過服務在 NodePort 30001 上公開微服務。

🤔 還記得我們用名稱「microservice1-image」建構的「Dockerfile」嗎?我們使用相同的映像來建立容器。

可透過集群內的連接埠 8080 存取它。我們假設「microservice1-image」透過「imagePullPolicy: Never」在本地可用。如果沒有到位,它將嘗試從 Docker Hub 🐋 中提取映像並失敗。

現在,讓我們為「microservice2」建立清單。建立一個名為「microservice2-deployment-service.yaml」的新檔案並新增以下內容:

// 👇🏻/k8s/manifests/microservice1-deployment-service.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: microservice2
spec:
  selector:
    matchLabels:
      app: microservice2
  template:
    metadata:
      labels:
        app: microservice2
    spec:
      containers:
        - name: microservice2
          image: microservice2-image
          # Make sure to set it to Never, or else it will pull from the docker hub and fail.
          imagePullPolicy: Never
          resources:
            limits:
              memory: "200Mi"
              cpu: "500m"
          ports:
            - containerPort: 3002
---
apiVersion: v1
kind: Service
metadata:
  name: microservice2
  labels:
    app: microservice2
spec:
  type: NodePort
  selector:
    app: microservice2
  ports:
    - port: 8081
      targetPort: 3002
      nodePort: 30002

它與“microservice1”的清單類似,只有一些更改。 👀

此配置部署一個名為「microservice2」的微服務,並透過部署在連接埠 3002 上將其內部公開,並透過服務在 NodePort 30002 上將其外部公開。

可透過叢集內的連接埠 8081 進行存取,假設「microservice2-image」可透過「imagePullPolicy: Never」在本地使用。

全部完成後,請確保套用這些設定並使用這些服務啟動 Kubernetes 叢集。將目錄更改為/manifests並執行以下命令:👇🏻

kubectl apply -f microservice1-deployment-service.yaml
kubectl apply -f microservice2-deployment-service.yaml

執行以下命令檢查我們的兩個部署是否正在執行:👇🏻

kubectl get pods

Kubernetes Pod

最後,我們的應用程式已準備就緒,並使用必要的部署配置部署在 Kubernetes 上。 🎉


安裝 Odigos 😍

💡 Odigos 是一個開源可觀察性控制平面,使組織能夠建立和維護其可觀察性管道。

Odigos - 監控工具

ℹ️ 如果您在 Mac 上執行,請執行以下命令在本地安裝 Odigos。

brew install keyval-dev/homebrew-odigos-cli/odigos

ℹ️ 如果您使用的是 Linux 計算機,請考慮透過執行以下命令從 GitHub 版本安裝它。確保根據您的 Linux 發行版更改該檔案。

ℹ️ 如果 Odigos 二進位檔案不可執行,請在執行安裝指令之前執行此指令 chmod +x odigos 使其可執行。

curl -LJO https://github.com/keyval-dev/odigos/releases/download/v1.0.9/cli_1.0.9_linux_amd64.tar.gz
tar -xvzf cli_1.0.9_linux_amd64.tar.gz
./odigos install

Odigos 安裝

如果您需要有關其安裝的更多簡短說明,請按照此連結操作。

現在,Odigos 已準備好執行 🎉。我們可以執行它的 UI,配置追蹤後端,並相應地發送追蹤。


將 Odigos 連接到追蹤後端 💫

💡 Jaeger 是一個開源的端對端分散式追蹤系統。

Odigos - 分散式追蹤平台

設定 Jaeger!

在本教程中,我們將使用 Jaeger 🕵️‍♂️,這是一個流行的開源平台,用於查看微服務應用程式中的分散式追蹤。我們將用它來查看 Odigos 生成的痕跡。

有關 Jaeger 安裝說明,請點選此 link。 👀

若要在 Kubernetes 叢集上部署 Jaeger,請執行下列命令:👇🏻

kubectl create ns tracing
kubectl apply -f https://raw.githubusercontent.com/keyval-dev/opentelemetry-go-instrumentation/master/docs/getting-started/jaeger.yaml -n tracing

在這裡,我們建立一個「tracing」命名空間,並在該命名空間中為 Jaeger 應用部署配置📃。

此命令設定自託管 Jaeger 實例及其服務。 👀

執行以下命令來取得正在執行的 pod 的狀態:👇🏻

kubectl get pods -A -w

等待所有三個 Pod 都 正在執行,然後再繼續。

Kubernetes Pod

現在,要在本地查看 Jaeger Interface 💻,我們需要進行連接埠轉送。將流量從本機電腦上的連接埠 16686 轉送至 Kubernetes 叢集中選定 pod 上的連接埠 16686。

kubectl port-forward -n tracing svc/jaeger 16686:16686

此命令在本機電腦和 Jaeger pod 之間建立一條隧道,公開 Jaeger UI,以便您可以與其互動。

最後,在瀏覽器上開啟「 http://localhost:16686 」並查看 Jaeger 實例正在執行。

Jaeger UI

設定 Odigos 與 Jaeger 一起工作! 🌟

ℹ️ 對於 Linux 用戶,請前往從 GitHub 版本下載 Odigos 二進位檔案的資料夾,然後執行以下命令來啟動 Odigos UI。

./odigos ui

ℹ️ 對於 Mac 用戶,只需執行:

odigos ui

造訪“ http://localhost:3000 ”,您將看到 Odigos 介面,您將在“default”命名空間中看到您的部署。

Odigos 登陸頁

選擇這兩個選項並點擊“下一步”。在下一頁上,選擇 Jaeger 作為後端,並在出現提示時加入以下詳細資訊:

  • 目的地名稱🛣️:提供您想要的任何名稱,例如說快速追蹤

  • 端點🎯:為端點加上jaeger.tracing:4317

就是這樣 - Odigos 已準備好向我們的 Jaeger 後端發送痕跡。就是這麼簡單。 🤯

具有兩個微服務的 Odigos UI


查看分散式追蹤 🧐

設定 Odigos 後,在 Jaeger 主頁「 http://localhost:16686 」上,您將已經看到列出的兩個微服務。

Jaeger UI 列出了兩個微服務

Odigos 已經開始向 Jaeger 發送我們的應用程式痕跡。 😉

請記住,這是我們的微服務應用程式。由於以「microservice1」為起點,因此再向「microservice1」發出一些請求,隨後它將向「microservice2」請求資料並傳回。最終,Jaeger 將開始填滿這些痕跡。

Jaeger 分散式追蹤

點擊任一請求,您應該能夠觀察請求如何流經您的應用程式以及完成每個請求所需的時間。

這一切都是在沒有更改一行程式碼的情況下完成的。 🤯 一切都感謝 Odigos! 🤩

令人震驚的 GIF

想像一下,這只是一個很小的虛擬應用程式,但對於一個執行著大量微服務並相互交互的更大的應用程式來說,分散式追蹤將非常強大! 💪

透過分散式跟踪,您可以輕鬆辨識應用程式中的瓶頸,並確定哪個服務導致問題或花費更長的時間。 🕒


讓我們總結一下! 🥱

到目前為止,您已經學習如何使用 Odigos 作為應用程式和追蹤後端 Jaeger 之間的 中間件,透過分散式追蹤來密切監控 👀 Javascript 應用程式。 👏

如果您已經做到了這一步,請拍拍自己的背。 🥳你值得擁有! 😉

本教學的源程式碼可在此處取得:

https://github.com/keyval-dev/blog/tree/main/odigos-monitor-JS-like-a-pro

如果您對本文有任何疑問或建議,請在下面的評論部分分享。 👇🏻

那麼,這就是本文的內容。感謝您的閱讀! 🎉🫡


原文出處:https://dev.to/odigos/monitor-your-javascript-application-like-a-pro-581p


共有 0 則留言