到目前為止,向應用程序發送基本的 HTTP 請求是一種有效使用 Knative 函數的方式。然而,無服務器的松耦合特性同時也適用于事件驅動架構。也就是說,可能在文件上傳到 FTP 服務器時我們需要調用一個函數;又或者,在我們進行物品銷售時需要調用一個函數來處理支付和庫存更新的操作。與其操心我們的應用程序或函數監聽上述事件的邏輯,不如當那些被關注的事件發生時,讓 Knative 去處理并通知我們。
如果要自己實現這些功能則需要做很多工作并要編寫實現特定功能的代碼。幸運的是,Knative 提供了一個抽象層使消費事件變得更容易。Knative 直接提供了一個“事件”,而不需要你寫特定的代碼來選擇消息代理。當事件發生時應用程序根本無需關心它來自哪里或發到哪去,就是這么簡單。為實現這一目標,Knative 引入了三個新的概念:Source(源)、Channel(通道)和 Subscription(訂閱)。
如你所料,Source 是事件的來源,它是我們定義事件在何處生成以及如何將事件傳遞給關注對象的方式。例如,Knative 團隊開發了許多開箱即用的源。舉幾個例子:
GCP PubSub (谷歌云發布訂閱)
訂閱 Google PubSub 服務中的主題并監聽消息。
Kubernetes Event (kubernetes 事件)
Kubernetes 集群中發生的所有事件的反饋。
GitHub
監視 GitHub 存儲庫中的事件,諸如版本的 pull 請求,推送和創建發布。
Container Source (容器源)
如果你需要創建自己的事件源,Knative 還有一個抽象---容器源。這允許你輕松創建自定義的事件源,并打包為容器。請參見第六章中的“構建自定義事件源”部分。
雖然這只是當前事件源的子集,但清單在不斷的快速增長。你可以在 Knative Eventing 文檔中的 Knative 生態系統部分查看事件源的當前列表。
讓我們來看一個使用 Kubernetes 事件源并將結果輸出到標準輸出的簡單案例。我們將部署一個運行在 8080 端口上用于監聽 POST 請求并輸出請求結果的函數,如例 4-1 所示。
例4-1: knative-eventhing-demo/app.go
package mainimport ( "fmt" "io/ioutil" "log" "net/http")func handlePost(rw http.ResponseWriter, req *http.Request) { defer req.Body.Close() body, _ := ioutil.ReadAll(req.Body) fmt.Fprintf(rw, "%s", body) log.Printf("%s", body)}func main() { log.Print("Starting server on port 8080...") http.HandleFunc("/", handlePost) log.Fatal(http.ListenAndServe(":8080", nil))}
任何人都可以像我們一樣部署此服務,如例 4-2 所示。
例4-2:knative-eventing-demo/service.yaml
apiVersion: serving.knative.dev/v1alpha1kind: Servicemetadata: name: knative-eventing-demospec: runLatest: configuration: revisionTemplate: spec: container: image: docker.io/gswk/knative-eventing-demo:latest
$ kubectl apply -f knative-eventing-demo/service.yaml
到目前為止,不出意外的話,我們甚至可以像前兩章那樣向該服務發送下面的請求:
$ curl $SERVICE_IP -H "Host: knative-eventing-demo.default.example.com" -XPOST -d "Hello, Eventing"> hello, Eventing
接下來,我們可以設置 Kubernetes 事件源。在配置和身份認證方面,不同的事件源則有不同的要求。例如,GCP PubSub 源則要求向 GCP 進行身份請求驗證。對于 Kubernetes 事件源,則需要創建一個服務帳戶,該帳戶有權讀取到 Kubernetes 集群內發生的事件。就像在第3章中所做的那樣,我們在 YAML 中定義了這個服務帳戶并將其應用到我們的集群,如例 4-3 所示。
例4-3: knative-eventing-demo/serviceaccount.yaml
apiVersion: v1kind: ServiceAccountmetadata: name: events-sa namespace: default---apiVersion: rbac.authorization.k8s.io/v1kind: Rolemetadata: creationTimestamp: null name: event-watcherrules:- apiGroups: - "" resources: - events verbs: - get - list - watch---apiVersion: rbac.authorization.k8s.io/v1kind: RoleBindingmetadata: creationTimestamp: null name: k8s-ra-event-watcherroleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: event-watchersubjects:- kind: ServiceAccount name: events-sa namespace: default
$ kubectl apply -f knative-eventing-demo/serviceaccount.yaml
隨著 events-sa 服務帳戶創建好后,剩下的就是定義我們的實際源,在我們的演示案例中是一個 Kubernetes 事件源實例。該實例將以一個特定的配置運行,在這個演示案例中則是一個預定義的服務帳戶??梢钥吹轿覀兊呐渲萌缡纠?4-4 所示。
例4-4: knative-eventing-demo/source.yaml
apiVersion: sources.eventing.knative.dev/v1alpha1kind: KubernetesEventSourcemetadata: name: k8seventsspec: namespace: default serviceAccountName: events-sa sink: apiVersion: eventing.knative.dev/v1alpha1 kind: Channel name: knative-eventing-demo-channel
其中大部分都相當簡單,我們將創建的對象類型定義為 KubernetesEventSource,簡稱為 k8sevents,并傳遞一些特定實例的配置,例如我們應該運行的 Namespace (命名空間)和使用的 Service Account (服務帳戶)。你可能已經注意到了一個新的東西,即接收器配置。
接收器是定義我們想把事件發送到的目的地和 Kubernetes 對象參考的一種方法?;蛘吒唵蔚卣f,就是一種在 Kubernetes 中尋址到另一個預定義對象的方法。在 Knative 中使用事件源時,這通常是一個服務(如果我們想要將事件直接發送到在 Knative 上運行的應用程序),或者是一個尚未引入的組件——Channel(通道)。
現在我們已經為事件定義了一個源,則需要某個地方來接收它們。雖然你可以將事件直接發送到服務,這也就意味著你可以自己處理重試的邏輯和隊列。當一個事件發送到你的服務并且它恰好關閉時會發生什么?如果要將相同的事件發送到多個服務,又該怎么辦?為了回答這些問題,Knative 引入了 Channel 的概念。
通道處理緩沖和持久性,有助于確保將事件傳遞到其預期的服務,即使該服務已被關閉。另外,Channel 是我們代碼和底層消息傳遞解決方案之間的抽象。這意味著可以像 Kafka 和 RabbitMQ一樣在某些服務之間進行消息交換,但在這兩種情況下我們都不需要編寫特定的實現代碼。繼續我們的演示案例,我們將設置一個用于發送所有事件的通道,如例 4-5 所示。你會注意到此通道與我們在示例 4-4 中的事件源中定義的接收器很像。
例4-5: knative-eventing-demo/channel.yaml
apiVersion: eventing.knative.dev/v1alpha1kind: Channelmetadata: name: knative-eventing-demo-channelspec: provisioner: apiVersion: eventing.knative.dev/v1alpha1 kind: ClusterChannelProvisioner name: in-memory-channel
$ kubectl apply -f knative-eventing-demo/channel.yaml
在這里,我們創建了一個 knative-eventing-demo-channel 的通道,并定義我們想要創建的通道類型,在該演示案例中則是一個 in-memory-channel (內存通道)。正如前面所述,Knative 事件的一個重要目標是它完全從底層基礎架構中抽象出來,這意味著支持可插入通道的消息服務。這是通過 ClusterChannelProvisioner (集群通道提供者)一種用于定義 Knative 應如何與我們的消息傳遞服務進行通信的模式來實現的。我們的演示案列使用了內存通道配置程序,但 Knative 實際上也提供了一些選項來支持我們的通道服務:
in-memory-channe
完全在 Kubernetes 集群的內存中進行處理,不依賴于獨立運行的服務來傳遞事件。非常適合開發,但不建議用于生產環境。
GCP PubSub (谷歌云消息發布訂閱系統)
僅使用 Google PubSub 托管服務來傳遞信息但需要訪問 GCP 帳戶權限。
Kafka (分布式發布訂閱消息系統)
將事件發送到正在運行的 Apache Kafka 集群,這是一個開源的集群分布式流媒體平臺,具有出色的消息隊列功能。
NATS (一個高性能的開源消息系統)
將事件發送到正在運行的 NATS 集群,這是一個高性能的開源消息系統,可以以各種模式和配置傳遞和使用消息。
盡管有了這些選項,但還有一個問題:我們如何實現從通道將事件發送到我們的服務?
我們將事件源發送到通道,并準備好開始處理它們的服務,但目前我們沒有辦法獲取從通道發送到服務的事件。Knative 允許我們給這種情況定義訂閱功能。訂閱是通道和服務之間的紐帶,指示 Knative 如何在整個系統中管理我們的事件。圖 4-1 展示了如何使用訂閱將事件路由到多個應用程序的示例。
圖4-1. 事件源可以將事件發送到通道,以便多個服務可以同時接收它們,或者它們可以直接發送到一個服務
Knative 中的服務不了解或不關心事件和請求是如何獲取的。它可以是來自入口網關的 HTTP 請求,也可以是從通道發送來的事件。無論何種方式,我們的服務僅接收 HTTP 請求。這是 Knative 中一個重要的解耦,它確保我們將代碼編寫到我們的架構中,而不是在于底層。讓我們創建訂閱,它將從我們的通道向我們的服務發送事件。正如示例 4-6 所示,該定義僅使用了兩個引用,一個引用 Channel,另一個引用 Service。
例4-6: knative-eventing-demo/subscription.yaml
apiVersion: eventing.knative.dev/v1alpha1kind: Subscriptionmetadata: name: knative-eventing-demo-subscriptionspec: channel: apiVersion: eventing.knative.dev/v1alpha1 kind: Channel name: knative-eventing-demo-channel subscriber: ref: apiVersion: serving.knative.dev/v1alpha1 kind: Service name: knative-eventing-demo
到此,我們已經準備好了所有的通道,以便可以將事件發送到應用程序上。Kubernetes 會記錄集群中發生的事件,事件源會將其發送到通道再發送到我們的服務,這要歸功于我們定義的訂閱功能。如果我們查看服務中的日志,可立即看到這些事件,如例 4-7 所示。
例4-7: 從服務中檢查日志
$ kubectl get pods -l app=knative-eventing-demo-00001 -o name pod/knative-eventing-demo-00001-deployment-764c8ccdf8-8w782$ kubectl logs knative-eventing-demo-00001-deployment-f4c794667-mcrcv -c user-container2019/01/04 22:46:41 Starting server on port 8080...2019/01/04 22:46:44 {"metadata":{"name":"knative-eventing-demo-00001.15761326c1edda18","namespace":"default"...[Truncated for brevity]
這些構建塊為幫助實現豐富、強大的事件驅動架構鋪平了道路,但這僅僅是個開始。我們將在第六章的“構建自定義事件源”中使用 ContainerSource 創建自定義源。我們還將在第7章中展示事件。
END
本文由 貴州做網站公司 整理發布,部分圖文來源于互聯網,如有侵權,請聯系我們刪除,謝謝!
網絡推廣與網站優化公司(網絡優化與推廣專家)作為數字營銷領域的核心服務提供方,其價值在于通過技術手段與策略規劃幫助企業提升線上曝光度、用戶轉化率及品牌影響力。這...
在當今數字化時代,公司網站已成為企業展示形象、傳遞信息和開展業務的重要平臺。然而,對于許多公司來說,網站建設的價格是一個關鍵考量因素。本文將圍繞“公司網站建設價...
在當今的數字化時代,企業網站已成為企業展示形象、吸引客戶和開展業務的重要平臺。然而,對于許多中小企業來說,高昂的網站建設費用可能會成為其發展的瓶頸。幸運的是,隨...
根據描述上下左右鍵跳舞的游戲? ;游戲的上下左右鍵是超級舞者在線,這是世界 歷時三年獨立開發的首款在線跳舞機游戲。游戲模仿KONAMI s Dance DacneRevolution,和它不同的是它有鍵盤和舞毯兩大模式,還有很多小模式。2005年,發布單機版《超級舞者》,2006年,正式將單機版制作成網絡版。這款游戲的主題是全3D虛擬角色的舞蹈模擬。超級舞者的跳舞毯怎么玩DDR單機游戲?先連接...
冰糖葫蘆歌原唱?《冰糖葫蘆》的原曲是:馮曉泉。這首歌由《冰糖葫蘆》馮曉泉演唱,馮曉泉作曲,張和平和杜鵬作詞。冰糖葫蘆原唱是誰?《糖葫蘆》這首歌的原唱是馮曉泉。馮曉泉,音樂人,滿族,出生于哈爾濱,歌手,國家新銳音樂人。冰糖葫蘆蔡國慶原唱?不,《糖葫蘆》這首歌的原唱是馮曉泉。歌詞:都說糖葫蘆是酸的,酸中裹著甜。都說糖葫蘆是甜的,其實里面是酸的。糖葫蘆掛在竹簽上很好看,象征著幸福和團圓。把幸福和團圓連在...
十堰哪家電腦維修比較好的?石巖的電腦維修集中在柳巖,不同的品牌會去相應的售后服務處,會好一些,其他的會去騙人。十堰萬瑞科技有限公司是做什么的軟件開發;系統集成;網絡工程、智能工程;工業自動化和辦公信息設備的銷售;信息技術和管理咨詢服務;計算機軟硬件銷售及售后服務;電腦配件銷售及維修服務;辦公設備和耗材的銷售。電腦壞了去那里修?1.如果認識的朋友知道,可以打電話問朋友。2.把電腦帶到附近的電腦市場,...