[解讀REST] 4.基於網路應用的架構風格

来源:http://www.cnblogs.com/linianhui/archive/2017/09/24/rest_network-based-software-architecture-style.html
-Advertisement-
Play Games

上篇文章介紹了一組自洽的術語來描述和解釋軟體架構;如何利用架構屬性評估一個架構風格;以及對於基於網路的應用架構來說,那些架構屬性是值得我們重點關註評估的。本篇在以上的基礎上,列舉一下一些常見的(REST除外)的適用於基於網路應用的架構風格,並使用對比架構屬性的方式對其進行評估。 1 架構風格所產生的 ...


上篇文章介紹了一組自洽的術語來描述和解釋軟體架構;如何利用架構屬性評估一個架構風格;以及對於基於網路的應用架構來說,那些架構屬性是值得我們重點關註評估的。本篇在以上的基礎上,列舉一下一些常見的(REST除外)的適用於基於網路應用的架構風格,並使用對比架構屬性的方式對其進行評估。

1 架構風格所產生的架構屬性

架構設計的目的是為了滿足或者超出應用的需求,而不是為了創造出一種特殊的交互拓撲或者一種特殊的設計方式。當設計一個系統時所選擇的架構風格,必須與這些需求保持一致,而不是相抵觸。因此應該依據這些架構風格所產生的架構屬性來對架構風格進行評估。架構屬性是相對的,如果添加以一個架構約束,增強了某一個架構屬性,也可能會消弱另外一個架構屬性;此外,一個架構屬性是被增強了還是被消弱了,也會受到系統實現的的影響。

下麵幾個小節來評估每一種架構風格,以及它們都會產生那些架構屬性。(+)表示增強改善,(-)表示消弱,(±)表示取決於具體的場景。

2 數據流風格(Data Flow Style)

2.1 管道和過濾器(Pipe and Filter = PF)

在PF風格中,每個組件(過濾器)會從輸入端讀取數據,併在輸出端輸出數據(亦可以增量處理,而不必等到全部處理完再交給下一個過濾器)。這裡的架構約束是一個過濾器必須完全獨立於其他的過濾器(零耦合)。多個過濾器這樣頭尾相連組合起來,就像是一個管道,所以稱之為管道和過濾器風格(簡稱PF)。這種風格可以產生如下幾個的架構屬性:

  1. 簡單性(+):可以把過濾器簡單的組合起來。
  2. 可重用性(+):任何兩過濾器都可以鏈接在一起。
  3. 可擴展性(+):可以新增過濾器到已有的系統中。
  4. 可進化性(+):舊的過濾器可以被新的替代,只要其行為不發生變化。
  5. 可配置性(+):PF風格就像有一個看不見的手在組合過濾器的鏈接方式,來調整其整體的行為。
  6. 用戶感知的性能(±):PF天生可以支持併發的執行,所以對此有改善作用。但是如果管道過長,且過濾器不支持增量處理,那麼則可能會增加延遲,降低用戶感知的性能。

具體的例子:比如linux shell,asp.net core中的middleware和filter等。

2.2 統一管道和過濾器(Uniform Pipe and Filter = UPF)

UPF在PF的基礎上,增加了一個所有過濾器都必須具有相同介面的約束。這個約束會在PF的基礎上,產生如下的架構屬性:

  1. 簡單性(++):相同的介面的約束可以進一步增強PF的簡單性。
  2. 可重用性(++):相同的介面的約束可以進一步增強PF的可重用性。
  3. 可配置性(++):相同的介面的約束可以進一步增強PF的可配置性。
  4. 網路性能(-):相同的介面的約束需要對數據的格式做統一的轉換,可能會降低網路的性能。

具體的例子:比如linux的標準輸入輸出流,asp.net core中的middleware也算是(沒有跨越網路)具有相同介面的約束的UPF。

3 複製風格(Replication Style)

3.1 複製倉庫(Replicated Repository = RR)

通過利用多個進程來提供相同的服務,即為RR風格。這些多個分散的服務對於客戶端來說,就好像是只有一個集中的服務。這種風格可以產生如下幾個的架構屬性:

  1. 用戶感知的性能(++):可以明顯的改善用戶感知的性能。
  2. 可伸縮性(+):可以通多增加或減少服務來調整服務的伸縮性。
  3. 可靠性(+):得益於多個分散的服務,當某一個服務宕機之後不會對整體的運行造成多少影響。

具體的例子:比如GIT(分散式的版本管理系統本地有著完整的倉庫副本),CVS(集中式的版本管理系統本地也是有完整的倉庫副本的,只是寫操作是需要網路的)等。

3.2 緩存(Cache = $)

緩存風格是複製倉庫風格的一個變種:複製個別請求的結果,以便被後面的請求復用這些結果。這種風格可以產生如下幾個的架構屬性:

  1. 效率(+):因為某些請求就近即可處理,則可以改進其效率。
  2. 用戶感知的性能(+):改善了效率,則用戶感知的性能亦可得到改善,但是不如複製倉庫風格的改善明顯,畢竟也會有不少的請求沒有命中緩存。
  3. 簡單性(+):由於只是簡單的複製請求結果,實現起來簡單的多,則其具備簡單性的特點。
  4. 可伸縮性(+):降低了到達真正的服務那裡的比例,相當於增強了服務的可伸縮性。

具體的例子:DNS緩存,CDN等。

4 分層風格(Hierarchical Style)

4.1 客戶-伺服器(Client-Server = CS)

伺服器組件提供了一組服務,並監聽對這些服務的請求;客戶端組件通過一個連接器把請求發送給伺服器。伺服器可以拒絕這個請求,也可以執行這個請求,並把響應發送給客戶端。服務端通常來說是一個永不終止的進程,通常是為多個客戶端提供服務的。這個約束背後的原則是分離關註點(但是並不關心會話狀態是在服務端還是客戶端),這種風格可以產生如下幾個的架構屬性:

  1. 簡單性(+):適當的功能分離可以簡化客戶端和服務端組件,使其只關註自身的職責。
  2. 可伸縮性(+):簡化了服務端組件後,從而可以提供服務端組件的可伸縮性。
  3. 可進化性(+):只要通信介面不發生變化,客戶端和服務端組件都可以獨立的升級進化。

具體的例子:RPC等。

4.2 分層系統(Layered System = LS)

按照層次來組織,每一層都使用下層的服務,並且為其上層提供服務。層內部的細節對於相鄰的層而已是完全被隱藏起來的。這種風格可以產生如下幾個的架構屬性:

  1. 可重用性(+):降低了各層之間的耦合,使得每一層都可以被覆用。
  2. 可進化性(+):在上下層介面不變的情況下,每一層都可以獨立進化。
  3. 可移植性(+):每一層得益於只關心其下層是否可用即可被移植,所以對移植性有改善。
  4. 可伸縮性(+):簡化每層組件的實現,有利於提升可伸縮性。
  5. 用戶感知的性能(-):分層處理增加了數據處理的開銷和延遲,會降低用戶感知的性能。

具體的例子:TCP/IP協議,分層的網路協議棧。

4.3 分層-客戶-伺服器(Layered-Client-Server = LCS)

LCS是在LS和CS的結合體。可以理解為在CS的基礎上增加了代理組件和網關組件,對於客戶端而言,代理組件是一個共用伺服器,它接受請求並把它轉發給伺服器。網關組件在客戶端組件和代理組件看來就像是一個正常的伺服器,只是網關組件內部只是將它轉發給了內部的其他伺服器。在CS和LS的基礎上,LCS改善瞭如下的架構屬性:

  1. 可伸縮性(++):可以添加負載均衡或者安全檢查之類的監控,用來提高系統的可伸縮性。
  2. 可進化性(++):得益於增加的網關和代理組件,可以使得客戶端和服務端組件更容易升級部署。

 具體的例子:shadowsocks等。

4.4 客戶-無狀態-伺服器(Client-Stateless-Server = CSS)

在CS的基礎上,增加一個約束:服務端組件上不允許有會話狀態。從客戶端發給的伺服器的每個請求都必須包含理解請求所必須的所有信息,即不能在服務端上保存請求上下文信息(比如上一個請求的信息),會話狀態應該都保存的客戶端。這個約束會在CS的基礎上,產生如下的架構屬性:

  1. 可見性(+):監視系統不必為了確定請求的全部內容而查看多個請求的數據。
  2. 可靠性(+):各自獨立的沒有依賴的請求可以更簡單的從故障中恢復出來。
  3. 可伸縮性(+):服務端不必保存多個請求直接的狀態,從而允許服務端簡化組件的實現並且快速釋放資源。
  4. 網路性能(-):由於服務端不再保存共用的狀態數據,則會使得每次請求都會發送重覆的數據,從而降低網路性能。

具體的例子:大多數桌面(或者APP)應用。

4.5 客戶-緩存-無狀態-伺服器(Client-Cache-Stateless-Server = C$SS)

在CSS的基礎上,增加緩存組件。緩存在客戶端和伺服器直接進行周旋:它可以復用早先的請求,用來響應後面的相同請求,從而避免向原始伺服器發送請求(得到的響應是一樣的)。增加的這個組件可以在CSS的基礎上進一步改善以下的架構屬性:

  1. 效率(+):復用之前的請求結果,避免了額外的網路請求,從而改善了效率。
  2. 用戶感知的性能(+):改善了效率,從而可以提升用戶感知的性能。

具體的例子:SUN的NFS。

4.6 分層-客戶-緩存-無狀態-伺服器(Layered-Client-Cache-Stateless-Server = LC$SS)

合併了LCS和C$SS兩種風格,其產生的架構屬性為LCS和C$SS的組合(但是不會把重覆的CS結算兩次)。

具體的例子:DNS系統。

4.7 遠程會話(Remote Session = RS)

RS是CS的一種變體,它試圖使客戶端組件的複雜性最小化或者使它們的可重用性最大化。每個客戶在伺服器上啟動一個會話,然後調用伺服器的一系列服務,最後退出會話。應用狀態被保存在伺服器上。這種風格可以產生如下幾個的架構屬性:

  1. 簡單性(+):簡化客戶端組件,集中維護服務端組件使得整體更容易維護。
  2. 效率(+):利用伺服器維護了會話上下文信息,可以提升效率。
  3. 可進化性(+):繼承自CS。
  4. 可伸縮性(-):伺服器維護了會話上下文信息,降低了可伸縮性。
  5. 可見性(-):監控程式必須要瞭解整個上下文信息,才能得以監視。

具體的例子:Telnet,SSH。

4.8 遠程數據訪問(Remote Data Access = RDA)

RDA是CS的一種變體,它把應用狀態分佈在客戶端和服務端上。客戶端發送一個標準的數據查詢請求給服務端,服務端分配一個工作空間並執行這個查詢,這可能會產生一個巨大的結果集。客戶端可以在在結果集上進行進一步操作。這就需要客戶端瞭解服務端的數據結構,以便構造依賴該結構的查詢。這種風格可以產生如下幾個的架構屬性:

  1. 效率(+):可以在伺服器上執行多次迭代,逐步縮小一個結果集,從而改善效率。
  2. 可見性(+):標準的數據查詢語言可以改善可見性。
  3. 簡單性(-):客戶端必須像伺服器實現那些理解相同的數據操作概念,因此降低了簡單性。
  4. 可伸縮性(-):在服務端保存應用上下文,降低了可伸縮性。
  5. 可靠性(-):部分的故障會導致工作空間處於未知狀態,也降低了可靠性。儘管可以和事物機制(例如兩階段提交)來修正可靠性的問題,但是其代價則是增加了複雜性和交互的開銷。

具體的例子:SQL。

5 移動代碼風格(Mobile Code Style)

5.1 虛擬機(Virtual Machine = VM)

所有的移動代碼風格的基礎都是VM(或解釋器)風格。VM風格本身並不是基於網路的風格,但是它通常在REV和COD風格中於一個組件結合在一起使用。代碼在一個滿足了安全和可靠性的受控的環境中執行,VM通常被用作腳本語言的引擎,來執行特定的任務。這種風格可以產生如下幾個的架構屬性:

  1. 可擴展性(+):在一個特定的平臺上將指令和實現分離,改善了可擴展性。
  2. 可移植性(+):指令和實現的分離也提高了其可移植性。
  3. 可見性(-):難以通過簡單的查看代碼來瞭解要它們要做什麼事情,從而降低了可見性。
  4. 簡單性(±):需要對指令執行的環境進行關係,則降低了簡單性;但是在一些情況下可以通過簡化靜態功能得到補償。

5.2 遠程求值(Remote Evluation = REV)

REV風格來源於CS+VM風格,客戶端組件必須知道如何執行一個服務,但是缺少執行此服務所必須的資源,而這些資源都位於一個服務端站點上。因此,客戶端組件把如何執行服務的代碼發送給服務端的一個服務端組件,由它來執行代碼,然後把結果返回給客戶端。這種REV會要求被執行的代碼是在一個受保護的環境中,使其不會影響到其他的客戶端。這個約束在CS+VM的基礎上可以產生如下的架構屬性:

  1. 可擴展性(+):可以定製伺服器組件的服務。
  2. 可定製性(+):可以定製伺服器組件的服務。
  3. 效率(+):可執行代碼運行在伺服器端,可以不必通過跨越網路進行多次交互來得到相同的結果,從而可以得到更好的效率。
  4. 可伸縮性(-):服務端對代碼執行環境的管理會降低可伸縮性。
  5. 可靠性(-):服務端管理的代碼執行環境本身會增加一些故障。

具體的例子:redis可以執行lua腳本。

5.3 按需代碼(Code On Demand = COD)

COM風格來源於CS+VM風格(但是又不同於REV),客戶端組件知道如何訪問一組資源,但是不知道如何處理它們。客戶端需要向服務端請求一份可以處理這部分資源的代碼,這部分代碼在客戶端本地執行。這個約束在CS+VM的基礎上可以產生如下的架構屬性:

  1. 可伸縮性(+):可以為已經部署的客戶添加功能。
  2. 可配置性(+):可以為已經部署的客戶添加功能。
  3. 用戶感知的性能(+):如果代碼可以適應客戶端環境,並通過本地的一些交互代替網路交互,則有助於提高用戶感知的性能。
  4. 可伸縮性(-):服務端不在管理代碼的可執行環境,釋放了服務端的壓力,則改善了伺服器的可伸縮性。

具體的例子:瀏覽器中的JS。

5.4 分層-按需代碼-客戶-緩存-無狀態-伺服器(Layered--Code-on-Demand-Client-Cache-Stateless-Server = LCODC$SS)

把COD添加到簽名所說的LC$SS風格上,這時候把代碼被看作是另一種形式的數據元素,因此並不會妨礙LC$SS的優點,同時也會疊加COD的優點。

5.5 移動代理(Mobile Agent = MA)

 MA風格來源於REV+COD。在MA中,一個完整的計算組件,它的狀態,代碼、執行代碼所需的數據都被一起移動到了遠程站點。它是已REV和COM兩種方式同時工作的。

6 點對點風格(Peer-to-Peer Style)

6.1 基於事件的集成(Event-based-integration = EBI)

基於事件集成的風格也被成為隱式調用風格或者事件系統風格。通過消除瞭解連接器介面的標識信息的必要性,它可以降低組件之間的耦合。此架構風格不是之間調用另外一個組件,而是通過一個組件發佈或者廣播一個或多個事件。然後由系統負責調用其他註冊了對這些事件感興趣的組件。這樣的系統一般都會有一個事件匯流排,所有的組件都通過這個匯流排監聽它們各自感興趣的事件。這種風格可以產生如下幾個的架構屬性:

  1. 可進化性(+):可以替換現有的組件而不影響其他的組件。
  2. 可擴展性(+):添加新的監聽組件非常容易。
  3. 可重用性(+):可以使用通用的事件介面和繼承機制。
  4. 可配置性(+):如同PF風格一樣,EBI也有一個看不見的手在配置著整個系統。
  5. 效率(+):基於事件的數據傳遞方式,使得普通的輪詢機制不再需要,從而可以提高效率。
  6. 可伸縮性(--):各組件依賴的事件匯流排是整個系統的瓶頸點:事件的數量,由事件廣播引起的事件風暴等都會損害系統的可伸縮性。
  7. 簡單性(±):可伸縮性的問題可以通過添加分層系統和事件過濾來緩解,但是也會以損害簡單性為代價。
  8. 可見性(-):難以預料一個事件發生後會由什麼樣的結果,缺乏可理解性。
  9. 可靠性(-):不支持大粒度的數據交換,也不支持從局部的故障中恢復。

具體的例子:發佈/訂閱的消息系統。

6.2 C2

C2是EBI和LCS的組合形成的風格。C2在EBI的基礎上,支持大粒度的重用,並通過加強基礎層獨立性來支持系統組件的靈活組合。非同步通知消息向下傳遞,非同步請求消息向上傳遞,這是組件之間通信的唯一方式。這個約束加強了對高層依賴的松耦合(服務請求可以被忽略),並且於底層實現了零耦合(無需知道系統使用了通知),這樣既改善了對整個系統的控制,又沒有喪失EBI的大多數優點。

通知是對於組件中的狀態變化的公告,C2並不會對通知中應該包含什麼內容加以限制。連接器的首要職責是消息的路由和廣播,其次是消息的過濾。引入對於消息的分層過濾,可以解決EBI的可伸縮性的問題,同時改善可進化性和可重用性。

6.3 分散式對象(Distributed Object = DO)

DO是CS和CS的組合。在單獨的CS的風格總,客戶端和服務端是相互獨立的,各自只負責自己的部分。DO則是使一個組件既是客戶端也是服務端。也就是說它既對外提供服務,同時也是服務的消費方。DO組件的內部是完全被隱藏和保護起來的,操作它的唯一辦法是通過它公開的介面進行訪問。一個DO為了要和另外一個DO交互,則必須知道另外一個DO的標識信息,當一個DO的標識信息發生變化的時候,則必須要修改所有顯示調用它的DO。因此必須要又一些控制器對象來負責管理維護系統的狀態。

6.4 被代理的分散式對象(brokered Distributed Object = BDO)

為了降低DO中受到對象標識信息的影響,通常會使用一種或者多種架構風格來輔助通信,比如EBI和被代理的CS風格。這樣的目的在於引入一個名稱解析組件,用來把一個通用的服務的名稱解析為一個能夠滿足該請求的對象的特定名稱,並使用這個特定名稱的對象來處理請求。儘管它改善了可重用性和可進化性,但是額外的間接層會產生一定的網路開銷,從而降低用戶感知的性能。具體的例子:CORBA,ODP。

7 總結

以上的每一種架構風格都在組件之間推崇一種特定的交互類型。當組件跨域廣域網的分佈的時候,應用的可以用就會取決於對於網路的使用或者誤用。通過對已架構風格對於架構屬性的影響來刻畫架構,才能選擇出更適合此類應用的架構設計。

但是以上的評估是有一些局限性的,這裡的評估是特別為分散式超媒體系統的需求量身定做的。比如通信的內容是細粒度的控制信息,那麼PF風格的很多優點就不復存在了;而且如果用戶交互的通信如果是必須的,PF則根本就不適用。同樣的,如果客戶端沒有對請求進行緩存,那麼分層+緩存的風格則只會增加延遲,而不會帶來任何好處。這樣的問題需要針對每一種類型的通信問題進行單獨對比。下麵的表格總結一下上面介紹到的所有的架構風格。

風格 繼承 網路性能 用戶感知的性能 效率 可伸縮性 簡單性 可進化性 可擴展性 可定製性 可配置性 可重用性 可見性 可移植性 可靠性
PF     ±     + + +   + +      
UPF PF - ±     ++ + +   ++ ++ +    
RR     ++   +                 +
$ RR   + + + +                
CS         + + +              
LS     -   +   +       +   +  
LCS CS+LS   -   ++ + ++       +   +  
CSS CS -     ++ + +         +   +
C$SS CSS+$ - + + ++ + +         +   +
LC$SS LCS+C$SS - ± + +++ ++ ++       + + + +
RS CS     + - + +         -    
RDA CS     + - -           +   -
VM           ±   +       - +  
REV CS+VM     + - ±   + +     - + -
COD CS+VM   + + + ±   +   +   -    
LCODC$SS LC$SS+ COD - ++ ++ ++ +±+ ++ +   + + ± + +
MA REV+COD   + ++   ±   ++ + +   - +  
EBI       + -- ± + +   + + -   -
C2 EBI+LCS   - +   + ++ +   + ++ ± + ±
DO CS+CS -   +     + +   + + -   -
BDO DO+LCS - -       ++ +   + ++ - +  

做了4篇博客的前期準備工作,下一篇就開始介紹什麼是REST了。以上 如有錯誤之處,歡迎指正!

參考資料

理解本真的REST:http://www.infoq.com/cn/articles/understanding-restful-style/

架構風格與基於網路的軟體架構設計-導讀:http://www.infoq.com/cn/articles/doctor-fielding-article-review

架構風格與基於網路的軟體架構設計:http://www.infoq.com/cn/minibooks/web-based-apps-archit-design


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 微服務里一個重要的概念就是服務註冊與發現技術,當你有一個新的服務運行後,我們的服務中心可以感知你,然後把加添加到服務列表裡,然後當你死掉後,會從服務中心把你移除,而你作為一個服務,對其它服務公開的只是服務名稱,而不是最終的服務地址URL,這對於雲平臺,容器化架構來說是非常重要的! 一 安裝單獨的Eu ...
  • 1.類圖 UML類圖是用來描述類、介面、協作及它們之間的關係的圖。用來顯示系統中各個類的靜態結構。 2.類圖的組成元素 類圖由以下六種元素組成:類,介面,泛化關係,關聯關係,依賴關係,實現關係。 3.類圖的繪製 3.1類圖的表示法 類的UML表示為一個長方形垂直分為三個部分:頂部為類的名稱部分,中間 ...
  • Redis是一個key value存儲系統,現在在各種系統中的使用越來越多,大部分情況下是因為其高性能的特性,被當做緩存使用,這裡介紹下Redis經常遇到的使用場景。 Redis特性 一個產品的使用場景肯定是需要根據產品的特性,先列舉一下Redis的特點: 讀寫性能優異 持久化 數據類型豐富 單線程 ...
  • GOF《設計模式》一書中提出了七條設計原則,七原則是一種理想狀態的表達,但實際項目開發中可能會不得不打破這些原則的限制。任何基類可以出現的地方,子類一定可以出現,且必須遵從基類所有規則定義,但反過來說,除了擴展基類,我們又為什麼要違背基類規則定義呢?這一條與開關原則結合起來理解就是,基類遵循關原則,... ...
  • 什麼是單例模式? 從“單例”字面意思上理解為——一個類只有一個實例,所以單例模式也就是保證一個類只有一個實例的一種實現方法罷了。其官方定義為:確保一個類只有一個實例,並提供一個全局訪問點。 為什麼會有單例模式? 從單例模式的定義中我們可以看出——單例模式的使用自然是當我們的系統中某個對象只需要一個實 ...
  • 工具: MyEclipse,MySQL 步驟: 1.打開MyEclipse,新建一個Java Project(取名:h1) 2.創建MySQL資料庫 3.找到MyEclipse下的MyEclipse Hibernate單擊 會出現以下界面,按照如下方式填寫鏈接資料庫 4.選中項目名,添加Hibern ...
  • HTTP協議 客戶機與服務端之間的數據交互需要遵守一定的約定,比如協議版本,數據類型,是否有緩存,是否有壓縮等,只有在這些約定的基礎上才能相互之間愉快的工作。 Netty通信過程中的編解碼 這時說的是基於TCP/IP的Netty之間的通信。TCP/IP協議下客戶端與服務端之間要進行數據交互,一般需要 ...
  • Ninject 3.3 beta1 has gone live. This release mainly focus on bug fix and platform update. Support .NET Standard 2.0 Since version 3.3, Ninject starts ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...