Knative Eventing通過其Broker-Trigger模型為Serverless應用提供了強大的事件驅動能力,不僅支援事件的轉寄和過濾,還允許開發人員進行複雜的事件流程編排。這種架構適用於需要響應外部或內部觸發器來執行商務邏輯的應用情境,例如基於使用者行為自動發送通知、處理來自不同資料來源的資料流等。本文介紹如何基於Knative Eventing構建一個簡單的事件驅動架構,該事件驅動架構包含從服務部署到訊息傳遞機制的建立,再到最終的功能驗證。
原理說明
Knative Eventing提供了一個完整的事件模型,方便接入各個外部系統的事件。事件接入以後,通過Cloud Event標準在內部流轉,結合Broker-Trigger事件驅動模型進行事件處理。
如下圖所示,在Knative事件驅動架構中,Broker是訊息傳遞的中介,Trigger用於在特定條件下自動觸發處理流程。Broker-Trigger事件驅動模型的原理是通過Trigger訂閱Broker事件並過濾,最後將事件發送到對應的服務進行消費。
Event Source:這是產生事件的源頭,可以是內部系統(如資料庫更新)或外部服務(如雲Message Service)。
Ingress:在Eventing架構中,用於接收外來事件進入Knative叢集。
Channel:在Knative Eventing中使用Broker-Trigger模型需要選擇相應的Channel, 也就是事件流轉系統,當前支援Kafka、NATS Streaming、InMemoryChannel事件轉寄通道,預設為InMemoryChannel。
Broker:事件的中介層,負責接收來自不同事件來源的事件,並根據配置的Trigger進行路由。Broker可以實現複雜的事件流和處理邏輯,支援多種協議和後端事件服務(如NATS、Kafka等),使得事件的管理和分發更加靈活高效。
Trigger:定義了事件如何被路由到特定的服務。每個Trigger都關聯了一個事件過濾器(通常基於事件類型或內容)和一個Service目標,只有匹配過濾條件的事件才會被發送到指定的Service。
Service:在Eventing情境下,Service是事件的最終處理者,接收到由Trigger路由過來的事件後執行相應的商務邏輯。
前提條件
已安裝Knative Serving和Knative Eventing。具體操作,請參見部署Knative、部署Knative Eventing。
下文介紹如何利用Knative Eventing架構搭建一套簡單的事件驅動系統,其中包含了事件產生、傳輸及消費的基本要素。
步驟一:部署Knative服務
本文以event-display為樣本Knative服務,該服務的主要職責是接收事件並列印出其內容。
使用以下範例程式碼建立Knative Service。
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: event-display namespace: default spec: template: spec: containers: - image: registry.cn-hangzhou.aliyuncs.com/knative-sample/event-display:v1028
部署Knative Service。
kubectl apply -f event-display.yaml
查看Knative Service是否建立成功。
kubectl get ksvc
預期輸出:
NAME URL LATESTCREATED LATESTREADY READY REASON event-display http://event-display.default.example.com event-display-00001 event-display-00001 True
步驟二:建立Broker和Trigger
在樣本中,建立了一個名為default
的Broker以及一個與之關聯的Triggermy-service-trigger
,後者指定了所有未特別指定處理方式的事件都應轉寄至之前部署的event-display
服務。
建立Broker。
使用以下範例程式碼建立Broker。
apiVersion: eventing.knative.dev/v1 kind: Broker metadata: name: default namespace: default
部署Broker。
kubectl apply -f broker.yaml
查看Broker是否建立成功。
kubectl get broker
預期輸出:
NAME URL AGE READY REASON default http://broker-ingress.knative-eventing.svc.cluster.local/default/default 9s True
輸出結果展示了Broker的基本資料和URL。URLzhi ding le指定了事件應該發送到哪裡。
建立Trigger。
使用以下範例程式碼建立Trigger。
訂閱default Broker並將事件轉寄到event-display服務上。
apiVersion: eventing.knative.dev/v1 kind: Trigger metadata: name: my-service-trigger spec: broker: default subscriber: ref: apiVersion: serving.knative.dev/v1 kind: Service name: event-display
以上代碼建立的
my-service-trigger
與default Broker
關聯,並指定了event-display
服務作為訂閱者。這意味著,任何發送到default Broker
的事件,只要沒有其他特定的Trigger指定處理,都將被轉寄到event-display
服務上。部署Trigger。
kubectl apply -f trigger.yaml
查看Trigger是否建立成功。
kubectl get trigger
預期輸出:
NAME BROKER SUBSCRIBER_URI AGE READY REASON my-service-trigger default http://event-display.default.svc.cluster.local 22s True
輸出結果展示Trigger已經設定成功,並且處於就緒狀態,表明配置正確且能夠接收並路由事件。
步驟三:發送事件並驗證服務是否能夠正常接收事件
從外部直接向Broker發送HTTP POST請求類比事件觸發,然後使用curl
命令發送帶有特定CloudEvents頭資訊的請求到Broker,觀察event-display
服務是否接收到這條訊息,並按預期展示。
從Broker中擷取發送事件請求的地址
broker-ingress.knative-eventing
,通過向Broker發送事件請求,驗證Knative Eventing系統中的Broker服務是否已經正確配置並能夠接收事件。通過kubectl的port-forward功能將叢集內部服務的連接埠轉寄到本地,以訪問服務。
kubectl port-forward svc/broker-ingress -n knative-eventing 8080:80
使用
curl
命令發送一個POST請求到本地的8080連接埠,以驗證服務是否能夠正確接收並處理請求。curl -v "http://localhost:8080/default/default" \ -X POST \ -H "Ce-Id: 536808d3-88be-4077-9d7a-a3f162705f79" \ -H "Ce-Specversion: 1.0" \ -H "Ce-Type: dev.knative.samples.helloworld" \ -H "Ce-Source: dev.knative.samples/helloworldsource" \ -H "Content-Type: application/json" \ -d '{"msg":"Hello World from the curl pod."}'
預期輸出:
Note: Unnecessary use of -X or --request, POST is already inferred. * Trying 127.0.0.1:8080... * Connected to localhost (127.0.0.1) port 8080 (#0) > POST /default/default HTTP/1.1 > Host: localhost:8080 > User-Agent: curl/8.1.2 > Accept: */* > Ce-Id: 53****3-88be-4077-9d7a-a3f162******9 > Ce-Specversion: 1.0 > Ce-Type: dev.knative.samples.helloworld > Ce-Source: dev.knative.samples/helloworldsource > Content-Type: application/json > Content-Length: 40 > < HTTP/1.1 202 Accepted < Allow: POST, OPTIONS < Date: Tue, 15 Oct 2024 09:36:42 GMT < Content-Length: 0 < * Connection #0 to host localhost left intact
預期輸出表明,服務能夠正確地接收到發送到
http://localhost:8080/default/default
的POST請求,並返回了一個202 Accepted
狀態代碼,表明請求已被接受。
查看event-display的Pod日誌,確認事件來源。
擷取event-display Pod的資訊。查看名為event-display的Pod的日誌
kubectl get pods --namespace=default | grep event-display # 輸出結果如下所示: event-display-00001-deployment-766f7b9fd6-gfcz5 2/2 Running 0 3m43s
查看日誌內容。
kubectl logs event-display-00001-deployment-766f7b9fd6-gfcz5 # 日誌輸出結果如下所示: Defaulted container "user-container" out of: user-container, queue-proxy ☁️ cloudevents.Event Context Attributes, specversion: 1.0 type: dev.knative.samples.helloworld source: dev.knative.samples/helloworldsource id: 536808d3-88be-4077-9d7a-a3f162705f79 datacontenttype: application/json Extensions, knativearrivaltime: 2024-10-28T11:48:56.929517041Z Data, { "msg": "Hello World from the curl pod1." }
預期輸出表明,一個運行在Kubernetes上的應用正在接收來自Knative Samples Hello World源的CloudEvents事件,並列印出了這些事件的內容。