日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Nginx >内容正文

Nginx

微软用它取代了`Nginx`吞吐量提升了百分之八十!

發布時間:2024/1/11 Nginx 63 coder
生活随笔 收集整理的這篇文章主要介紹了 微软用它取代了`Nginx`吞吐量提升了百分之八十! 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Azure應用服務用YARP取代了Nginx,獲得了80%以上的吞吐量。他們每天處理160B多個請求(1.9 m RPS)。這是微軟的一項了不起的技術創新。

首先我們來介紹一下什么是Yarp

Yarp是什么?

YARP(Yet Another Reverse Proxy)是一個開源的、高性能的反向代理庫,由Microsoft開發,使用C#語言編寫。它旨在作為.NET平臺上構建反向代理服務器的基礎。YARP主要針對.NET 5及以上版本,允許開發者在.NET應用程序中輕松地實現反向代理的功能。

YARP的主要特點和功能:

  1. 模塊化和可擴展性: YARP設計成高度模塊化的,這意味著可以根據需要替換或擴展內部組件,如HTTP請求路由、負載均衡、健康檢查等。
  2. 性能: YARP針對高性能進行了優化,利用了.NET的異步編程模型和高效的IO操作,以處理大量并發連接。
  3. 配置驅動: YARP的行為可以通過配置來控制,支持從文件、數據庫或其他來源動態加載配置。
  4. 路由: 可以基于各種參數(如路徑、頭部、查詢參數)配置請求路由規則。
  5. 負載均衡: 內置多種負載均衡策略,如輪詢、最少連接、隨機選擇等,并且可以自定義負載均衡策略。
  6. 健康檢查: 支持后端服務的健康檢查,以確保請求只會被轉發到健康的后端服務實例。
  7. 轉換器: 允許對請求和響應進行轉換,如修改頭部、路徑或查詢參數。
  8. 會話親和性: 支持會話親和性(Session Affinity),確保來自同一客戶端的請求被發送到相同的后端服務實例。

使用YARP的一些場景:

  • 反向代理: 在客戶端和后端服務之間提供一個中間層,用于請求轉發和負載均衡。
  • API網關: 作為微服務架構中的API網關,提供路由、鑒權、監控等功能。
  • 邊緣服務: 在應用程序和外部世界之間提供安全層,處理SSL終止、請求限制等任務。

Yarp簡單的使用

創建一個WebApi的項目

安裝Nuget

<ItemGroup>
	<PackageReference Include="Yarp.ReverseProxy" Version="2.0.0" />
</ItemGroup>

打開appsettings.json

{
 "Logging": {
   "LogLevel": {
     "Default": "Information",
     "Microsoft": "Warning",
     "Microsoft.Hosting.Lifetime": "Information"
   }
 },
 "AllowedHosts": "*",
 "ReverseProxy": {
   "Routes": {
     "route1" : {
       "ClusterId": "cluster1",
       "Match": {
         "Path": "{**catch-all}"
       }
     }
   },
   "Clusters": {
     "cluster1": {
       "Destinations": {
         "destination1": {
           "Address": "https://cn.bing.com/"
         }
       }
     }
   }
 }
}

打開Program.cs

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddReverseProxy()
    .LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"));
var app = builder.Build();
app.MapReverseProxy();
app.Run();

然后啟動項目,訪問我們的api就會被代理轉發到bing

Yarp工具代理使用

下面我們在提供一個在中間件使用yarp的方式

我們需要用到IHttpForwarder

先修改Program.cs 在這里我們注入了HttpForwarder,然后提供一個Run中間件,在中間件中手動指定了端點的地址https://cn.bing.com/ 然后我們啟動一下項目。

using Yarp.ReverseProxy.Forwarder;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpForwarder(); // 注入IHttpForwarder 
var app = builder.Build();

var httpMessage = new HttpMessageInvoker(new HttpClientHandler());

app.Run((async context =>
{
    var httpForwarder = context.RequestServices.GetRequiredService<IHttpForwarder>();
    var destinationPrefix = "https://cn.bing.com/";

    await httpForwarder.SendAsync(context, destinationPrefix, httpMessage);
}));

app.Run();

也是一樣會被代理過去,但是于簡單使用不一樣的是我們是在代碼層面控制代理的。

使用yarp修改Bing的響應內容

我們繼續基于上面的代理使用進行修改bing的相應內容!

打開Program.cs

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpForwarder(); // 注入IHttpForwarder 
var app = builder.Build();

var httpMessage = new HttpMessageInvoker(new HttpClientHandler()
{
    // 忽略https錯誤
    ServerCertificateCustomValidationCallback = (_, _, _, _) => true,
    AllowAutoRedirect = false,
    AutomaticDecompression = DecompressionMethods.GZip,
    UseCookies = false,
    UseProxy = false,
    UseDefaultCredentials = true,
});
var destinationPrefix = "https://cn.bing.com/";

var bingTransformer = new BingTransformer();

app.Run((async context =>
{
    var httpForwarder = context.RequestServices.GetRequiredService<IHttpForwarder>();
    await httpForwarder.SendAsync(context, destinationPrefix, httpMessage, new ForwarderRequestConfig(),
        bingTransformer);
}));

app.Run();

創建BingTransformer.cs

public class BingTransformer : HttpTransformer
{
    public override async ValueTask TransformRequestAsync(HttpContext httpContext, HttpRequestMessage proxyRequest,
        string destinationPrefix,
        CancellationToken cancellationToken)
    {
        var uri = RequestUtilities.MakeDestinationAddress(destinationPrefix, httpContext.Request.Path,
            httpContext.Request.QueryString);
        proxyRequest.RequestUri = uri;
        proxyRequest.Headers.Host = uri.Host;
        await base.TransformRequestAsync(httpContext, proxyRequest, destinationPrefix, cancellationToken);
    }

    public override async ValueTask<bool> TransformResponseAsync(HttpContext httpContext,
        HttpResponseMessage? proxyResponse,
        CancellationToken cancellationToken)
    {
        await base.TransformResponseAsync(httpContext, proxyResponse, cancellationToken);

        if (httpContext.Request.Method == "GET" &&
            httpContext.Response.Headers["Content-Type"].Any(x => x.StartsWith("text/html")))
        {
            var encoding = proxyResponse.Content.Headers.FirstOrDefault(x => x.Key == "Content-Encoding").Value;
            if (encoding?.FirstOrDefault() == "gzip")
            {
                var content = proxyResponse?.Content.ReadAsByteArrayAsync(cancellationToken).Result;
                if (content != null)
                {
                    var result = Encoding.UTF8.GetString(GZipDecompressByte(content));
                    result = result.Replace("國內版", "Token Bing 搜索 - 國內版");
                    proxyResponse.Content = new StringContent(GZipDecompressString(result));
                }
            }
            else if (encoding.FirstOrDefault() == "br")
            {
                var content = proxyResponse?.Content.ReadAsByteArrayAsync(cancellationToken).Result;
                if (content != null)
                {
                    var result = Encoding.UTF8.GetString(BrDecompress(content));
                    result = result.Replace("國內版", "Token Bing 搜索 - 國內版");
                    proxyResponse.Content = new ByteArrayContent(BrCompress(result));
                }
            }
            else
            {
                var content = proxyResponse?.Content.ReadAsStringAsync(cancellationToken).Result;
                if (content != null)
                {
                    content = content.Replace("國內版", "Token Bing 搜索 - 國內版");
                    proxyResponse.Content = new StringContent(content);
                }
            }
        }

        return true;
    }

    /// <summary>
    /// 解壓GZip
    /// </summary>
    /// <param name="bytes"></param>
    /// <returns></returns>
    public static byte[] GZipDecompressByte(byte[] bytes)
    {
        using var targetStream = new MemoryStream();
        using var compressStream = new MemoryStream(bytes);
        using var zipStream = new GZipStream(compressStream, CompressionMode.Decompress);
        using (var decompressionStream = new GZipStream(compressStream, CompressionMode.Decompress))
        {
            decompressionStream.CopyTo(targetStream);
        }

        return targetStream.ToArray();
    }

    /// <summary>
    /// 解壓GZip
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    public static string GZipDecompressString(string str)
    {
        using var compressStream = new MemoryStream(Encoding.UTF8.GetBytes(str));
        using var zipStream = new GZipStream(compressStream, CompressionMode.Decompress);
        using var resultStream = new StreamReader(new MemoryStream(compressStream.ToArray()));
        return resultStream.ReadToEnd();
    }

    /// <summary>
    /// Br壓縮
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public static byte[] BrCompress(string str)
    {
        using var outputStream = new MemoryStream();
        using (var compressionStream = new BrotliStream(outputStream, CompressionMode.Compress))
        {
            compressionStream.Write(Encoding.UTF8.GetBytes(str));
        }

        return outputStream.ToArray();
    }

    /// <summary>
    /// Br解壓
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public static byte[] BrDecompress(byte[] input)
    {
        using (var inputStream = new MemoryStream(input))
        using (var outputStream = new MemoryStream())
        using (var decompressionStream = new BrotliStream(inputStream, CompressionMode.Decompress))
        {
            decompressionStream.CopyTo(outputStream);
            return outputStream.ToArray();
        }
    }
}

得到的效果我們將國內版修改成了Token Bing 搜索 - 國內版

Yarp相關資料

技術交流群:737776595

官方文檔:https://microsoft.github.io/reverse-proxy/articles/getting-started.html

來著token的分享

總結

以上是生活随笔為你收集整理的微软用它取代了`Nginx`吞吐量提升了百分之八十!的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产人妖ts重口系列网站观看 | 色av吧 | 久久影音先锋 | 寂寞d奶大胸少妇 | 国产伦理片在线观看 | 波多野结衣亚洲 | 免费在线观看黄网站 | 美女黄页网站 | 影音先锋每日资源 | www毛片 | 黄色福利视频网站 | 国产大片在线观看 | 成年人免费网 | 男人草女人 | 香蕉视频色 | 91精品一区二区三区四区 | 色校园 | 中文字幕手机在线视频 | 中文字幕有码在线视频 | 91av在线免费观看 | 久久精品天天中文字幕人妻 | 国产精品成人一区二区 | 久久青青草原亚洲av无码麻豆 | 欧美特一级 | 中文天堂在线视频 | 精品无码人妻一区二区三区 | 日本精品视频在线播放 | 亲嘴扒胸摸屁股激烈网站 | 久久久天天 | 日韩欧美在线观看一区二区三区 | 精品伦一区二区三区 | 国产成人免费看 | 中文字幕在线观看精品 | 狠狠操在线观看 | 俄罗斯色片 | 精品人妻无码一区二区三区 | 91精品国产麻豆 | www亚洲| 四虎影院新网址 | 欧美成人资源 | 欧美11一13sex性hd | 雷电将军和丘丘人繁衍后代视频 | 日日夜夜爱| 国产精品自拍99 | 国产精品揄拍一区二区 | 成人伊人网站 | 超碰2023| 免费荫蒂添的好舒服视频 | 欧美一道本 | 不卡视频在线播放 | 四虎视频国产精品免费 | 97在线精品视频 | 久久综合激的五月天 | 国产熟妇与子伦hd | 91视频二区| 久久蜜臀精品av | 亚洲伦理在线播放 | 欧美激情videos | 色站综合 | 亚洲AV无码乱码国产精品色欲 | 激情 小说 亚洲 图片 伦 | 最新国产精品自拍 | 在线高清观看免费观看 | 国产精品一级片 | 亚洲网站在线免费观看 | 日本波多野结衣在线 | 国产在线一区二区视频 | 欧美精品激情 | 国产特黄大片aaaa毛片 | 亚洲乱轮视频 | 美女隐私免费看 | 在线a网站 | 国产精品v欧美精品v日韩 | 乳揉みま痴汉4在线播放 | 草草影院最新 | 一级性生活免费视频 | av无码一区二区三区 | 国产一区二区色 | 激情五月激情综合网 | 印度午夜性春猛xxx交 | 黄色片网站免费观看 | 亚洲一二三区在线 | 蜜桃成熟时李丽珍在线观看 | 无码人妻aⅴ一区二区三区 国产高清一区二区三区四区 | 国产伦精品 | 韩日中文字幕 | 天堂av免费在线观看 | 99色网| 欧美性猛交xxxx乱大交俱乐部 | 少妇无套内谢免费视频 | 欧美日韩一区二区在线观看 | 亚洲一区精品在线 | 熟妇人妻一区二区三区四区 | 98成人网| 国产aaa视频 | 成人性生交大片免费看96 | 久久久在线视频 | 国产人妻精品一区二区三区 | missav | 免费高清av在线看 |