微服務從設計到部署(三)進程間通信

来源:http://www.cnblogs.com/oopsguy/archive/2017/09/04/7472238.html
-Advertisement-
Play Games

在單體應用程式中,組件可通過語言級方法或者函數相互調用。相比之下,基於微服務的應用程式是一個運行在多台機器上的分散式系統。通常,每個服務實例是一個進程。因此,服務必須使用進程間通信(IPC)機制進行交互。稍後我們將瞭解到多種 IPC 技術,但在此之前,我們先來探討一下涉及到的各種設計問題。 ...


鏈接https://github.com/oopsguy/microservices-from-design-to-deployment-chinese
譯者Oopsguy

本書的第三章主要是關於使用微服務架構構建應用程式。第一章介紹了微服務架構模式,將其與單體架構模式進行對比,並討論了使用微服務的優點和缺點。第二章描述了應用程式客戶端通過扮演中間人角色的 API 網關與微伺服器進行通信。在本章中,我們來瞭解一下系統中的服務是如何相互通信的。第四章將詳細探討服務發現方面的內容。

3.1、簡介

在單體應用程式中,組件可通過語言級方法或者函數相互調用。相比之下,基於微服務的應用程式是一個運行在多台機器上的分散式系統。通常,每個服務實例是一個進程。

因此,如圖 3-1 所示,服務必須使用進程間通信(IPC)機制進行交互。

稍後我們將瞭解到多種 IPC 技術,但在此之前,我們先來探討一下涉及到的各種設計問題。

使用進程間通信交互的微服務

3.2、交互方式

當為服務選擇一種 IPC 機制時,首先需要考慮服務如何交互。有很多種客戶端-服務交互方式。它們可以分為兩個類。第一類是一對一交互與一對多交互:

  • 一對一 - 每個客戶端請求都由一個服務實例處理。
  • 一對多 - 每個請求由多個服務實例處理。

第二類是同步交互與非同步交互:

  • 同步 - 客戶端要求服務及時響應,在等待過程中可能會發生阻塞。
  • 非同步 - 客戶端在等待響應時不會發生阻塞,但響應(如果有)不一定立即返回。

下表展示了各種交互方式。

- 一對一 一對多
同步 請求/響應 -
非同步 通知 發佈/訂閱
非同步 請求/非同步響應 發佈/非同步響應

表 3-1、進程間通信方式

一對一交互分為以下列舉的類型,包括同步(請求/響應)和非同步(通知與請求/非同步響應):

  • 請求/響應 - 客戶端向服務發出請求並等待響應。客戶端要求響應及時到達。在基於線程的應用程式中,發出請求的線程可能在等待時發生阻塞。
  • 通知(又名單向請求) - 客戶端向服務發送請求,但不要求響應。
  • 請求/非同步響應 - 客戶端向服務發送請求,服務非同步響應。客戶端在等待時不發生阻止,適用於假設響應可能不會立即到達的場景。

一對多交互可分為以下列舉的類型,它們都是非同步的:

  • 發佈/訂閱 - 客戶端發佈通知消息,由零個或多個感興趣的服務消費。
  • 發佈/非同步響應 - 客戶端發佈請求消息,然後等待一定時間來接收消費者的響應。

通常,每個服務都組合著使用這些交互方式。對於一些服務,單一的 IPC 機制就足夠了,但其他服務可能需要組合多個 IPC 機制。

圖 3-2 顯示了當用戶請求打車時,打車應用中的服務可能會發生交互。

使用了多種 IPC 機制的服務交互

服務使用了通知、請求/響應和發佈/訂閱組合。例如,乘客的智能手機向 Trip Management 微服務發送一條通知以請求一輛車。Trip Management 服務通過使用請求/響應來調用 Passenger Management 服務以驗證乘客的帳戶是否可用。之後,Trip Management 服務創建路線,並使用發佈/訂閱通知其他服務,包括用於定位可用司機的 Dispatcher。

現在我們來看一下交互方式,我們先來看看如何定義 API。

3.3、定義 API

服務 API 是服務與客戶端之間的契約。無論您選擇何種 IPC 機制,使用介面定義語言(interface definition language,IDL)嚴格定義服務 API 都是非常有必要的。有論據證明使用 API 優先(API‑first)法定義服務更加合適。在對您需要實現的服務的 API 定義進行迭代之後,您可以通過編寫介面定義並與客戶端開發人員進行審閱來開始開發服務。這樣設計可以增加您構建出符合客戶端需求的服務的機率。

正如您將會在後面看到,定義 API 的方式取決於您使用何種 IPC 機制。如果您正在使用消息傳遞,則 API 由消息通道和消息類型組成。如果您使用的是 HTTP,則 API 由 URL、請求和響應格式組成。稍後我們將詳細地介紹關於 IDL 方面的內容。

3.4、演化 API

服務 API 總是隨著時間而變化。在單體應用程式中,更改 API 和更新所有調用者通常是一件直截了當的事。但在基於微服務的應用程式中,即使您的 API 的所有消費者都是同一應用程式中的其他服務,要想完成這些工作也是非常困難的。通常,您無法強制所有客戶端與服務升級的節奏一致。此外,您可能需要逐步部署新版本服務,以便新舊版本的服務同時運行。制定這些問題的處理策略還是很重要的。

處理 API 變更的方式取決於變更的程度。某些更改是次要或需要向後相容以前的版本。例如,您可能會向請求或響應添加屬性。這時設計客戶與服務時遵守魯棒性原則就顯得很有意義了。使用較舊 API 的客戶端應繼續使用新版本的服務。該服務為缺少的請求屬性提供預設值,並且客戶端忽略任何多餘的響應屬性。使用 IPC 機制和消息格式非常重要,可以讓您輕鬆地演化 API。

但有時候,您必須對 API 作出大量不相容的更改。由於您無法強制客戶端立即升級,服務也必須支持較舊版本的 API 一段時間。如果您使用了基於 HTTP 的機制(如 REST),則一種方法是將版本號嵌入 URL 中。每個服務實例可能同時處理多個版本。或者,您可以部署多個不同的實例,每個實例用於處理特定版本。

3.5、處理局部故障

正如第二章中關於 API 網關所述,在分散式系統中存在局部故障風險。由於客戶端進程與服務進程是分開的,服務可能無法及時響應客戶端的請求。由於故障或者維護,服務可能需要關閉。也有可能因服務過載,造成響應速度變得極慢。

例如,請回想第二章中的產品詳細信息場景。我們假設 Recommendation Service 沒有響應。客戶端天真般的實現可能會無限期地阻塞以等待響應。這不僅會導致用戶體驗糟糕,而且在許多應用程式中,它將消耗如線程之類等寶貴資源。以致最終,在運行時將線程用完,造成無法響應,如圖 3-3 所示。

因無響應服務引起的線程阻塞

為了防止這個問題出現,您必須設計您的服務以處理局部故障。以下是一個由 Netflix 給出的好方法。處理局部故障的策略包括:

  • 網路超時 - 在等待響應時,不要無限期地阻塞,始終使用超時方案。使用超時方案確保資源不被無限地消耗。
  • 限制未完成的請求數量 - 對客戶端擁有特定服務的未完成請求的數量設置上限。如果達到了上限,發出的額外請求可能是毫無意義的,因此這些嘗試需要立即失敗。
  • 斷路器模式 - 追蹤成功和失敗請求的數量。如果錯誤率超過配置閾值,則斷開斷路器,以便後續的嘗試能立即失敗。如果出現大量請求失敗,則表明服務不可用,發送請求將是無意義的。發生超時後,客戶端應重新嘗試,如果成功,則關閉斷路器。
  • 提供回退 - 請求失敗時執行回退邏輯。例如,返回緩存數據或者預設值,如一組空白的推薦數據。

Netflix Hystrix 是一個實現上述和其他模式的開源庫。如果您正在使用 JVM,那麼您一定要考慮使用 Hystrix。如果您在非 JVM 環境中運行,則應使用相等作用的庫。

3.6、IPC 技術

有多種 IPC 技術可供選擇。服務可以使用基於同步請求/響應的通信機制,比如基於 HTTP 的 REST 或 Thrift。或者,可以使用非同步、基於消息的通信機制,如 AMQP 或 STOMP。

還有各種不同的消息格式。服務可以使用人類可讀的、基於文本的格式,如 JSON 或 XML。或者,可以使用如 Avro 或 Protocol Buffers 等二進位格式(更加高效)。稍後我們將討論同步 IPC 機制,但在此之前讓我們先來討論一下非同步 IPC 機制。

3.7、非同步、基於消息的通信

當使用消息傳遞時,進程通過非同步交換消息進行通信。客戶端通過發送消息向服務發出請求。如果服務需要回覆,則通過向客戶端發送一條單獨的消息來實現。由於通信是非同步的,因此客戶端不會阻塞等待回覆。相反,客戶端被假定不會立即收到回覆。

一條消息由頭部(如發件人之類的元數據)和消息體組成。消息通過通道進行交換。任何數量的生產者都可以向通道發送消息。類似地,任何數量的消費者都可以從通道接收消息。有兩種通道類型,分別是點對點(point‑to‑point)與發佈訂閱(publish‑subscribe):

  • 點對點通道發送一條消息給一個切確的、正在從通道讀取消息的消費者。服務使用點對點通道,就是上述的一對一交互方式。
  • 發佈訂閱通道將每條消息傳遞給所有訂閱的消費者。服務使用發佈訂閱通道,就是上述的一對多交互方式。

圖 3-4 展示了打車應用程式如何使用發佈訂閱通道。

使用了發佈-訂閱通道的打車應用

Trip Management 服務通過向發佈訂閱通道寫入 Trip Created 消息來通知已訂閱的服務,如 Dispatcher。 Dispatcher 找到可用的司機並通過向發佈訂閱通道寫入 Driver Proposed 消息來通知其他服務。

有許多消息系統可供選擇。您應該選擇一個支持多種編程語言的。

一些消息系統支持標準協議,如 AMQP 和 STOMP。其他消息系統有專有的文檔化協議。

有大量的開源消息系統可供選擇,包括 RabbitMQApache KafkaApache ActiveMQNSQ。在高層上,他們都支持某種形式的消息和通道。他們都力求做到可靠、高性能和可擴展。然而,每個代理的消息傳遞模型細節上都存在著很大差異。

使用消息傳遞有很多優點:

  • 將客戶端與服務分離 - 客戶端通過向相應的通道發送一條消息來簡單地發出一個請求。服務實例對客戶端而言是透明的。客戶端不需要使用發現機制來確定服務實例的位置。
  • 消息緩衝 - 使用如 HTTP 的同步請求/響應協議,客戶端和服務在交換期間必須可用。相比之下,消息代理會將消息寫入通道入隊,直到消費者處理它們。這意味著,例如,即使訂單執行系統出現緩慢或不可用的情況,線上商店還是可以接受客戶的訂單。訂單消息只需要簡單地排隊。
  • 靈活的客戶端-服務交互 - 消息傳遞支持前面提到的所有交互方式。
  • 毫無隱瞞的進程間通信 - 基於 RPC 的機制試圖使調用遠程服務看起來與調用本地服務相同。然而,由於物理因素和局部故障的可能性,他們實際上是完全不同的。消息傳遞使這些差異變得非常明顯,所以開發人員不會被這些虛假的安全感所欺騙。

然而,消息傳遞也存在一些缺點:

  • 額外的複雜操作 - 消息傳遞系統是一個需要安裝、配置和操作的系統組件。消息代理程式必須高度可用,否則系統的可靠性將受到影響。
  • 實施基於請求/響應的交互的複雜性 - 請求/響應式交互需要做些工作來實現。每個請求消息必須包含應答通道標識符和相關標識符。該服務將包含相關 ID 的響應消息寫入應答通道。客戶端使用相關 ID 將響應與請求相匹配。通常使用直接支持請求/響應的 IPC 機制更加容易。

現在我們已經瞭解了使用基於消息的 IPC,讓我們來看看請求/響應的 IPC。

3.8、同步的請求/響應 IPC

當使用基於同步、基於請求/響應的 IPC 機制時,客戶端向伺服器發送請求。該服務處理該請求並返迴響應。

在許多客戶端中,請求的線程在等待響應時被阻塞。其他客戶端可能會使用非同步、事件驅動的客戶端代碼,這些代碼可能是由 FuturesRx Observables 封裝的。然而,與使用消息傳遞不同,客戶端假定響應能及時到達。

有許多協議可供選擇。有兩種流行協議分別是 REST 和 Thrift。我們先來看一下 REST。

3.8.1、REST

如今,開發 RESTful 風格的 API 是很流行的。REST 是一種使用了 HTTP (幾乎總是)的 IPC 機制。

資源是 REST 中的一個關鍵概念,它通常表示業務對象,如客戶、產品或這些業務對象的集合。REST 使用 HTTP 動詞(謂詞)來操縱資源,這些資源通過 URL 引用。例如,GET 請求返回一個資源的表示形式,可能是 XML 文檔或 JSON 對象形式。POST 請求創建一個新資源,PUT 請求更新一個資源。

引用 REST 創建者 Roy Fielding:

“REST 提供了一套架構約束,當作為整體應用時,其強調組件交互的可擴展性、介面的通用性、組件的獨立部署以及中間組件,以減少交互延遲、實施安全性和封裝傳統系統。” - Roy Fielding,《架構風格與基於網路的軟體架構設計》

圖 3-5 展示了打車應用程式可能使用 REST 的方式之一。

使用了 RESTful 交互的打車應用

乘客的智能手機通過向 Trip Management 服務的 /trips 資源發出一個 POST 請求來請求旅程。該服務通過向 Passenger Management 服務發送一個獲取乘客信息的 GET 請求來處理該請求。在驗證乘客被授權創建旅程後,Trip Management 服務將創建旅程,並向智能手機返回 201 響應。

許多開發人員聲稱其基於 HTTP 的 API 就是 RESTful。然而,正如 Fielding 在這篇博文中所描述的那樣,並不是所有的都是這樣。

Leonard Richardson 定義了一個非常有用的 REST 成熟度模型,包括以下層次:

  • 級別 0 - 級別 0 的 API 的客戶端通過向其唯一的 URL 端點發送 HTTP POST 請求來調用該服務。每個請求被指定要執行的操作、操作的目標(如業務對象)以及參數。
  • 級別 1 - 級別 1 的 API 支持資源概念。要對資源執行操作,客戶端會創建一個 POST 請求,指定要執行的操作和參數。
  • 級別 2 - 級別 2 的 API 使用 HTTP 動詞(謂詞)執行操作:使用 GET 檢索、使用 POST 創建和使用 PUT 進行更新。請求查詢參數和請求體(如果有)指定操作的參數。這使服務能夠利用 Web 基礎特性,如緩存 GET 請求。
  • 級別 3級 - 級別 3 的 API 基於非常規命名原則設計,HATEOAS(超文本作為應用程式狀態引擎)。基本思想是 GET 請求返回的資源的表示,包含用於執行該資源上允許的操作的鏈接。例如,客戶端可以使用發送 GET 請求檢索訂單返回的訂單響應中的鏈接來取消訂單。HATEOAS 的一個好處是不再需要將 URL 硬編碼在客戶端代碼中。另一個好處是,由於資源的表示包含可允許操作的鏈接,所以客戶端不必猜測可以對當前狀態的資源執行什麼操作。

使用基於 HTTP 的協議有很多好處:

  • HTTP 簡單易懂。
  • 您可以使用瀏覽器中的擴展(如 Postman)測試 HTTP API,或者使用 curl 命令行測試 HTTP API(假設使用了 JSON 或其他一些文本格式)。
  • 它直接支持請求/響應式通信。
  • HTTP 是防火牆友好。
  • 它不需要中間代理,簡化了系統架構。

使用 HTTP 也存在一些缺點:

  • HTTP 僅直接支持請求/響應的交互方式。您可以使用 HTTP 進行通知,但伺服器必須始終發送 HTTP 響應。
  • 因為客戶端和服務直接通信(沒有一個中間者來緩衝消息),所以它們必須在交換期間都運行。
  • 客戶端必須知道每個服務實例的位置(即 URL)。如第二章關於 API 網關所述,這是現代應用程式中的一個不簡單的問題。客戶端必須使用服務發現機制來定位服務實例。

開發人員社區最近重新發現了 RESTful API 介面定義語言的價值。有幾個可以選擇,包括 RAMLSwagger。一些 IDL(如 Swagger)允許您定義請求和響應消息的格式。其他如 RAML,需要您使用一個單獨的規範,如 JSON 模式。除了用於描述 API 之外,IDL 通常還具有可從介面定義生成客戶端 stub 和伺服器 skeleton 的工具。

3.8.2、Thrift

Apache Thrift 是 REST 的一個有趣的替代方案。它是一個用於編寫跨語言 RPC 客戶端和伺服器 skeleton。Thrift 提供了一個 C 風格的 IDL 來定義您的 API。您可以使用 Thrift 編譯器生成客戶端存根和伺服器端骨架。編譯器可以生成各種語言的代碼,包括 C++、Java、Python、PHP、Ruby、Erlang 和 Node.js。

Thrift 介面由一個或多個服務組成。一個服務定義類似於一個 Java 介面。它是強類型方法的集合。Thrift 方法可以返回一個(可能為 void)值,或者如果它們被定義為單向,則不會返回值。返回值方法實現了請求/響應的交互方式,客戶端等待響應,並可能會拋出異常。單向方式對應通知互動方式,伺服器不發送響應。

Thrift 支持多種消息格式:JSON,二進位和壓縮二進位。二進位比 JSON 更有效率,因為其解碼速度更快。而且,顧名思義,壓縮二進位是一種節省空間的格式。當然,JSON 是人性化和瀏覽器友好的。Thrift 還為您提供了包括原始 TCP 和 HTTP 在內的傳輸協議選擇。原始 TCP 可能比 HTTP 更有效率。然而,HTTP 是防火牆友好的、瀏覽器友好的和人性化的。

3.9、消息格式

我們已經瞭解了 HTTP 和 Thrift,現在讓我們來看看消息格式的問題。如果您使用的是消息系統或 REST,則可以選擇您的消息格式。其他 IPC 機制如 Thrift 可能只支持少量的消息格式,甚至只支持一種。在任一種情況下,使用跨語言消息格式就顯得非常重要了。即使您現在是以單一語言編寫您的微服務,您將來也可能會使用到其他語言。

有兩種主要的消息格式:文本和二進位。基於文本格式的例子有 JSON 和 XML。這些格式的優點在於,它們不僅是人類可讀的,而且是自描述的。在 JSON 中,對象的屬性由鍵值對集合表示。類似地,在 XML 中,屬性由命名元素和值表示。這使得消息消費者能夠挑選其感興趣的值並忽略其餘的值。因此,可以輕鬆地向後相容作出微小更改的消息格式。

XML 文檔的結構由 XML 模式(schema)指定。隨著時間的推移,開發人員社區已經意識到 JSON 也需要一個類似的機制。一個選擇是使用 JSON Schema,獨立或作為 IDL 的一部分,如 Swagger。

使用基於文本的消息格式的缺點是消息往往是冗長的,特別是 XML。因為消息是自描述的,每個消息除了它們的值之外還包含屬性的名稱。另一個缺點是解析文本的開銷。因此,您可能需要考慮使用二進位格式。

有幾種二進位格式可供選擇。如果您使用的是 Thrift RPC,您可以使用二進位 Thrift。如果您選擇的消息格式,包括了流行的 Protocol BuffersApache Avro。這兩種格式都提供了一種用於定義消息結構的類型 IDL。然而,一個區別是 Protocol Buffers 使用標記欄位,而 Avro 消費者需要知道模式才能解釋消息。因此,Protocol Buffers 的 API 演化比 Avro 更容易使用。這裡有篇博文對 Thrift、Protocol Buffers 和 Avro 作出了極好的比較。

3.10、總結

微服務必須使用進程間通信機制進行通信。在設計服務如何進行通信時,您需要考慮各種問題:服務如何交互、如何為每個服務指定 API、如何演變 API 以及如何處理局部故障。微服務可以使用兩種 IPC 機制:非同步消息傳遞和同步請求/響應。為了進行通信,一個服務必須能夠找到另一個服務。在第四章中,我們將介紹微服務架構中服務發現問題。

微服務實戰:NGINX 與 應用程式架構

by Floyd Smith

NGINX 使您能夠實現各種伸縮和鏡像操作,使您的應用程式更加靈敏和高度可用。您為伸縮和鏡像所作的選擇會影響到您如何進行進程間通信,這是本章的主題。

我們在 NGINX 方面建議您在實現基於微服務的應用程式時考慮使用四層架構。Forrester 在這方面有詳細的報告,您可以從 NGINX 上免費下載。這些層代表客戶端(包括台式機或筆記本電腦、移動、可穿戴或 IoT 客戶端)、交付、聚合(包括數據存儲)和服務,其中包括應用功能和特定服務,而不是共用數據存儲。

四層架構比以前的三層架構更加靈活,具有可擴展、響應靈敏、移動友好,並且內在支持基於微服務的應用程式開發和交付等優點。像 Netflix 和 Uber 這樣的行業引領者能夠通過使用這種架構來實現用戶所需的性能水平。

NGINX 本質上非常適合四層架構,從客戶端層的媒體流,到交付層的負載均衡與緩存、聚合層的高性能和安全的基於 API 的通信的工具,以及服務層中支持靈活管理的短暫服務實例。

同樣的靈活性使得可以實現強大的伸縮和鏡像模式,以處理流量變化,防止安全攻擊,此外還提供可用的故障配置切換,從而實現高可用。

在更為複雜的架構中,包括服務實例實例化和需求不斷的服務發現,解耦的進程間通信往往更受青睞。非同步和一對多通信方式可能比高耦合的通信方式更加靈活,它們最終提供更高的性能和可靠性。

本系列全部譯文

相關鏈接


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

-Advertisement-
Play Games
更多相關文章
  • 世間總是一圖勝過千萬言! 下麵的8幅圖來自於 Program Creek 的 Java教程 ,目前這是該網站最受歡迎的文章.希望本文能幫你回顧你已經知道的那些知識。如果圖片講解的不夠清晰,你可能需要閱讀詳細的文章或者進行搜索。 1. String對象不可改變的特性 (詳情請點擊上面的標題查看) 下圖 ...
  • 常用的web.xml的配置 1、Spring 框架解決字元串編碼問題:過濾器 CharacterEncodingFilter(filter-name) 2、在web.xml配置監聽器ContextLoaderListener(listener-class) ContextLoaderListener ...
  • 1.解決方法其中之一 在web.xml下添加配置: CharacterEncodingFilter org.springframework.web.filter.CharacterEncodingFilter encoding UTF-8 ... ...
  • 三個版本:1、java SE 標準版 2、java EE企業版 3、Java ME 小型版本 JVM (java virtual machine) java虛擬機 JRE(java runtime environment) Java 運行環境 JDK(java development kit) Ja ...
  • 1.linux 安裝python pip 及 CPU下tensorfolw安裝 一般的Linux系統中都有自帶的python,但版本較低。 通過終端下載pip ...
  • 首先從表現層介紹,後續後深入原理。 1,先簡單介紹maven如何生成jar文件方便測試 2.自定義兩個jar包,其中包含相同包名和類名 與export的導入順序有關。只會載入第一個,並且運行正常。 3.自定義jar和jdk包, 其中包含相同的包名和類名 與export的導入順序有關。同樣是只會載入第 ...
  • 1. 講講你認為的高性能網站架構,或者說現在流行的網站架構。 2. 什麼是一主多從? 3. 什麼是負載均衡? ...
  • 定義(百度百科): 當一個對象的內在狀態改變時允許改變其行為,這個對象看起來像是改變了其類。 UML類圖: 具體代碼: 模塊說明: Context:它定義了客戶需要的介面並維護一個具體狀態角色(State)的實例,將與狀態相關的操作交給當前的ConcreteState對象來處理 State:定義一個 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...