基于Nginx dyups模块的站点动态上下线并实现简单服务治理
原文连接:http://www.cnblogs.com/beyondbit/p/6063132.html
简介
今天主要讨论一下,对于分布式服务,站点如何平滑的上下线问题。
分布式服务
在分布式服务下,我们会用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. 最后我想请大伙讨论一下,你们公司是怎么上下线的, 是直接覆盖,还是有其他策略。 欢迎在评论区讨论。
可以参考另一篇文章:
nginx修改upstream不重启的方法(ngx_http_dyups_module模块)
ngx_http_dyups_module带的功能我很喜欢,但是最大的不足就是不能生成配置文件,所有内容都保存在内存中,希望以后的版本能够支持。
【临时的方法是可以将数据放在redis中】
基于Nginx dyups模块的站点动态上下线并实现简单服务治理相关推荐
- 分布式服务动态上下线感知
分布式服务动态上下线感知 首先,我们要从解决问题的角度得知分布式服务的由来,从单机服务到分布式服务经历了哪些过程 起初,服务是比较单一的,在一个工程包之中会包含所有的模块,但随着互联网的快速发展,客户 ...
- hdfs haadmin使用,DataNode动态上下线,NameNode状态切换管理,数据块的balance,HA下hdfs-api变化(来自学习资料)
1.2.4集群运维测试 HA集群中两个namenode状态的管理命令 [root@mini2 hadoop-2.6.4]# bin/hdfs haadmin Usage: DFSHAAdmin [-n ...
- zookpeer实现对服务器动态上下线的监听
服务器动态上下线程序的工作机制 服务器代码: 补充:volatile关键字:java中一切都是对象,当多个线程操作同一个对象时候,该对象会放在堆内存中,而多个线程相当于在多个栈中,当A线程想要去除对象 ...
- hdfs haadmin使用,DataNode动态上下线,NameNode状态切换管理,数据块的balance,HA下hdfs-api变化(来自学习资料)...
1.2.4集群运维测试 HA集群中两个namenode状态的管理命令 [root@mini2 hadoop-2.6.4]# bin/hdfs haadmin Usage: DFSHAAdmin [-n ...
- 服务器动态上下线监听案例
服务器动态上下线监听案例 文章目录 1.需求 2.需求分析 3.编程实现 1.先在集群上创建/servers节点 2.服务器端向Zookeeper注册代码(Server) 3.客户端代码(Client ...
- Zookeeper——服务器动态上下线、客户端动态监听
文章目录: 1.前言 2.实操步骤 2.1 服务端代码 2.2 客户端代码 2.3 测试 1.前言 某分布式系统中,主节点可以有多台,可以动态上下线,任意一台客户端都能实时感知到主节点服务器的上下线. ...
- zookeeper实现服务器动态上下线,分布式锁
通过前面的Zookeeper学习,我做了几个例子来巩固以下: 1.服务器动态上下线 需求:app client可以感知到app server的上下线(app client和app server是指我们 ...
- Zookeeper服务器动态上下线idea上server类中server.regist(args[0])数组越界解决
Zookeeper服务器动态上下线idea上server类中server.regist(args[0])数组越界解决 运行server服务类时报错:Exception in thread"m ...
- java本地监听zk服务器节点【动态上下线】
[README] java本地访问 zk cluster, refer 2 https://blog.csdn.net/PacosonSWJTU/article/details/111404364 [ ...
- 干货 | 秒级上下线,携程服务注册中心架构演进
作者简介 Alex,携程资深软件工程师,关注微服务架构及分布式缓存技术. 一.前言 携程的微服务框架产品从2013年发展至今,已经历了7年多的打造.其中所使用的服务注册中心也从最开始人工数据维护架构演 ...
最新文章
- 教你用一行Python代码实现并行(附代码)
- c++读取json文件_SPARK入门 - json文件读取
- 皮一皮:这个老爸有觉悟...
- 过拟合与模型调优(part1)--过拟合,模型调优,数据分割
- 【Codeforces - 127D】Password(思维,二分+字符串Hash)
- python自动化测试框架有哪几种_Python自动化测试-Unittest单元测试框架详解
- Linux学习笔记---移植官方linux步骤(一)
- Centos7静默安装Weblogic12C
- 华为怒发公开信;锤子手机难产罗永浩陷尴尬处境;苹果错失 5G | 极客头条
- c语言输出合法的出栈算法,c语言栈的实现以及操作
- 电脑快捷键(键盘不灵了赶紧使用快捷键)
- “暴风一号”学习日记(一)
- Excel或C语言复数运算
- 信息系统项目管理师-软考-B站自学
- 我知道的几个免费的API数据接口
- 【转贴】龙芯生态产品和解决方案巡展(第四篇)——存储
- 微信小程序token过期后重新执行失效的请求封装(用户无感刷新token)
- 微信无法连接服务器1-500,GIF表情超过500kb无法添加到微信的解决方法
- 【网络】VLAN 及其配置详解
- ICCV 2021 | 视觉Transformer中的相对位置编码
热门文章
- 17.3加入知识的文本增强
- Hadoop:一文详解MapReduce的工作机制
- Machine Learning - XII. Support Vector Machines支持向量机(Week 7)
- numpy教程:随机数模块numpy.random
- json序列化_JSON 序列化和反序列化 In Go
- mysql设置主键可视化_mysql怎么设置主键自
- 解决Ubuntu18.04使用快捷键 Ctrl+Alt+T 无法打开终端的问题
- Android 属性动画(三)
- 搭建Android/Linux驱动编译开发环境篇
- 4.Scala-数据结构