原文连接: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中】

本文转自 Tenderrain 51CTO博客,原文链接:http://blog.51cto.com/tenderrain/1966423

基于Nginx dyups模块的站点动态上下线并实现简单服务治理相关推荐

  1. 分布式服务动态上下线感知

    分布式服务动态上下线感知 首先,我们要从解决问题的角度得知分布式服务的由来,从单机服务到分布式服务经历了哪些过程 起初,服务是比较单一的,在一个工程包之中会包含所有的模块,但随着互联网的快速发展,客户 ...

  2. 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 ...

  3. zookpeer实现对服务器动态上下线的监听

    服务器动态上下线程序的工作机制 服务器代码: 补充:volatile关键字:java中一切都是对象,当多个线程操作同一个对象时候,该对象会放在堆内存中,而多个线程相当于在多个栈中,当A线程想要去除对象 ...

  4. 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 ...

  5. 服务器动态上下线监听案例

    服务器动态上下线监听案例 文章目录 1.需求 2.需求分析 3.编程实现 1.先在集群上创建/servers节点 2.服务器端向Zookeeper注册代码(Server) 3.客户端代码(Client ...

  6. Zookeeper——服务器动态上下线、客户端动态监听

    文章目录: 1.前言 2.实操步骤 2.1 服务端代码 2.2 客户端代码 2.3 测试 1.前言 某分布式系统中,主节点可以有多台,可以动态上下线,任意一台客户端都能实时感知到主节点服务器的上下线. ...

  7. zookeeper实现服务器动态上下线,分布式锁

    通过前面的Zookeeper学习,我做了几个例子来巩固以下: 1.服务器动态上下线 需求:app client可以感知到app server的上下线(app client和app server是指我们 ...

  8. Zookeeper服务器动态上下线idea上server类中server.regist(args[0])数组越界解决

    Zookeeper服务器动态上下线idea上server类中server.regist(args[0])数组越界解决 运行server服务类时报错:Exception in thread"m ...

  9. java本地监听zk服务器节点【动态上下线】

    [README] java本地访问 zk cluster, refer 2 https://blog.csdn.net/PacosonSWJTU/article/details/111404364 [ ...

  10. 干货 | 秒级上下线,携程服务注册中心架构演进

    作者简介 Alex,携程资深软件工程师,关注微服务架构及分布式缓存技术. 一.前言 携程的微服务框架产品从2013年发展至今,已经历了7年多的打造.其中所使用的服务注册中心也从最开始人工数据维护架构演 ...

最新文章

  1. 教你用一行Python代码实现并行(附代码)
  2. c++读取json文件_SPARK入门 - json文件读取
  3. 皮一皮:这个老爸有觉悟...
  4. 过拟合与模型调优(part1)--过拟合,模型调优,数据分割
  5. 【Codeforces - 127D】Password(思维,二分+字符串Hash)
  6. python自动化测试框架有哪几种_Python自动化测试-Unittest单元测试框架详解
  7. Linux学习笔记---移植官方linux步骤(一)
  8. Centos7静默安装Weblogic12C
  9. 华为怒发公开信;锤子手机难产罗永浩陷尴尬处境;苹果错失 5G | 极客头条
  10. c语言输出合法的出栈算法,c语言栈的实现以及操作
  11. 电脑快捷键(键盘不灵了赶紧使用快捷键)
  12. “暴风一号”学习日记(一)
  13. Excel或C语言复数运算
  14. 信息系统项目管理师-软考-B站自学
  15. 我知道的几个免费的API数据接口
  16. 【转贴】龙芯生态产品和解决方案巡展(第四篇)——存储
  17. 微信小程序token过期后重新执行失效的请求封装(用户无感刷新token)
  18. 微信无法连接服务器1-500,GIF表情超过500kb无法添加到微信的解决方法
  19. 【网络】VLAN 及其配置详解
  20. ICCV 2021 | 视觉Transformer中的相对位置编码

热门文章

  1. 17.3加入知识的文本增强
  2. Hadoop:一文详解MapReduce的工作机制
  3. Machine Learning - XII. Support Vector Machines支持向量机(Week 7)
  4. numpy教程:随机数模块numpy.random
  5. json序列化_JSON 序列化和反序列化 In Go
  6. mysql设置主键可视化_mysql怎么设置主键自
  7. 解决Ubuntu18.04使用快捷键 Ctrl+Alt+T 无法打开终端的问题
  8. Android 属性动画(三)
  9. 搭建Android/Linux驱动编译开发环境篇
  10. 4.Scala-数据结构