【运维】第04课:入口网关服务注册发现-Openrety 动态 uptream

本课时,我将带你一起了解入口网关服务的注册发现,并使用 OpenResty 实现一套动态 Upstream。

课前学习提示

基于本课时我们将要学习的内容,我建议你课前先了解一下 Nginx 的基础,同时熟悉基础的 Lua 语言语法,另外再回顾一下 HTTP 的请求过程,对于 Nginx 的负载均衡基本原理也要有基础的了解,掌握这些对我们学习此课时能起到一定的帮助。

关于本课时的内容,我用思维导图来先给你做一个整体的介绍:

首先,我会讲解动态 Upstream 的实现意义和场景,以及企业常见的基于开源实现方式。同时还会摘选其中一种实现方式,也就是基于 OpenResty 实现动态 Upstream 的案例进行演示。

动态 Upstream 场景

首先,我们来讲解第一部分内容,也就是动态 Upstream 的场景。

我们先来看一下这样一个典型的场景,整体了解动态 Upstream 的作用。

在这里插入图片描述

从图中流量的整体入口开始看,流量从左上方按照箭头方向访问站点,最先交给第一级服务 Nginx,Nginx 承担入口网关的作用,通常情况下,通过 Nginx Upstream来作负载均衡,从而实现将入口的流量均匀地分配给后台的 real server处理。

从图中我们可以看到,右上角的方框中有两台 Real server ,分别是 App server 1 和 App server 2。

那我们需要的动态 Upstream 是一个什么场景呢?当往这组集群中再添加一台新的后台服务 real server,也就是 App server 3 ,并且实现将入口的流量动态的(非手动方式)分发给新 App server 3,这个时候我们就需要用到动态配置upstream了。

动态 Upstream 实现意义

那么实现动态 Upstream 有什么好处呢?

再结合在上面的场景,要实现动态upsteam,首先后台服务节点App server 1 和 App server 2 ,它们将自己的信息(如:负载情况、服务状态情况、连接信息、服务名称等)实时的上报给管理中心,使得管理中心会收集 App server 1 和 App server 2 的节点状态,同时管理中心也会根据自身的策略动态地调整 Nginx 的 Upstream 配置。

假如当某一个Real server的负载过高,此时便可以通过管理中心去动态地调整 Nginx 的 Upstream 策略,入口网关动态地添加新的节点从而实时性的实现Real server资源水平的扩容,反之实现动态减少后台节点也是同样原理。这样的场景中作到及时调整upstream策略,从而使得入口网关动态分流,实现及时资源缩容和故障感知。

这个场景中,如果upstream配置不是通过动态的方式去实现调整,就需要通过手动的方式(先修改配置,再手工重启服务等),手动的方式没法作到自动化及实时触发调整。

在这里插入图片描述

我们再看一个常见的 K8s 的入口网关架构,这里就使用了动态 Upstream。我们知道 K8s + Docker 的服务部署模式下,ETCD 作为服务注册发现中的 KV存储数据库,存取着后台节点服务的注册信息,包含服务名称、连接方式等。所以,在图中会把所有后台的 服务节点(App1-App4) 的信息注册到 ETCD 的数据库中存储。然后 入口网关(如:Nginx) 通过查看etcd中数据并根据变化情况动态地调整 Upstream 配置,这个就是在K8S中动态入口网关理论原理。

图中上面的箭头表示一个服务的注册和动态的 Upstream 更新配置文件。下面的箭头表示动态的实现负载均衡策略流量转发,这个就是在 K8s 和 Docker 的部署场景中入口网关的实现原理。

动态 Upsteam 实现方式

那么,动态 Upstream 的实现方式都有哪些呢?下面我给你具体讲解一下。

我们知道Nginx 本身诞生的比 K8s 和 Docker 更早,Nginx 默认的配置模块是有来实现动态Upstream 是有局限的,这也是上一讲中我所认为Nginx存在缺陷,所以我们想要实现,通常有这么几种方式:

在这里插入图片描述

第一种方式是通过 Nginx+Lua,使用 Lua 语言开发接口,做到动态调用,也就是基于 Openresty 动态实现 Upstream,因为我们知道 Openresty 服务本身就是基于 Nginx 和 Lua 的一个结合体。

第二种方式是通过已经开源并成熟的组件,如 confd 工具或 国内某大公司开源的 nginx-upsync-module 的模块来实现动态 Upstream。

第三种方式是通过一个独立的入口网关把 Nginx 完全替换掉,比如我们现在了解的 Kong 网关还有 Traefik,都是在 K8s 中支持云原生的非常好的网关服务。

那我总结的实现方式有以上三种,接下来本课时我们来演示 Openresty 动态 Upstream 方案,使用 Lua 语言开发一套动态的接口,我们可以动态地调用接口实现一个动态的分流。

这个方案中实现了3个接口,让 Openresty 支持添加、删除、监控 Upstream 后台节点的功能(如图接口1-接口3)。

我们看下如图描述的内容:

在这里插入图片描述

通过开放接口,管理中心或者配置中心用可以调用这三个接口动态修改入口网关的负载均衡配置。我们接下来重点介绍Openresty Lua 语言如何开发实现这三个接口。

在正式演示之前再带你熟悉一下 Openresty。Openresty 是一个基于 Nginx 与 Lua 开发的高性能web平台,内部集成了大量的 Lua 库和第三方模块,如果使用Nginx则需要通过 Nginx 编译 Lua 模块非常繁琐,所以需要支持LUA直接使用 Openresty 就可以了。

大家用浏览器打开 Openresty 的官方网站(https://openresty.org/cn/),你可以看到 Openresty 的官方文档,同时因为本课时会作 Openresty 的演示,如果你希望模拟安装,可以按照官网的方式来进行安装。

同样,接下来演示案例也用到了Nginx模拟后台服务,Nginx 的安装建议你参考官方的安装方式,这里可以通过 官方提供yum 源的方式来安装 Nginx。

演示

接下来演示这个动态 Upstream, 分为三大部分进行讲解。

  • 第一部分是安装流程;
  • 第二部分是配置方式;
  • 第三部分是测试;

现在,我登录到一台虚拟主机上,来具体演示 Openresty 如何实现动态 Upstream。首先,我们需要安装 Nginx 和 Openresty,你可以参考官方文档来自行安装。

然后配置 Nginx 服务,Nginx这里作用不是作代理入口,而是 在整个演示场景的 real server 节点,我们需要模拟三个端口的后台服务。通过 Openresty 来负责作代理网关并负载均衡,所以我们可以配置一个基于 Nginx 的虚拟端口的虚拟主机。这里我做了三份配置文件 81、82、83,三份配置文件分别占用三个端口,然后我们可以自己参考这三个配置文件来进行配置,然后启用 Nginx。

启用 Nginx 后会占用 81、82、83 三个端口,我们还可以用浏览器来访问这三个端口。访问 83 端口时会显示一个 Server 3 和 url 3 的黄色的页面。然后我们访问 82 端口,显示的是 Server 2 和 url 2 的红色背景页面信息。访问 81 端口时显示的是 Server 1 和 url 1 的蓝色文字背景信息。这就是后台提供的三个 HTTP 服务,已经分别都做好了,然后我们需要配置 Openresty 的 Upstream 。

cd到 Openresty 的目录下,然后 cd 到 Nginx 目录,Nginx 的 conf 目录下有一个 Nginx.conf 文件,这是一个 Openresty 的主配置文件。同一级的 Nginx 目录下还有一个 ngx_lua 配置目录,这里已经放好了lua开发的代码文件。

这个目录是我自定义新建的,里面有三个脚本;upsops 是用来做动态调节 Upstream 节点信息的接口代码;upstream.lua 是用来设置负载均衡策略的代码,另外一个是实现节点信息获取的代码。

那么我们来看 openresty 服务的配置 nginx.conf 中,分别对这三个代码文件做了引用,配置会对外提供几个访问路径,其中一个是根的访问路径,也就是对外提供服务的访问路径,一个是 location=/ups一会我们拿这个重点讲解这个,它是实现动态更新配置 Upstream 主机节点信息的接口。

往上会看到我的 location 对外提供服务的时候,会引用到 proxy_pass 的本地的一组服务单元。服务单元分别配置了三台主机,也就是我们刚刚配置的三台 Nginx 虚拟主机的连接信息,然后后面的 balancer_by_lua_flie 就是修改了默认的配置负载均衡策略。

好,我们重点看upsops.lua 脚本的实现逻辑是什么样子的?我们来看一下。当用户请求这个路径是 ups 的时候,它会交给 Lua 解析处理。然后到 ngx_lua 目录下我们打开文件(upsops.lua )看一下,在最上面定义了一些本地的变量,有获取请求的参数,客户端的请求方法赋值给了 OP。

OP 主要是有哪两个方法呢?这个接口代码支持是增加(add)\删除(del)两个,这里会先获取所有主机的 Upstream 的服务节点,客户端通过发送put 请求传递过来的需要添加或者删除的新节点的信息,然后传递给 变量server ,这里会判断一个请求是否有带参数,并进行一个校验,接着还会关联一个独立的函数【function down_server(upstream_name,server)】。这里会用来判断一个逻辑,这个逻辑用来控制在 Upstream 后台 Real server 里最少应该保持一台主机,如果低于一台的话是不允许的,现实中如果upstream的后台服务节点数不可能为零。

代码最后会去判断客户端传递过来的操作方法(OP),是选择增加 Upstream 节点,还是删除 Upstream 节点,如果在删除节点时候会调用 down_server 的方法判断,判断它是不是符合至少保留一个节点的要求。

整体上,我们看到删除和添加成功后都会有对应的提示,如果有错误的话也会暴露出对应的错误信息,如果你看到对应的错误代码,可以分析具体的原因。

这就是整个 upsops.lua代码 中的大概逻辑,现在我们可以启用 Openresty 来简单做一个测试。

先关闭之前的服务,然后再启动。这个时候会看到暴露出一个 800 端口,这个就是 Openresty 占用的端口,我们可以通过 800 端口来进行访问测试。

首先显示的是一个蓝色的页面,我们再来刷新这个页面,第 2 次的时候会出现 server 2 url 2,再刷就会到 server 3 url 3 了,所以我们会看到它是一个因为配置负载均衡而轮循展示。

接下来我们可以删除一台主机,调用刚刚讲到的 upsops 脚本里面暴露出来的 ups 接口。我们用 curl 命令来模拟一个 put 的方法,-v 显示整个的请求过程,后面就是请求的链接,ups 就是我们刚请求的接口路径,然后 op=add 就是选择添加主机操作。这里,我们先删除一台主机,选择删除 83 端口节点,然后回车。

这个时候会看到返回的是 200 的状态码,并且会有一个提示删除 83 端口的后台服务成功。这个时候我们再来刷新页面,看看 server 3 还会不会再出现,我们可以多刷新几次。这个时候会发现我的浏览器会停留在 server 1 和 url 2 间进行不断的变更,而不会出现 server 3(对应 83 端口的服务)。

同样我们来演示如何把 server 3 加回来,也就是 端口为 83 节点的信息加回来,这时我们把 op后的操作改成 add。这时同样也会返回正确的提示。同样,再到浏览器端中看一下。这个时候 server 3 就加回来了。

你有没有发现,整个过程都是通过调用接口来实现的,也就是说我们要模拟动态发现的时候,其实就可以在管理或者注册中心节点,通过调用这种 HTTP API 接口的方式来动态的调用upstream配置。这个演示大家可以按照我给的这些脚自己模拟。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

iHero

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值