• .Net Core 3.1 -- APISIX2.6 微服务网关入门


    前言:

    (1)Apache APISIX是一个动态的、实时的、高性能的 API 网关。它提供丰富的流量管理功能,例如负载均衡、动态上游服务、金丝雀发布、断路、身份验证、可观察性等。您可以使用 Apache APISIX 来处理传统的南北流量,以及服务之间的东西流量。它也可以用作 k8s ingress controller。这个作为微服务网关十分重要

    它是国人开源,目前已经进入 Apache 进行孵化,社区活跃,文档详细友好,厉害!!!

    APISIX地址:https://github.com/apache/apisixDashBoard:https://github.com/apache/apisix-dashboard

    文档地址:https://apisix.apache.org/zh/docs/apisix/architecture-design/apisix

    (2)APISIX 通过插件机制,提供了动态负载均衡、身份验证、限流限速等等功能,当然我们也可以自己开发插件进行拓展。更多的特性大家可以自行去了解一下

    (3)Apache APISIX 的技术架构:

    图片来源:APISIX 官网

    下面,让我们快速进入APISIX的 极简入门。

    1、快速安装

    《APISIX 官方文档 —— 安装》中,介绍了源码包、RPM 包、Docker 三种安装方式。这里我们使用 CentOS 7.9 系统,所以采用 RPM 包。

    因为 APISIX 是基于 OpenResty + etcd 来实现,所以需要安装响应的依赖。

    1.1 安装相关依赖

    # install etcd
    wget https://github.com/etcd-io/etcd/releases/download/v3.4.13/etcd-v3.4.13-linux-amd64.tar.gz
    tar -xvf etcd-v3.4.13-linux-amd64.tar.gz && 
        cd etcd-v3.4.13-linux-amd64 && 
        sudo cp -a etcd etcdctl /usr/bin/
    
    # add OpenResty source
    sudo yum install yum-utils
    sudo yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo
    
    # install OpenResty and some compilation tools
    sudo yum install -y openresty curl git gcc openresty-openssl111-devel unzip
    
    # install LuaRocks
    curl https://raw.githubusercontent.com/apache/apisix/master/utils/linux-install-luarocks.sh -sL | bash -
    
    # start etcd server
    nohup etcd &

    检查下ETCD 是否启动成功:

    1.2 安装APISIX

    $ sudo yum install -y https://github.com/apache/apisix/releases/download/2.6/apisix-2.6-0.x86_64.rpm
    

    检查一下APISIX版本:

    启动APISIX服务:

    默认会安装在/usr/local/apisix路径下,默认端口9080,可通过如下命令检查:

    1.3 APISIX dashboard(控制台)安装

    参考文档:

    https://github.com/apache/apisix-dashboard

    (1)git获取源码:

    $ git clone https://github.com/apache/incubator-apisix-dashboard.git
    $ cd incubator-apisix-dashboard

    切换分支版本,需要与apisix版本一致即可

    $ git checkout -b release/2.6 origin/release/2.6

    (2)构建控制流:manager-api

    控制流用于为控制台提供接口,相当于在APISIX与控制台之间的桥梁。手动构建需要如下步骤:1.需要事先装好 Go 1.13+注意:如果你想使用Orchestration的插件功能,需要安装Lua 5.1+已上版本。

    $ wget https://dl.google.com/go/go1.16.5.linux-amd64.tar.gz
    $ tar -C /usr/local -xzvf go1.16.5.linux-amd64.tar.gz
    -- 
    $ export PATH=$PATH:/usr/local/go/bin
    $ source /etc/profile

    检查环境变量:

    -- enable Go MODULE
    $ go env -w GO111MODULE=on
    
    -- 对于我们国内用户,可以设置Goproxy代理加速下载模块
    $ go env -w GOPROXY=https://goproxy.cn,direct
    

    (3)构建

    执行下面的命令:

    $ ./api/build.sh

    注意:如果执行上面的命令 会超时,可以单独把wget + 后面的链接复制出来,独立执行就可以了。

    (3)构建web

    确保机器上的Node.js版本在10.0.0+已上,执行下面的命令

    $ curl -sL https://rpm.nodesource.com/setup_16.x | sudo bash -
    $ sudo yum install nodejs
    $ node --version
    $ npm --version

    安装yarn:

    $ curl -sL https://dl.yarnpkg.com/rpm/yarn.repo | sudo tee /etc/yum.repos.d/yarn.repo
    $ sudo yum install yarn
    $ sudo yum build

    安装依赖:

    接下来就是漫长的等待。。。

    (4)运行控制流 manager-api

    [root@iZhp33yk3z4ttlhta3t5tkZ incubator-apisix-dashboard]# ./api/run.sh &

    根据提示,创建对应的文件夹:logs

    重新执行上面的命令:./api/run.sh &

    然后,我们直接:公网IP:9000,就可以访问 Dashboard,显示这样的界面时,解决方案:

    https://github.com/apache/apisix-dashboard/blob/master/docs/en/latest/FAQ.md

    修改:/root/incubator-apisix-dashboard/output/conf/

    注意:生产环境不能这样设置!!!

    杀掉 manager-api 进程后

    再重新启动一下:

    ./api/run.sh &

    账号密码都是 admin

    2、快速实践

    创建2个netcore 3.1 的项目(注意:需要安装对应的.net core sdk)

    启动 5000端口的app:

    启动 5001端口的app:

    2.1 动态负载均衡

    (1)创建 APISIX Upstream

    在 APISIX 控制台的「上游」菜单中,创建一个 APISIX Upstream。如下图所示:

    点击下一步,最后点击 提交,即可。

    (2)创建 APISIX Route

    APISIX Route,字面意思就是路由,通过定义一些规则来匹配客户端的请求,然后根据匹配结果加载并执行相应的 插件,并把请求转发给到指定 Upstream。

    点击下一步,选择上游服务:

    点击下一步,关于插件部门后面的问题后续会陆续更新。

    最后点击提交即可:

    (3)简单测试:

    现在,我们来请求 APISIX 网关,转发请求到后端服务。

    浏览器中输入:

    从结果可以看出,APISIX 网关使用带权轮询算法(Round Robin),将请求轮流转发到后端服务。博客已搬家到Infoq, 欢迎大家关注!

    2.2 限流限速

    2.2.1 原理

    在大规模微服务架构的场景下,避免服务出现雪崩,要减少停机时间,要尽可能的提高服务可用性。

    提高服务可用性,可以从很多方向入手,比如缓存、池化、异步化、负载均衡、队列和降级熔断等手段。

    缓存以及队列等手段,增加系统的容量。限流和降级则是关心在到达系统瓶颈时系统的响应,更看重稳定性。

    限流顾名思义,提前对各个类型的请求设置最高的 QPS 阈值,若高于设置的阈值则对该请求直接返回,不再调用后续资源。

    限流需要结合压测等,了解系统的最高水位,也是在实际开发中应用最多的一种稳定性保障手段。

    降级则是当服务器压力剧增的情况下,根据当前业务情况及流量对一些服务和页面有策略的降级,以此释放服务器资源以保证核心任务的正常运行。

    从降级配置方式上,降级一般可以分为主动降级和自动降级。主动降级是提前配置,自动降级则是系统发生故障时,如超时或者频繁失败,自动降级。

    本小结,我们来聊聊目前常见的限流算法。

    (1)计数器

    假设一个接口限制一分钟内的访问次数不能超过 100 个,维护一个计数器,每次有新的请求过来,计数器加一。

    这时候判断,如果计数器的值小于限流值,并且与上一次请求的时间间隔还在一分钟内,允许请求通过,否则拒绝请求,如果超出了时间间隔,要将计数器清零。

    计数器限流可以比较容易的应用在分布式环境中,用一个单点的存储来保存计数值,比如用 Redis,并且设置自动过期时间,这时候就可以统计整个集群的流量,并且进行限流。

    计数器方式的缺点是不能处理临界问题,或者说限流策略不够平滑。

    假设在限流临界点的前后,分别发送 100 个请求,实际上在计数器置 0 前后的极短时间里,处理了 200 个请求,这是一个瞬时的高峰,可能会超过系统的限制。

    计数器限流允许出现 2*permitsPerSecond 的突发流量,可以使用滑动窗口算法去优化,具体不展开。

    (2)漏桶算法

    假设我们有一个固定容量的桶,桶底部可以漏水(忽略气压等,不是物理问题),并且这个漏水的速率可控的,那么我们可以通过这个桶来控制请求速度,也就是漏水的速度。

    我们不关心流进来的水,也就是外部请求有多少,桶满了之后,多余的水会溢出。如下图所示:

    将算法中的水换成实际应用中的请求,可以看到漏桶算法从入口限制了请求的速度。

    使用漏桶算法,我们可以保证接口会以一个常速速率来处理请求,所以漏桶算法不会出现临界问题。

    (3)令牌桶算法

    漏桶是控制水流入的速度,令牌桶则是控制留出,通过控制 Token,调节流量。

     假设一个大小恒定的桶,桶里存放着令牌(Token)。桶一开始是空的,现在以一个固定的速率往桶里填充,直到达到桶的容量,多余的令牌将会被丢弃。

     如果令牌不被消耗,或者被消耗的速度小于产生的速度,令牌就会不断地增多,直到把桶填满。后面再产生的令牌就会从桶中溢出。

    最后桶中可以保存的最大令牌数永远不会超过桶的大小,每当一个请求过来时,就会尝试从桶里移除一个令牌,如果没有令牌的话,请求无法通过。

    C# 代码实现
    public  class TokenBucketLimiter
        {
    
            private long Capacity;//桶的容量,也就是令牌的数量
            private long WindowTimeInSeconds;
            private long LastRefillTimeStamp;
            private long RefillCountPerSecond;
            private long AvailableTokens;
    
            public TokenBucketLimiter(long capacity, long windowTimeInSeconds)
            {
                this.Capacity = capacity;//200
                this.WindowTimeInSeconds = windowTimeInSeconds;//60
                this.LastRefillTimeStamp = DateTime.Now.Ticks / 10000; //63751161398349
                this.RefillCountPerSecond = capacity / windowTimeInSeconds; //200 / 60
                this.AvailableTokens = 0;
            }
    
            public  long GetAvailableTokens()
            {
                return this.AvailableTokens;
            }
    
            public bool TryAcquire()
            {
                //更新令牌桶
                Refill();
    
                if (AvailableTokens > 0)
                {
                    --AvailableTokens;
                    return true;
                }
                else
                {
                    return false;
                }
            }
    
            private void Refill()
            {
                long now = DateTime.Now.Ticks / 10000;
    
                if (now > LastRefillTimeStamp)
                {
    
                    long elapsedTime = now - LastRefillTimeStamp;
    
                    int tokensToBeAdded = (int)((elapsedTime / 1000) * RefillCountPerSecond);
    
                    if (tokensToBeAdded > 0)
                    {
                        AvailableTokens = Math.Min(Capacity, AvailableTokens + tokensToBeAdded);
                        LastRefillTimeStamp = now;
                    }
                }
                //
            }
        }
    

    这两种算法的主要区别在于漏桶算法能够强行限制数据的传输速率,而令牌桶算法在能够限制数据的平均传输速率外,还允许某种程度的突发传输。

    在令牌桶算法中,只要令牌桶中存在令牌,那么就允许突发地传输数据直到达到用户配置的门限,因此它适合于具有突发特性的流量。

    总结:漏通和令牌通算法比较

    漏桶和令牌桶算法实现可以一样,但是方向是相反的,对于相同的参数得到的限流效果是一样的。

    主要区别在于令牌桶允许一定程度的突发,漏桶主要目的是平滑流入速率,考虑一个临界场景,令牌桶内积累了 100 个 Token,可以在一瞬间通过。

     但是因为下一秒产生 Token 的速度是固定的,所以令牌桶允许出现瞬间出现 permitsPerSecond 的流量,但是不会出现 2*permitsPerSecond 的流量,漏桶的速度则始终是平滑的。

    2.2.2 APISIX 使用

    注意:上述配置限制了每秒请求速率为 1,大于 1 小于 3 的会被加上延时,速率超过 3 就会被拒绝,返回503。

    只要你手速够快,就可以看到这样的返回结果,说明,成功被APISIX限流。

    官网中对参数的介绍:

    好了,暂时先了解到这里,后面还会陆续更新APISIX 相关的实战经验,想要详细了解的朋友,可以到官网深入学习,因为是国产开源APISIX网关,文档非常友好!

    参考资料:
    (1)https://apisix.apache.org/docs/apisix/FAQ/

    (2)https://github.com/apache/apisix

    (3)https://github.com/apache/apisix-dashboard

    作者:郭峥

    出处:http://www.cnblogs.com/runningsmallguo/

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

  • 相关阅读:
    《objective-c基础教程》学习笔记(三)—— 从结构体到面向对象
    《objective-c基础教程》学习笔记(二)—— for循环的基本应用
    《objective-c基础教程》学习笔记 (一)—— 开发环境配置和简单类型输出
    asp.net mvc 3.0 知识点整理 ----- (4).asp.net mvc 3 和asp.net mvc 4 对比
    git简单使用(上篇)
    git简单使用(下篇)
    Spring核心概念之Ioc
    "注解"的用法
    struts2进阶篇(3)
    struts2进阶篇(2)
  • 原文地址:https://www.cnblogs.com/runningsmallguo/p/14861017.html
Copyright © 2020-2023  润新知