您现在的位置是:Instagram刷粉絲, Ins買粉絲自助下單平台, Ins買贊網站可微信支付寶付款 > 

01 java事件發布訂閱(SpringBoot內置生命周期事件詳解 SpringBoot源碼(十))

Instagram刷粉絲, Ins買粉絲自助下單平台, Ins買贊網站可微信支付寶付款2024-05-16 22:39:20【】4人已围观

简介如何構建并在云上部署基于JAVA的RESTService?應用的架構Dustin.Whittle給出了云應用的示例架構,它具有高度的可擴展性,如下圖所示:在這個圖中,應用按照分層的理念進行了拆分,分別

如何構建并在云上部署基于JAVA的REST Service?

應用的架構

Dustin.Whittle給出了云應用的示例架構,它具有高度的可擴展性,如下圖所示:

在這個圖中,應用按照分層的理念進行了拆分,分別介紹如下:

客戶端層:客戶端層包含了針對目標平臺的用戶界面,可能會包括基于Web的、移動端的甚至是胖客戶端的用戶界面。一般來講,這可能會是Web應用,包含諸如用戶管理、會話管理、頁面構建等功能,但是其他客戶端所發起的交互都需要以RESTful服務的形式調用服務器。

服務:服務器包含了緩存服務以及聚合(aggregate)服務,其中緩存服務中持有記錄系統(system of re買粉絲rd)中最新的已知狀態,而聚集服務會直接與記錄系統交互,并且會執行一些破壞性的操作(會改變記錄系統中的狀態)。

記錄系統:記錄系統是領域特定的服務端,它會驅動業務功能,可能會包括客戶管理系統、采購系統、預定系統等等,這些很可能是遺留系統,你的應用需要與其進行交互。聚集服務要負責將你的應用從這些特有的記錄系統中抽象出來,并為你的應用提供一致的前端接口。

ESB:當記錄系統發生數據變化的時候,它需要觸發到指定主題(topic)的事件,這就是事件驅動架構(event-driven architecture,EDA)能夠影響應用的地方了:當記錄系統進行了一項其他系統可能感興趣的變更時,它會觸發一個事件,任何關注記錄系統的其他系統會監聽到這個事件,并作出對應的響應。這也是使用使用主題(topic)而不是隊列(queue)的原因:隊列支持點對點(point-to-point)的消息,而主題支持發布-訂閱(publish-subscribe)的消息或事件。當與遺留系統進行集成時,我們很期望這些遺留的系統能夠免遭負載的影響。因此,我們實現了一個緩存系統,這個緩存系統維持了記錄系統中所有最新的已知狀態。緩存系統會使用EDA的規則監聽記錄系統的變化,它會更新自己所保存數據的版本,從而保證與記錄系統中的數據相匹配。這是一個很強大的策略,不過會將一致性模型變為最終一致性,也就是說如果你在社交媒體上發布一條狀態的話,你的朋友可能在幾秒鐘甚至幾分鐘之后才能看到,數據最終是一致的,但有時你所看到的與你的朋友所看到的并不一致。如果能接受這種一致性的話,就能在很大程度上實現可擴展性的收益。

NoSQL:在數據存儲方面,有很多的可選方案,但如果要存儲大量數據的話,使用NoSQL存儲能夠更容易地擴展。有多種NoSQL存儲可供選擇,不過這要匹配所存儲數據的特點,如MongoDB適合存儲可搜索的數據,Neo4j適合存儲高度互相關聯的數據,而Cassandra適合存儲鍵/值對,像Solr這樣的搜索索引有利于加速對經常訪問數據的查詢。

部署到云端

前面介紹了基于云的應用架構,接下來作者闡述了這樣的應用該如何部署到云端。

RESTful Web服務要部署到Web容器中,并且要位于數據存儲之前。這些Web服務是沒有狀態的,只會反映其暴露的底層數據的狀態,因此可以根據需要部署任意數量的服務器。在基于云的部署中,開始時可以開啟足夠的實例以應對日常的需求,然后配置彈性策略,從而根據負載增加或減少服務器的數量。衡量飽和度的最好指標就是服務的響應時間。另外還需要考慮這些服務所使用的底層數據存儲的性能。示例的部署圖如下所示:

如果在云部署時有EDA的需求,那么就需要部署ESB,作者給出的建議是根據功能對ESB進行分區(partitioning),這樣一個segment的過大負載不會影響到其他的segment。如下圖所示:

這種分離使System 1的負載與System 2的負載實現了隔離。如果System 1產生的負載拖慢了ESB,它只會影響到自己的segment,并不會影響到System 2的segment,因為它部署在其他硬件上。如果ESB產品支持的話,我們還可以給指定的segment添加服務器來實現擴展。

基于云的應用與傳統應用有著很大的差別,因為它有著不同的擴展性需求。基于云的應用必須有足夠的彈性以應對服務器的添加與移除,必須松耦合,必須盡可能的無狀態,必須預先規劃失敗的情況,并且必須能夠從幾臺服務器擴展到成千上萬臺服務器。

針對云應用并沒有唯一正確的架構,但是本文所闡述的RESTful服務以及事件驅動架構卻是經過實踐檢驗有效的架構。作者認為REST和EDA是實現云端可擴展應用的基本工具。

目前,國內許多傳統的軟件廠商正在逐漸往云端遷移,希望本文所闡述的架構理念能夠為讀者提供一些借鑒。

SpringBoot內置生命周期事件詳解 SpringBoot源碼(十)

SpringBoot中文注釋項目Github地址:

買粉絲s://github.買粉絲/yuanmabiji/spring-boot-2.1.0.RELEASE

本篇接 SpringBoot事件監聽機制源碼分析(上) SpringBoot源碼(九)

溫故而知新,我們來簡單回顧一下上篇的內容,上一篇我們分析了 SpringBoot啟動時廣播生命周期事件的原理 ,現將關鍵步驟再濃縮總結下:

上篇文章的側重點是分析了SpringBoot啟動時廣播生命周期事件的原理,此篇文章我們再來詳細分析SpringBoot內置的7種生命周期事件的源碼。

分析SpringBoot的生命周期事件,我們先來看一張類結構圖:

由上圖可以看到事件類之間的關系:

EventObject 類是JDK的事件基類,可以說是所有Java事件類的基本,即所有的Java事件類都直接或間接繼承于該類,源碼如下:

可以看到 EventObject 類只有一個屬性 source ,這個屬性是用來記錄最初事件是發生在哪個類,舉個栗子,比如在SpringBoot啟動過程中會發射 ApplicationStartingEvent 事件,而這個事件最初是在 SpringApplication 類中發射的,因此 source 就是 SpringApplication 對象。

ApplicationEvent 繼承了DK的事件基類 EventObject 類,是Spring的事件基類,被所有Spring的具體事件類繼承,源碼如下:

可以看到 ApplicationEvent 有且僅有一個屬性 timestamp ,該屬性是用來記錄事件發生的時間。

SpringApplicationEvent 類繼承了Spring的事件基類 ApplicationEvent ,是所有SpringBoot內置生命周期事件的父類,源碼如下:

可以看到 SpringApplicationEvent 有且僅有一個屬性 args ,該屬性就是SpringBoot啟動時的命令行參數即標注 @SpringBootApplication 啟動類中 main 函數的參數。

接下來我們再來看一下 SpringBoot 內置生命周期事件即 SpringApplicationEvent 的具體子類們。

SpringBoot開始啟動時便會發布 ApplicationStartingEvent 事件,其發布時機在環境變量Environment或容器ApplicationContext創建前但在注冊 ApplicationListener 具體監聽器之后,標志標志 SpringApplication 開始啟動。

可以看到 ApplicationEnvironmentPreparedEvent 事件多了一個 environment 屬性,我們不妨想一下,多了 environment 屬性的作用是啥?

答案就是 ApplicationEnvironmentPreparedEvent 事件的 environment 屬性作用是利用事件發布訂閱機制,相應監聽器們可以從 ApplicationEnvironmentPreparedEvent 事件中取出 environment 變量,然后我們可以為 environment 屬性增加屬性值或讀出 environment 變量中的值。

當SpringApplication已經開始啟動且環境變量 Environment 已經創建后,并且為環境變量 Environment 配置了命令行和 Servlet 等類型的環境變量后,此時會發布 ApplicationEnvironmentPreparedEvent 事件。

監聽 ApplicationEnvironmentPreparedEvent 事件的第一個監聽器是 ConfigFileApplicationListener ,因為是 ConfigFileApplicationListener 監聽器還要為環境變量 Environment 增加 application.properties 配置文件中的環境變量;此后還有一些也是監聽 ApplicationEnvironmentPreparedEvent 事件的其他監聽器監聽到此事件時,此時可以說環境變量 Environment 幾乎已經完全準備好了。

可以看到 ApplicationContextInitializedEvent 事件多了個 ConfigurableApplicationContext 類型的 買粉絲ntext 屬性, 買粉絲ntext 屬性的作用同樣是為了相應監聽器可以拿到這個 買粉絲ntext 屬性執行一些邏輯,具體作用將在 3.4.4 詳述。

ApplicationContextInitializedEvent 事件在 ApplicationContext 容器創建后,且為 ApplicationContext 容器設置了 environment 變量和執行了 ApplicationContextInitializers 的初始化方法后但在bean定義加載前觸發,標志ApplicationContext已經初始化完畢。

同樣可以看到 ApplicationPreparedEvent 事件多了個 ConfigurableApplicationContext 類型的 買粉絲ntext 屬性,多了 買粉絲ntext 屬性的作用是能讓監聽該事件的監聽器們能拿到 買粉絲ntext 屬性,監聽器拿到 買粉絲ntext 屬性一般有如下作用:

ApplicationPreparedEvent 事件在 ApplicationContext 容器已經完全準備好時但在容器刷新前觸發,在這個階段 bean 定義已經加載完畢還有 environment 已經準備好可以用了。

ApplicationStartedEvent 事件將在容器刷新后但 ApplicationRunner 和 CommandLineRunner 的 run 方法執行前觸發,標志 Spring 容器已經刷新,此時容器已經準備完畢了。

ApplicationReadyEvent 事件在調用完 ApplicationRunner 和 Co

很赞哦!(8779)

Instagram刷粉絲, Ins買粉絲自助下單平台, Ins買贊網站可微信支付寶付款的名片

职业:程序员,设计师

现居:新疆巴音郭楞且末县

工作室:小组

Email:[email protected]