【愚公系列】2022年03月 ASP.NET Core中间件-功能开关

简介: 【愚公系列】2022年03月 ASP.NET Core中间件-功能开关

前言

1.功能开关的概念

功能开关,相当于可以控制访问的流转和访问的允许和禁止。例如东京在6月18日做店庆促销活动,在交易下单环节,可能需要调用A、B、C三个接口来完成,但是其实A和B是必须的,C只是附加的功能(例如在下单的时候做一下推荐),可有可无,在平时系统没有压力,容量充足的情况下,调用下没问题,但是在类似店庆之类的大促环节,系统已经满负荷了,这时候其实完全可以不去调用C接口,怎么实现这个呢?改代码?no,no,no,这样太不敏捷,此时开关诞生了,开发人员只要简单执行一下命令或者点一下页面,就可以关掉对于C接口的调用,在大促过去之后,再把开关恢复回去即可。


2.功能开关的优点

功能开关(Feature flags)就是这样一种部署技术。


可以提高应用程序的灵活性。

可以将新功能部署到生产环境中,但限制其可用性。

可以为控制是否激活一项新功能,而无需重新启动应用程序或部署新代码,它们将新功能的发布与代码部署分离。


一、ASP.NET Core中间件实现

1.相关依赖

我们需要引用nuget包Microsoft.FeatureManagement.AspNetCore,并在ConfigureServices中添加扩展


public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddFeatureManagement();
    ...
}

setting.json文件增加配置


"FeatureManagement": 
{
    "ForbiddenDebugEndpoint": false
}

2.中间件代码

public class DebugMiddleware : IMiddleware
{
    private readonly IFeatureManager _featureManager;
    public DebugMiddleware(IFeatureManager featureManager)
    {
        _featureManager = featureManager;
    }
    public async Task InvokeAsync(HttpContext context, RequestDelegate next)
    {
        var isDebugEndpoint = context.Request.Path.Value.Contains("/test");
        var debugEndpoint = await _featureManager.IsEnabledAsync("ForbiddenDebugEndpoint");
        if (isDebugEndpoint && debugEndpoint)
        {
            context.SetEndpoint(new Endpoint((context) =>
            {
                context.Response.StatusCode = StatusCodes.Status403Forbidden;
                return Task.CompletedTask;
            },
                        EndpointMetadataCollection.Empty,
                        "无权访问"));
        }
        await next(context);
    }
}

3.在管道中的使用

app.UseMiddleware<DebugMiddleware >()

4.修改配置控制

关键就是这句话,我们使用了功能开关:


var debugEndpoint = await _featureManager.IsEnabledAsync("ForbiddenDebugEndpoint");

只需要在配置文件中设置ForbiddenDebugEndpoint值为true或false就可以控制


"FeatureManagement": 
{
    "ForbiddenDebugEndpoint": false
}

二、IFeatureFilter过滤器

IFeatureFilter(功能过滤器)可用于确定是否满足某些条件以启用一项功能。功能过滤器可以自由使用任何可用的标准,例如流程状态或请求内容。

可以为给定功能注册功能过滤器,如果任何特征过滤器评估为真,该特征将被考虑启用。


1.过滤去代码

public class DebugFeatureSettings
{
    public string[] DebugEndpoints { get; set; }
}
[FilterAlias("DebugFeatureFilter")]
public class DebugFeatureFilter : IFeatureFilter
{
    private readonly IHttpContextAccessor _httpContextAccessor;
    public DebugFeatureFilter(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }
    public Task<bool> EvaluateAsync(FeatureFilterEvaluationContext context)
    {
        var settings = context.Parameters.Get<DebugFeatureSettings>();
        foreach (var endPoint in settings.DebugEndpoints)
        {
            var isDebugEndpoint = _httpContextAccessor.HttpContext.Request.Path.Value.Contains(endPoint);
            return Task.FromResult(isDebugEndpoint);
        }
        return Task.FromResult(false);
    }
}

2.配置文件

"FeatureManagement": {
    "ForbiddenDebugEndpoint": {
        "EnabledFor": [
        {
            "Name": "DebugFeatureFilter",
            "Parameters": {
                "DebugEndpoints": [ "/test" ]
            }
        }
        ]
    }
}

3.改写功能开关中间件

public class DebugMiddleware : IMiddleware
{
    private readonly IFeatureManager _featureManager;
    public DebugMiddleware(IFeatureManager featureManager)
    {
        _featureManager = featureManager;
    }
    public async Task InvokeAsync(HttpContext context, RequestDelegate next)
    {
        var debugEndpoint = await _featureManager.IsEnabledAsync("ForbiddenDebugEndpoint");
        if (debugEndpoint)
        {
            context.SetEndpoint(new Endpoint((context) =>
            {
                context.Response.StatusCode = StatusCodes.Status403Forbidden;
                return Task.CompletedTask;
            },
                        EndpointMetadataCollection.Empty,
                        "无权访问"));
        }
        await next(context);
    }
}
相关文章
|
12月前
|
开发框架 .NET C#
ASP.NET Core Blazor 路由配置和导航
大家好,我是码农刚子。本文系统介绍Blazor单页应用的路由机制,涵盖基础配置、路由参数、编程式导航及高级功能。通过@page指令定义路由,支持参数约束、可选参数与通配符捕获,结合NavigationManager实现页面跳转与参数传递,并演示用户管理、产品展示等典型场景,全面掌握Blazor路由从入门到实战的完整方案。
791 6
|
开发框架 .NET 开发者
简化 ASP.NET Core 依赖注入(DI)注册-Scrutor
Scrutor 是一个简化 ASP.NET Core 应用程序中依赖注入(DI)注册过程的开源库,支持自动扫描和注册服务。通过简单的配置,开发者可以轻松地从指定程序集中筛选、注册服务,并设置其生命周期,同时支持服务装饰等高级功能。适用于大型项目,提高代码的可维护性和简洁性。仓库地址:&lt;https://github.com/khellang/Scrutor&gt;
962 5
|
开发框架 算法 中间件
ASP.NET Core 中的速率限制中间件
在ASP.NET Core中,速率限制中间件用于控制客户端请求速率,防止服务器过载并提高安全性。通过`AddRateLimiter`注册服务,并配置不同策略如固定窗口、滑动窗口、令牌桶和并发限制。这些策略可在全局、控制器或动作级别应用,支持自定义响应处理。使用中间件`UseRateLimiter`启用限流功能,并可通过属性禁用特定控制器或动作的限流。这有助于有效保护API免受滥用和过载。 欢迎关注我的公众号:Net分享 (239字符)
562 1
|
消息中间件 存储 负载均衡
消息中间件的选择:RabbitMQ是一个明智的选择
消息中间件的选择:RabbitMQ是一个明智的选择
439 0
|
消息中间件 存储 中间件
【消息中间件】详解三大MQ:RabbitMQ、RocketMQ、Kafka
【消息中间件】详解三大MQ:RabbitMQ、RocketMQ、Kafka
15153 1
|
消息中间件 编解码 Docker
Docker部署RabbitMQ消息中间件
【7月更文挑战第4天】Docker部署RabbitMQ消息中间件
718 3
|
消息中间件 数据库
消息中间件系列教程(18) -RabbitMQ-基于RabbitMQ解决分布式事务(思想)
消息中间件系列教程(18) -RabbitMQ-基于RabbitMQ解决分布式事务(思想)
555 0
|
消息中间件
消息中间件系列教程(17) -RabbitMQ-死信队列
消息中间件系列教程(17) -RabbitMQ-死信队列
460 0
|
消息中间件
消息中间件系列教程(16) -RabbitMQ-应答模式
消息中间件系列教程(16) -RabbitMQ-应答模式
311 0
|
消息中间件
消息中间件系列教程(15) -RabbitMQ-基于全局消息ID解决幂等性问题
消息中间件系列教程(15) -RabbitMQ-基于全局消息ID解决幂等性问题
433 0