写点什么

APISIX2.6 微服务网关入门

发布于: 2021 年 06 月 07 日

前言:

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

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

APISIX 地址:https://github.com/apache/apisix

DashBoard(2.6):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 etcdwget https://github.com/etcd-io/etcd/releases/download/v3.4.13/etcd-v3.4.13-linux-amd64.tar.gztar -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 sourcesudo yum install yum-utilssudo yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo
# install OpenResty and some compilation toolssudo yum install -y openresty curl git gcc openresty-openssl111-devel unzip
# install LuaRockscurl https://raw.githubusercontent.com/apache/apisix/master/utils/linux-install-luarocks.sh -sL | bash -
# start etcd servernohup 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),将请求轮流转发到后端服务。

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

发布于: 2021 年 06 月 07 日阅读数: 96
用户头像

还未添加个人签名 2019.09.03 加入

还未添加个人简介

评论

发布
暂无评论
APISIX2.6微服务网关入门