基于Nginx dyups模块的站点动态上下线

简介

今天主要讨论一下,对于分布式服务,站点如何平滑的上下线问题。

分布式服务

在分布式服务下,我们会用nginx做负载均衡, 业务站点访问某服务站点的时候, 统一走nginx, 然后nginx根据一定的轮询策略,将请求路由到后端一台指定的服务器上。

这样的架构是没有问题的, 但是我们这里考虑几个问题,

1. 网站上下线问题:我们网站平时更新站点的时候是直接覆盖文件,然后重启, 那这样会造成一些请求中断,如果是非核心逻辑那还好, 如果是核心逻辑,那请求中断,会影响一些数据一致性,比如资金, 交易,订单等。

2. 动态加减机器,比如某个站点访问量大,要新增机器,那就需要修改nginx的配置,然后reload, 这样会中断连接。 虽然reload很快,但是还是会有一瞬间的请求中断。

对于第一个问题,我们可以在请求量少的时候去更新, 但是这种在一些服务稳定的公司可用, 对于互联网企业,可能2-3天就一个版本, 而且需要立刻上线, 如果每次都要等到凌晨4点去更新, 可能整个的开发节奏都被带慢了。

对于第二个问题, 对于可以预见的流量,比如大促来临,可以提前3天放在请求量少的时候更新。

最近几年,随着SOA的普及和微服务的出现,特别是dubbo的出现,服务治理的概念被提出来。 服务治理是一个很宏大的概念,包括服务注册,服务自动发现,服务路由,服务依赖,集群容错,服务降级,服务监测,服务审批等,当然不是每个服务中心都必须实现这些东西, 公司可以根据自己的实际需求来定制实现。

基于Nginx dyups模块的动态上下线

基于以上这些情况, 我计划实现一个工具,这个工具首先解决站点上下线和动态扩容问题,也就是说在不需要重启nginx的情况下,并且在保证请求不丢失的情况下来更新站点。 同时带有部分服务治理功能。

服务上线

1. 在一个新服务上线的时候,一般会提前申请几台机器, 运维会在nginx上新增server,并新增server对应的upstream ,正常情况下upstream应该配置是后端服务器的IP,但是这里不配置(如果允许,甚至这一步都可以省略)。

2. 服务部署好并启动,在启动的时候,向注册中心注册自身的服务信息,包括IP和端口。

3. 注册中心收到请求后,会对服务进行健康检测,确保提供的服务没有问题,则将服务状态标示为预上线状态。

4. 在后台管理中心,就可以将预上线的服务设置为上线,服务管理中心会调用nginx的上线接口,将服务IP新增或者更新到upstream中,服务就可以提供访问。

服务更新

假如我们现在有一个服务需要更新,则执行以下步骤:

1. 在后台管理中心,将一个服务设为下线,此时服务中心会调用nginx的下线接口,将指定服务器的IP设置为下线。

2. 在等待1分钟后,确保没有新连接连过来,则可以开始更新服务站点。

3. 更新完毕后,再手动设为上线,此时服务中心会调用nginx的上线接口,将指定服务器的IP设置为上线。当然对于成熟的服务,这些都可以自动化,有些公司会有一些自动化发布工具, 与自动化发布工具集成,可以一键下线,更新并上线。

服务运行期间

在服务运行过程中,会有一个健康检测的服务对所有提供服务的站点进行健康检测,一旦检测到有问题,就执行下线逻辑。 直到问题被解决,最后执行上线流程。

动态加减机器

在服务运行过程中,可能因为某些原因,服务请求飙高(前提是这些请求都是合法的),超过了当前集群的承载能力,当系统检测到这些情况后,可以动态扩充机器,比如现在流行的docker,在启动容器的时候,同时启动应用,应用在启动的时候,将自身信息注册给注册中心,注册中心再将这些信息同步到nginx,应用就可以提供访问,整体上就可以实现弹性计算。

为什么不实现服务动态发现?

这里可以看到图中已经有一个服务注册中心。 既然有了服务注册中心了, 那可以让业务站点连接服务注册中心来获取真实的服务IP,然后绕过nginx来连接服务,这里之所以没有这样做,是因为:

1.  实现服务动态发现,这个需要和RPC框架配合,而且需要做服务的软负载,失败重连,限流等,整个项目设计就上升了一个复杂度, 考虑到有些项目还未使用RPC,并且不想对原有的项目有过多的侵入, 所以这里不做实现。 但是并不意味没有这些功能,服务的负载, 失败重连, 限流,其实这些功能在nginx中同样也有,可以直接使用,所以没有必要重新再开发。

2.  实现服务动态发现,获取到真实的服务IP,然后直连,这些一般是在流量特别大,nginx上出现短板的时候使用,但实际情况,一般很少会耗尽nginx的性能,即使有,也可以通过ngxin水平扩展来实现,所以这里依然使用nginx作为负载均衡。

这里讲一下这个项目的关键点:

1. 服务的注册和健康检测这个没有技术难点,这里不做解释。

2. 关于操作nginx上下线,这里的确是一个难点,因为nginx本身并没有提供这些上下线API,需要openresty并配合一些第三方扩展来实现。 这里主要用到了两个扩展模块:ngx_http_dyups_module  lua-upstream-nginx-module

ngx_http_dyups_module(https://github.com/yzprofile/ngx_http_dyups_module)提供了粗粒度的upstream管理方法,可以对整个upstream进行新增,删除。

lua-upstream-nginx-module(https://github.com/openresty/lua-upstream-nginx-module) ,则提供了细粒度的管理方式,可以对某一个服务IP进行管理,其中提供的set_peer_down方法,可以对upstream中的某个ip进行上下线。

3. 也可以使用ngx_dynamic_upstream(https://github.com/cubicdaiya/ngx_dynamic_upstream)

这些插件有一个共同点,那就是在不需要重启nginx的基础上, 动态修改nginx的配置。

后记

1. 最后我想请大伙讨论一下,你们公司是怎么上下线的, 是直接覆盖,还是有其他策略。 欢迎在评论区讨论。

时间: 2024-08-02 19:07:06

基于Nginx dyups模块的站点动态上下线的相关文章

5.zookeeper应用案例之分布式服务器动态上下线感知

zookeeper应用案例之分布式服务器动态上下线感知,当服务器上线和下线时候客户端都能感知到,还有哪些机器在线.并对zookeeper管理的服务器进行节点的监听; 代码实现:客户端 每当服务端有服务器上线或下线 在客户端都能通过监听感知到 package org.zookeeper.anli; import java.util.ArrayList; import java.util.List; import org.apache.zookeeper.WatchedEvent; import o

动态上下线集群详解

动态上下线集群的一些配置: 1.namenode中 hdfs-site.xml 配置 <property> <name>dfs.hosts</name> <value>/ddmap/hadoop-1.0.4/conf/hdfs_include</value> </property> <property> <name>dfs.hosts.exclude</name> <value>/ddm

ZooKeeper之服务器动态上下线案例

需求 某分布式系统中,主节点可以有多台,可以动态上下线,任意一台客户端都能实时感知到主节点服务器的上下线. 需求分析 具体实现 先在集群上创建/servers节点 create /servers "servers" 一些依赖 pom.xml: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance&q

基于nginx和uWSGI在Ubuntu系统上部署Django项目

1. nginx1.1 安装sudo apt-get install nginx1.2启动.停止和重启sudo /etc/init.d/nginx startsudo /etc/init.d/nginx stopsudo /etc/init.d/nginx restart或者sudo service nginx startsudo service nginx stopsudo service nginx restart2. uWSGI安装用python的pip安装最简单:apt-get inst

面试题笔记:实现Nginx Upload 模块 功能上传文件。

linux服务器开发测评题目———————————————————————————— 搭建一个nginx服务器,能完成文件上传功能.主要构成有: <1> 用于测试服务器上传功能用的前端html页面 <2> nginx web服务器,包括了文件上传功能模块,注意配置好配置文件 <3> 对于上传成功的文件,给前端返回upload successfully信息 动手搭建完成后,针对上面的几点要求截几张图,同时把前端html页面,nginx配置文件,和假如需要使用的业务逻辑代码

[Nginx配置系列] 基于Nginx Geo与 Nginx Map模块进行Nginx白名单配置

一.简介 在通常情况下,使用 nginx 基于 ip 限制访问请求频率等限制内容,我们会需要对特定ip进行限制排除操作,因此本文引入了基于nginx geo 与 nginx map 进行此类情景相关配置: 在没有人为操作删除的情况下(without-http_geo_module),nginx默认模块中已经加载了ngx-http-geo-module相关内容: ngx-http-geo-module可以用来创建变量,变量值依赖于客户端 ip 地址; ngx-http-map-module可以基于

基于Nginx反向代理及负载均衡

基于Nginx反向代理及负载均衡 参考:http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass 只要没有被启用,默认就是开启的,因为proxy属于nginx内置标准模块,通常实现代理的时候,最核心模块是proxy_pass,用于将用户请求的rui递交至上游服务器的某个URI但这个模块大部分用于location当中,因此要实现将某一URI的访问代理某个上游服务器大致的格式为: location /name/ { pro

linux学习笔记——搭建基于nginx的web服务器、多核配置、nginx配置参数

############ 认识nginx #############Nginx:(发音同 engine x)是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行.由俄罗斯的程序设计师Igor Sysoev所开发,最初供俄国大型的入口网站及搜寻引擎Rambler(俄文:Рамблер)使用.  其优点是轻量级(占有内存少),高并发(并发能力强),事实上nginx的并发能力确实在同类型的网页伺服器中表现较好.目前中国大陆使用ngi

Nginx学习笔记六Nginx的模块开发

1.Nginx配置文件主要组成:main(全局配置)这部分的指令将影响其他所有部分.server(虚拟主机配置)这部分指令主要用于指定虚拟主机域名,IP和端口.upstream(主要为反向代理,负载均衡相关配置)这部分指令用于设置反向代理及后端服务 器的负载均衡.location(目录匹配配置)这部分指令用于匹配网页位置(例如,根目录"/","/images",等 等). location部分会继承server部分的指令,而server部分会继承main部分的指令.