NexusContract.Hosting.Yarp 1.0.0-preview.19

This is a prerelease version of NexusContract.Hosting.Yarp.
The owner has unlisted this package. This could mean that the package is deprecated, has security vulnerabilities or shouldn't be used anymore.
dotnet add package NexusContract.Hosting.Yarp --version 1.0.0-preview.19
                    
NuGet\Install-Package NexusContract.Hosting.Yarp -Version 1.0.0-preview.19
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="NexusContract.Hosting.Yarp" Version="1.0.0-preview.19" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="NexusContract.Hosting.Yarp" Version="1.0.0-preview.19" />
                    
Directory.Packages.props
<PackageReference Include="NexusContract.Hosting.Yarp" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add NexusContract.Hosting.Yarp --version 1.0.0-preview.19
                    
#r "nuget: NexusContract.Hosting.Yarp, 1.0.0-preview.19"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package NexusContract.Hosting.Yarp@1.0.0-preview.19
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=NexusContract.Hosting.Yarp&version=1.0.0-preview.19&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=NexusContract.Hosting.Yarp&version=1.0.0-preview.19&prerelease
                    
Install as a Cake Tool

NexusContract.Hosting.Yarp

生产级 HTTP/2 出口传输层 — 基于 YARP + Polly 的高性能上游 API 调用


📋 Overview

NexusContract.Hosting.Yarp 是 NexusContract 的出口层(Egress Layer),提供:

  1. HTTP/2 连接池 — 单连接多路复用,减少 TLS 握手
  2. Polly 弹性策略 — 自动重试(指数退避)+ 熔断器(防雪崩)
  3. 负载均衡 — 支持 RoundRobin、Random、LeastConnections、WeightedRoundRobin
  4. 生产级性能 — 连接复用、抖动重试、快速失败

架构位置

Hosting(Ingress)→ NexusEngine → Provider → INexusTransport(Egress)→ 上游 API

🚀 Quick Start

1. 安装包

dotnet add package NexusContract.Hosting.Yarp

2. 注册服务

// Program.cs
builder.Services.AddNexusYarpTransport(options =>
{
    // 重试策略
    options.RetryCount = 3;                             // 最多重试 3 次
    options.RetryBaseDelay = TimeSpan.FromMilliseconds(200); // 基础延迟 200ms(指数退避)

    // 熔断器策略
    options.CircuitBreakerFailureThreshold = 5;         // 5 次失败触发熔断
    options.CircuitBreakerSamplingDuration = TimeSpan.FromSeconds(30);  // 采样窗口 30s
    options.CircuitBreakerDurationOfBreak = TimeSpan.FromSeconds(30);   // 熔断持续 30s

    // HTTP/2 连接池
    options.MaxConnectionsPerServer = 10;               // 每服务器最多 10 个连接
    options.PooledConnectionIdleTimeout = TimeSpan.FromSeconds(90); // 空闲连接 90s 回收
    options.PooledConnectionLifetime = TimeSpan.FromMinutes(10);    // 连接最大生命周期 10min

    // 其他配置
    options.RequestTimeout = TimeSpan.FromSeconds(30);  // 请求超时 30s
    options.EnableRequestResponseLogging = false;       // 禁用详细日志(生产环境)
    options.EnableMetrics = true;                       // 启用性能指标
});

3. 使用传输层

public class AlipayProvider
{
    private readonly INexusTransport _transport;

    public AlipayProvider(INexusTransport transport)
    {
        _transport = transport;
    }

    public async Task<string> TradePayAsync(string bizContent, CancellationToken ct)
    {
        // 构造请求
        using var request = new HttpRequestMessage(HttpMethod.Post, "https://openapi.alipay.com/gateway.do")
        {
            Content = new StringContent(bizContent, Encoding.UTF8, "application/json"),
            Version = HttpVersion.Version20,  // 强制 HTTP/2
            VersionPolicy = HttpVersionPolicy.RequestVersionOrHigher
        };

        // 通过 YARP 传输(自动重试 + 熔断)
        HttpResponseMessage response = await _transport.SendAsync(request, ct);

        // 处理响应
        string responseBody = await response.Content.ReadAsStringAsync(ct);
        return responseBody;
    }
}

🔧 Configuration

YarpTransportOptions

属性 类型 默认值 说明
RetryCount int 3 最多重试次数
RetryBaseDelay TimeSpan 200ms 重试基础延迟(指数退避)
CircuitBreakerFailureThreshold int 5 触发熔断的失败次数
CircuitBreakerSamplingDuration TimeSpan 30s 熔断器采样窗口
CircuitBreakerDurationOfBreak TimeSpan 30s 熔断持续时间
MaxConnectionsPerServer int 10 每服务器最大连接数
PooledConnectionIdleTimeout TimeSpan 90s 空闲连接超时
PooledConnectionLifetime TimeSpan 10min 连接最大生命周期
RequestTimeout TimeSpan 30s 单个请求超时
EnableRequestResponseLogging bool false 启用详细日志
EnableMetrics bool true 启用性能指标

📊 Performance

HTTP/2 连接池优势

场景 HttpClient 直连 YarpTransport
TLS 握手 每次 ~100ms 复用(0ms)
并发请求 多连接 单连接多路复用
内存占用 高(每连接独立) 低(连接池共享)
错误重试 手动实现 Polly 自动
熔断保护 无 Polly 自动

Benchmark

BenchmarkDotNet v0.13.12, Windows 11 (10.0.22631.4602)
Intel Core i9-14900K, 1 CPU, 32 logical and 24 physical cores

| Method              | Mean     | Error    | StdDev   | Allocated |
|-------------------- |---------:|---------:|---------:|----------:|
| HttpClient_Direct   | 105.2 ms | 2.1 ms   | 1.9 ms   | 12.5 KB   |
| YarpTransport_HTTP2 | 12.8 ms  | 0.3 ms   | 0.2 ms   | 3.2 KB    |

🛡️ Resilience

Polly 弹性管道

超时(30s)→ 熔断器 → 重试(指数退避 + 抖动)→ HTTP/2 请求
1. 超时策略
  • 请求超过 30s 自动取消
  • 防止长时间挂起
2. 熔断器
  • 30s 内 5 次失败 → 熔断器开启
  • 开启后快速失败(不再尝试)
  • 30s 后尝试半开(测试恢复)
3. 重试策略
  • 最多重试 3 次
  • 指数退避:200ms → 400ms → 800ms
  • 抖动(Jitter):避免惊群效应
  • 仅重试以下错误:
    • HttpRequestException
    • TaskCanceledException
    • HTTP 408 (RequestTimeout)
    • HTTP 503 (ServiceUnavailable)
    • HTTP 429 (TooManyRequests)

🧪 Testing

单元测试示例

[Fact]
public async Task SendAsync_Should_RetryOnTimeout()
{
    // Arrange
    var mockHandler = new Mock<HttpMessageHandler>();
    mockHandler
        .SetupSequence<Task<HttpResponseMessage>>(
            "SendAsync",
            ItExpr.IsAny<HttpRequestMessage>(),
            ItExpr.IsAny<CancellationToken>())
        .ThrowsAsync(new TaskCanceledException())  // 第 1 次失败
        .ThrowsAsync(new TaskCanceledException())  // 第 2 次失败
        .ReturnsAsync(new HttpResponseMessage(HttpStatusCode.OK)); // 第 3 次成功

    var httpClient = new HttpClient(mockHandler.Object);
    var options = Options.Create(new YarpTransportOptions { RetryCount = 3 });
    var logger = Mock.Of<ILogger<YarpTransport>>();

    var transport = new YarpTransport(httpClient, options, logger);

    // Act
    var request = new HttpRequestMessage(HttpMethod.Get, "https://api.example.com");
    var response = await transport.SendAsync(request);

    // Assert
    response.StatusCode.Should().Be(HttpStatusCode.OK);
    mockHandler.Verify(
        m => m.SendAsync(It.IsAny<HttpRequestMessage>(), It.IsAny<CancellationToken>()),
        Times.Exactly(3)); // 重试了 3 次
}

📚 Best Practices

1. 生产环境配置

// appsettings.Production.json
{
  "YarpTransport": {
    "RetryCount": 3,
    "CircuitBreakerFailureThreshold": 10,
    "MaxConnectionsPerServer": 20,
    "EnableRequestResponseLogging": false,  // 关闭详细日志
    "EnableMetrics": true                   // 启用性能监控
  }
}

// Program.cs
builder.Services.AddNexusYarpTransport(options =>
{
    builder.Configuration.GetSection("YarpTransport").Bind(options);
});

2. 避免过度重试

// ❌ 错误:业务错误不应重试
// HTTP 400 Bad Request 说明参数错误,重试无意义

// ✅ 正确:仅重试临时错误
options.RetryCount = 3;  // 仅重试网络超时、服务不可用等临时错误

3. 监控熔断器状态

builder.Services.AddNexusYarpTransport(options =>
{
    options.CircuitBreakerFailureThreshold = 5;
    options.CircuitBreakerDurationOfBreak = TimeSpan.FromSeconds(30);
});

// 监听熔断器事件(通过日志)
// 熔断器开启:Circuit breaker opened. Fast-failing for 00:00:30.
// 熔断器关闭:Circuit breaker closed. Resuming normal operations.


📄 License

MIT License. See LICENSE for details.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated

Initial preview with HTTP/2 connection pooling, Polly retry/circuit breaker, and YARP integration.