zoukankan      html  css  js  c++  java
  • 打不死的小强 .net core 微服务 快速开发框架 Viper 限流

    1、Viper是什么?

      Viper 是.NET平台下的Anno微服务框架的一个示例项目。入门简单安全稳定高可用全平台可监控。底层通讯可以随意切换thrift grpc 自带服务发现、调用链追踪、Cron 调度、限流、事件总线、CQRS 、DDD、类似MVC的开发体验,插件化开发

      一个不可监控的微服务平台是可怕的,出了问题 难以准确定位问题的根源, Anno则提供了一套完整的监控体系,包括链路追踪服务占用的系统资源、系统自身 CPU、内存、硬盘使用率实时可监控等等。

      今天要说的是.netcore 微服务Viper的限流,防止恶意攻击,做一个打不死的小强

      如果对Viper不了解的可以看上篇文章了解 net core 微服务 快速开发框架 Viper 初体验

    github:
    https://github.com/duyanming/Viper
    文档地址:
    https://duyanming.github.io/

    体验地址:(体验用户为anno 密码123456 同一时间一个用户只能在一个终端登录用户多的时候可能发生强制退出的情况,稍后登录体验)
    http://140.143.207.244/

    2、限流Anno.RateLimit

      限流用到两个库 Anno.RateLimit、IPAddressRange。Anno.RateLimit为限流组件,IPAddressRange为IP匹配组件。

    IPAddressRange地址:https://github.com/jsakamoto/ipaddressrange

    using NetTools;
    ...
    // rangeA.Begin is "192.168.0.0", and rangeA.End is "192.168.0.255".
    var rangeA = IPAddressRange.Parse("192.168.0.0/255.255.255.0");
    rangeA.Contains(IPAddress.Parse("192.168.0.34")); // is True.
    rangeA.Contains(IPAddress.Parse("192.168.10.1")); // is False.
    rangeA.ToCidrString(); // is 192.168.0.0/24
    
    // rangeB.Begin is "192.168.0.10", and rangeB.End is "192.168.10.20".
    var rangeB1 = IPAddressRange.Parse("192.168.0.10 - 192.168.10.20");
    rangeB1.Contains(IPAddress.Parse("192.168.3.45")); // is True.
    rangeB1.Contains(IPAddress.Parse("192.168.0.9")); // is False.
    
    // Support shortcut range description. 
    // ("192.168.10.10-20" means range of begin:192.168.10.10 to end:192.168.10.20.)
    var rangeB2 = IPAddressRange.Parse("192.168.10.10-20");
    
    // Support CIDR expression and IPv6.
    var rangeC = IPAddressRange.Parse("fe80::/10"); 
    rangeC.Contains(IPAddress.Parse("fe80::d503:4ee:3882:c586%3")); // is True.
    rangeC.Contains(IPAddress.Parse("::1")); // is False.
    
    // "Contains()" method also support IPAddressRange argument.
    var rangeD1 = IPAddressRange.Parse("192.168.0.0/16");
    var rangeD2 = IPAddressRange.Parse("192.168.10.0/24");
    rangeD1.Contains(rangeD2); // is True.
    
    // IEnumerable<IPAddress> support, it's lazy evaluation.
    foreach (var ip in IPAddressRange.Parse("192.168.0.1/23"))
    {
        Console.WriteLine(ip);
    }
    
    // You can use LINQ via "AsEnumerable()" method.
    var longValues = IPAddressRange.Parse("192.168.0.1/23")
      .AsEnumerable()
      .Select(ip => BitConvert.ToInt32(ip.GetAddressBytes(), 0))
      .Select(adr => adr.ToString("X8"));
    Console.WriteLine(string.Join(",", longValues);
    
    // Constructors from IPAddress objects.
    var ipBegin = IPAddress.Parse("192.168.0.1");
    var ipEnd = IPAddress.Parse("192.168.0.128");
    var ipSubnet = IPAddress.Parse("255.255.255.0");
    
    var rangeE = new IPAddressRange(); // This means "0.0.0.0/0".
    var rangeF = new IPAddressRange(ipBegin, ipEnd);
    var rangeG = new IPAddressRange(ipBegin, maskLength: 24);
    var rangeH = new IPAddressRange(ipBegin, IPAddressRange.SubnetMaskLength(ipSubnet));
    
    // Calculates Cidr subnets
    var rangeI = IPAddressRange.Parse("192.168.0.0-192.168.0.254");
    rangeI.ToCidrString();  // is 192.168.0.0/24

     Anno.RateLimit限流组件的使用

       Anno.RateLimit支持令牌桶和漏桶两种算法

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using Anno.RateLimit;
    
    namespace ConsoleTest
    {
        /// <summary>
        /// 限流测试
        /// </summary>
        public class RateLimitTest
        {
            /// <summary>
            /// 限流测试
            /// </summary>
            public void Handle()
            {
                var service = LimitingFactory.Build(TimeSpan.FromSeconds(1),LimitingType.TokenBucket, 20, 5);
                Console.Write("请输入线程数:");
                long.TryParse(Console.ReadLine(), out long th);
                for (int i = 0; i < th; i++)
                {
                    var t = Task.Factory.StartNew(() =>
                    {
                        while (true)
                        {
                            var result = service.Request();
                            //如果返回true,说明可以进行业务处理,否则需要继续等待
                            if (result)
                            {
                                Console.WriteLine($"{DateTime.Now}--{Task.CurrentId}---ok");
                                //业务处理......
                            }
                            else
                                Thread.Sleep(100);
                        }
                    }, TaskCreationOptions.LongRunning);
                }
            }
        }
    }

    3、Viper限流

      下图是用Jmeter测试线上http://140.143.207.244/ 的截图,下图红色部分为限流直接返回失败的记录,调用方为 NewApi目标服务为NewApi可以看到返回的信息为Trigger current limiting,

    通过限流保证Viper成为一个打不死的小强

    配置Viper的限流

    {
      "Target": {
        "AppName": "ApiGateway",
        "IpAddress": "127.0.0.1",
        "Port": 7010,
        "TraceOnOff": true
      },
      "Limit": {
        "Enable": true,
        "TagLimits": [
          {
            "channel": "*",
            "router": "*",
            "timeSpan": "1",//限流周期单位秒
            "rps": 100,//周期内通过的请求个数
            "limitSize": 100//令牌桶,漏桶池子大小
          }
        ],
        "IpLimit": {//ip限流
          "timeSpan": 1,//限流周期单位秒
          "rps": 100,//周期内通过的请求个数
          "limitSize": 100//池子大小
        },
        "White": [//白名单 用法可以参考IPAddressRange
          "0.0.0.1",
          "192.168.1.2",
          "192.168.2.18"
        ],
        "Black": [//黑名单
          "0.0.0.2",
          "192.168.3.18"
        ]
      }
    }

    Limit.Enable:是否启用限流

    Limit.TagLimits:根据Tag限流

    channel: Anno.Plugs.Logic//请求tag 必须参数
    router: Platform      //模块名称(没有Module) 必须参数
    method: GetFunc      //模块方法 必须参数
    profile: fSFhFv5d4ZlC/JTz1EvoBDNWTr+sNtAhKWTuykqfZHU2oB8/W7aUayqsXmFJXPlR
    uname: yrm

    Limit.IpLimit:根据客户端Ip限流

    Limit.White:白名单

    Limit.IpLimit:黑名单

     关于更多的Viper限流细节可参考github:https://github.com/duyanming/Viper/blob/master/Viper/Extensions/Middleware/DymWebHostBuilderExtensions.cs

     以上分享了,Viper网关的限流。后面分享每个微服务如何通过注解方式限流、以及请求缓存、ViperService的 全局过滤器、模块过滤器、方法过滤器。

    过滤器类型有,授权过滤器、异常过滤器、Action过滤器。 Anno.EngineData.Filters

    两种常用算法

    令牌桶(Token Bucket)和漏桶(leaky bucket)是 最常用的两种限流的算法。

    令牌桶主要是控制注入的速度,漏桶则是控制出的速度。

    漏桶算法

    令牌桶算法

    关于更多限流只是可参考:

    张善友博客:https://www.cnblogs.com/shanyou/p/4280546.html

    凌晨三点半:https://www.cnblogs.com/vveiliang/p/9049393.html

     Viper

    github:
    https://github.com/duyanming/Viper
    文档地址:
    https://duyanming.github.io/

    体验地址:(体验用户为anno 密码123456 同一时间一个用户只能在一个终端登录用户多的时候可能发生强制退出的情况,稍后登录体验)
    http://140.143.207.244/

    关于Viper的更多内容,随后更新。敬请关注。开源不易,感谢Star。

  • 相关阅读:
    "字符反向拼接"组件:<reverse> —— 快应用组件库H-UI
    "首字母变大写"组件:<capitalize> —— 快应用组件库H-UI
    "字母全变大写"组件:<uppercase> —— 快应用组件库H-UI
    "字母全变小写"组件:<lowercase> —— 快应用组件库H-UI
    "多行文本"组件:<multi> —— 快应用组件库H-UI
    "斜体显示"组件:<i> —— 快应用组件库H-UI
    捕捉AVPlayerViewController 系统原生工具栏的出现、隐藏事件
    (简单实用)Android支付宝商家收款语音播报
    使用wkwebview时,push后,再pop返回,报错
    安卓进度条两边圆角+渐变的拓展
  • 原文地址:https://www.cnblogs.com/duyanming/p/13846451.html
Copyright © 2011-2022 走看看