企業應用架構研究系列二十三:微服務之程式網關YARP

来源:https://www.cnblogs.com/luking/archive/2022/08/17/16094668.html
-Advertisement-
Play Games

在搭建微服務框架的時候,離不開一個關鍵的微服務組件,應用程式網關,這個組件在微服務框架體系內至關重要。通過應用程式網關,可以將微服務框架內的服務進行重定向、限流、監控、故障轉移等整操作後,對外提供應用程式池中的服務,應用程式服務池是對外部不透明的,唯一的數據交換點就是微服務的應用程式網關。 應用程式 ...


  在搭建微服務框架的時候,離不開一個關鍵的微服務組件,應用程式網關,這個組件在微服務框架體系內至關重要。通過應用程式網關,可以將微服務框架內的服務進行重定向、限流、監控、故障轉移等整操作後,對外提供應用程式池中的服務,應用程式服務池是對外部不透明的,唯一的數據交換點就是微服務的應用程式網關。

  應用程式網的成熟開源產品比較多,Java、Go、.Net Core 等開發語言都提供了優秀的開源產品,由於目前專攻.Net Core 微服務架構,本文將只談.Net Core 語言開發的應用程式網關。其中最為出名的就是Ocelot 開源組件了,它提供了極其豐富的應用程式網關功能,並且Ocelot衍生的其它開源產品也是很多,Ocelot的生態非常不錯。

  但是今天,給大家推薦一款微軟開源的反向代理組件Yarp.ReverseProxy(Yet Another Robot Platform),這個開源產品知名度目前並不高,提供的應用程式網關功能也不是很強大,通過深入的研究,我相信它是一個很有潛力的開源產品。首先相信微軟推出的開源產品一定是精品,其次,YARP基於管道機制提供了豐富的二次開發介面和方法,這樣可以根據自己項目或自己產品個性化的需求進行深度的定製開發。還有,Yarp 本身也提供了軟負載均衡、健康監控、分散式追蹤、報文和路由Transforms等強大功能、對gRPC、WebSock、SPDY 等網路協議原生支持,新版本又推出了對後端服務提供基於HTTP/3連接的支持。微軟提供的性能測試,新版本(.NET 6 +)的性能高於Go 開發的ReverseProxy很高。

  

  通過簡單的描述,大家對YARP有了一個簡單瞭解,現在開始說一下它具體怎麼使用,YARP 的使用非常簡單,可以通過JSON配置文件就可以使用其很多功能,滿是大部分的反向代理功能。官網提供了詳細的使用說明文檔https://microsoft.github.io/reverse-proxy/index.html。並且這個YARP針對ServiceFabric 微服務運行平臺提供了擴展包,可以滿足基於ServiceFabric 開發的微服務平臺。

  YARP 的使用非常簡單,主要包含兩部分:Routes 和 Clusters 兩部分配置,這兩部分通過ClusterId 進行關聯。具體的配置請參考官網文檔或下麵提供的示例,非常容易理解每一個配置選項和配置方法,同時需要提醒的是,對路由的匹配和路由的轉變部分,還是需要用心研究一下。  

{
  // Base URLs the server listens on, must be configured independently of the routes below
  "Urls": "http://localhost:5000;https://localhost:5001",
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      // Uncomment to hide diagnostic messages from runtime and proxy
      // "Microsoft": "Warning",
      // "Yarp" : "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "ReverseProxy": {
    // Routes tell the proxy which requests to forward
    "Routes": { 
      "minimumroute" : {
        // Matches anything and routes it to www.example.com
        "ClusterId": "minimumcluster",
        "Match": {
          "Path": "{**catch-all}"
        }
      },
      "allrouteprops" : {
        // matches /something/* and routes to "allclusterprops"
        "ClusterId": "allclusterprops", // Name of one of the clusters
        "Order" : 100, // Lower numbers have higher precedence
        "Authorization Policy" : "Anonymous", // Name of the policy or "Default", "Anonymous"
        "CorsPolicy" : "Default", // Name of the CorsPolicy to apply to this route or "Default", "Disable"
        "Match": {
          "Path": "/something/{**remainder}", // The path to match using ASP.NET syntax. 
          "Hosts" : [ "www.aaaaa.com", "www.bbbbb.com"], // The host names to match, unspecified is any
          "Methods" : [ "GET", "PUT" ], // The HTTP methods that match, uspecified is all
          "Headers": [ // The headers to match, unspecified is any
            {
              "Name": "MyCustomHeader", // Name of the header
              "Values": [ "value1", "value2", "another value" ], // Matches are against any of these values
              "Mode": "ExactHeader", // or "HeaderPrefix", "Exists" , "Contains", "NotContains"
              "IsCaseSensitive": true
            }
          ],
          "QueryParameters": [ // The query parameters to match, unspecified is any
            {
              "Name": "MyQueryParameter", // Name of the query parameter
              "Values": [ "value1", "value2", "another value" ], // Matches are against any of these values
              "Mode": "Exact", // or "Prefix", "Exists" , "Contains", "NotContains"
              "IsCaseSensitive": true
            }
          ]
        },
        "MetaData" : { // List of key value pairs that can be used by custom extensions
          "MyName" : "MyValue"
        },
        "Transforms" : [ // List of transforms. See the Transforms article for more details
          {
            "RequestHeader": "MyHeader",
            "Set": "MyValue",
          } 
        ]
      }
    },
    // Clusters tell the proxy where and how to forward requests
    "Clusters": {
      "minimumcluster": {
        "Destinations": {
          "example.com": {
            "Address": "http://www.example.com/"
          }
        }
      },
      "allclusterprops": {
        "Destinations": {
          "first_destination": {
            "Address": "https://contoso.com"
          },
          "another_destination": {
            "Address": "https://10.20.30.40",
            "Health" : "https://10.20.30.40:12345/test" // override for active health checks
          }
        },
        "LoadBalancingPolicy" : "PowerOfTwoChoices", // Alternatively "FirstAlphabetical", "Random", "RoundRobin", "LeastRequests"
        "SessionAffinity": {
          "Enabled": true, // Defaults to 'false'
          "Policy": "Cookie", // Default, alternatively "CustomHeader"
          "FailurePolicy": "Redistribute", // default, Alternatively "Return503Error"
          "Settings" : {
              "CustomHeaderName": "MySessionHeaderName" // Defaults to 'X-Yarp-Proxy-Affinity`
          }
        },
        "HealthCheck": {
          "Active": { // Makes API calls to validate the health. 
            "Enabled": "true",
            "Interval": "00:00:10",
            "Timeout": "00:00:10",
            "Policy": "ConsecutiveFailures",
            "Path": "/api/health" // API endpoint to query for health state
          },
          "Passive": { // Disables destinations based on HTTP response codes
            "Enabled": true, // Defaults to false
            "Policy" : "TransportFailureRateHealthPolicy", // Required
            "ReactivationPeriod" : "00:00:10" // 10s
          }
        },
        "HttpClient" : { // Configuration of HttpClient instance used to contact destinations
          "SSLProtocols" : "Tls13",
          "DangerousAcceptAnyServerCertificate" : false,
          "MaxConnectionsPerServer" : 1024,
          "EnableMultipleHttp2Connections" : true,
          "RequestHeaderEncoding" : "Latin1" // How to interpret non ASCII characters in header values
        },
        "HttpRequest" : { // Options for sending request to destination
          "ActivityTimeout" : "00:02:00",
          "Version" : "2",
          "VersionPolicy" : "RequestVersionOrLower",
          "AllowResponseBuffering" : "false"
        },
        "MetaData" : { // Custom Key value pairs
          "TransportFailureRateHealthPolicy.RateLimit": "0.5", // Used by Passive health policy
          "MyKey" : "MyValue"
        }
      }
    }
  }
}

  通過代碼也是可以進行配置的,使用代碼配置其實更符合真正的生產環境場景,生產環境,配置往往需要動態的進行配置調整,同時也可能會增加一些額外的運行參數到網關中等等,如增加網關的身份認證,通過身份認證後,拿到一些額外參數加入到請求報文中傳遞給後臺服務等。下麵是通過代碼進行的配置,如下圖。

  

  現在我們就可以進行測試我們的YARP 網關了,我們通過將後端服務部署到Docker 中,通過 YARP 作為代理網關對外提供服務,如下圖,這樣達到了應用程式網關的效果,也實現了軟負載功能。

  

  後續將繼續YARP 的高級功能研究。

 

 

  

  

 

  

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

-Advertisement-
Play Games
更多相關文章
  • 為了保護用戶隱私,大多數應用只會在前臺運行時獲取用戶位置,當應用在後臺運行時,定位功能會被禁止。這就導致APP在後臺或者鎖屏時無法正常記錄GPS軌跡,這對打車、共用出行、跑步等需要實時記錄用戶軌跡的應用影響非常大,甚至影響了應用核心功能的使用體驗。那對於這些應用的開發者來說,如何在用戶主動授權位置信 ...
  • 今天在學習如何使用npm安裝包的時候,在使用 npm install xxx -g 安裝全局包時, 發現安裝的包無法使用。而安裝時cmd卻沒有報錯,這令我很疑惑,這應該是安裝成功了但卻不能使用。 如下圖所示 在查詢了資料後,使用了 npm root -g 命令,獲得了全局包的安裝路徑,打開後發現該路 ...
  • 使用$parent訪問父級組件實例 點擊打開視頻講解更詳細 和 $root 類似,$parent property 可以用來從一個子組件訪問父組件的實例。它提供了一種機會,可以在後期隨時觸達父級組件,以替代將數據以 prop 的方式傳入子組件的方式。 註意:在絕大多數情況下,觸達父級組件會使得你的應 ...
  • 前端周刊:2022-13 期 前端開發 Vue3 文檔更新 更新後的 Vue3 文檔分別提供了選項式和組合式兩個版本,內容豐富程度和細緻程度也有很大提升,推薦大家重讀一遍。 前端請求併發控制 所有請求都在一個數組中,以限定的併發數將請求發完 前端 API 請求的各種騷操作 併發控制 / 節流控制 / ...
  • 處理邊界情況之使用$root訪問根實例 點擊打開視頻教程 在每個 new Vue 實例的子組件中,其根實例可以通過 $root property 進行訪問。 例如,在這個根實例中: src\main.js import Vue from 'vue' import App from './App.vu ...
  • 本文是深入淺出 ahooks 源碼系列文章的第七篇,該系列已整理成文檔-地址。覺得還不錯,給個 star 支持一下哈,Thanks。 今天我們來聊聊定時器。 useInterval 和 useTimeout 看名稱,我們就能大概知道,它們的功能對應的是 setInterval 和 setTimeou ...
  • 行為型模式(Behavioral Pattern)是指對在不同對象之間劃分責任和演算法進行抽象化的設計模式,它不僅關註類和對象的結構,而且重點關註他們之間的相互作用。 對於一個系統來說,對象不是孤立運行的,對象之間可以通過相互通信和協作完成某些複雜的功能,對象之間是相互影響的。 ...
  • 性能優化屬於Java高級崗的必備技能,而且大廠特別喜歡考察,今天主要給大家介紹9種性能優化的方法@mikechen 1.代碼 之所以把代碼放到第一位,是因為這一點最容易引忽視,比如拿到一個性能優化的需求以後,言必稱緩存、非同步等。 實際上,第一步就應該是分析相關的代碼,找出相應的瓶頸,再來考慮具體的優 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...