服务优雅上下线实现方案-运维

     1、前言

        前一篇文章介绍了nginx通过nginx_upstream_check_module模块实现后端健康检查,基于这篇文章介绍一下服务优雅上下线的实现方案。

        对于微服务来说,服务的优雅上下线是必要的。对于上线来说,如果服务没有启动成功,就不应该对外暴露。对于下线来说,如果服务已经停止了,就应该保证已下线,避免上游流量进入不健康的机器。

        在项目升级的时候,绝大部分采用滚动升级的方式,需要停止一个旧的服务,然后启动一个新的服务,在这个过程中往往会出现服务的中断,那如何最大限度的做到发布的优雅,尽可能让升级的这个过程不影响到线上正在运行的业务,这时就需要实现服务的优雅上下线。

        服务的优雅上下线就是保证服务的稳定可用,避免流量中断,导致业务不可用。优雅上线其实就是等服务启动完全就绪后,对外提供服务,也叫无损发布,延迟暴露,服务预热。优雅下线其实就是在服务收到停机指令后,要先到注册中心注销,拒绝新的请求后,将旧的业务处理完成。

2、nginx作为服务的流量入口

        对于传统架构来说,后端服务常用nginx来做服务的入口或系统之间的交互。

3、应用服务使用注册中心

        同一个项目系统之间内部调用,使用注册中心的方式。如:zk、consul、eureka、nacos等。

4、服务优雅上线-运维

应用服务上线流程介绍:

① 执行启动脚本如:【sh server.sh start】,启动服务以java为例:【java -jar app.jar】

② 服务启动需要时间,先等待n秒,然后调用上线接口【http://127.0.0.1:port/ops/v1/on】,接口用来检测服务是否启动成功,若满足上线要求:如果涉及注册中心,则将服务注册到注册中心。

③ 更新接口【http://127.0.0.1:port/ops/v1/check】状态码,若第②部启动成功则更新成【200】,否则保持默认【599】。

④ 若【check】接口状态码非【200】,等待10秒,从新执行【on】接口,最多循环5次。

⑤ 若【check】接口状态码【200】,nginx根据【nginx_upstream_check_module】检查机制自动将服务上线,转发流量到此节点。

5、服务优雅下线-运维

应用服务下线流程介绍:

① 执行停止脚本【sh server.sh stop】,执行下线接口【http://127.0.0.1:port/ops/v1/down】,若服务涉及注册中心,则【down】接口自动调用相关接口将服务从注册中心下线。

② 下线接口执行成功后,同时更新【check】接口状态码为【404】,否则保持不变【200】

③ 当【check】接口状态码是非【200】时,nginx根据【nginx_upstream_check_module】检查机制自动从upstream中摘除,不再分发流量到此节点。

④ 当【check】接口状态码还是【200】时,从新执行第①步进行下线,最多循环10次。

⑤ 等待n秒(根据实际情况定),若有注册中心,虽然从注册中心摘除了节点,但是注册中心刷新列表需要时间,naocs:30s,以及让服务在这n秒内将之前进来的请求执行完毕(若执行不完,分析原因优化接口)。然后开始执行kill命令,先kill pid结束服务进程,n次kill不了服务,再kill -9 强制终止。

6、k8s 上下线思路

        基于上面的介绍,在k8s当中可以结合钩子函数探针资源对象实现pod的上下线。

        钩子函数:postStart 、 preStop

        k8s在主容器的启动之后和停止之前提供了两个钩子函数,钩子函数能够感知自身生命周期中的事件,并在相应的时刻运行用户指定的指令。

        探针

  • livenessProbe:存活性探针
  • readinessProbe:就绪性探针
  • startupProbe:启动探针

7、示例演示demo

1、下面是两个docker服务,端口:9091,9092

# docker ps -a | grep health
15cadf1009a6   registry.cn-beijing.aliyuncs.com/wl_666/app:health-check-v2   "/bin/bash start.sh"     2 weeks ago      Up 4 seconds                  0.0.0.0:9092->3000/tcp, :::9092->3000/tcp   tender_meninsky
2c691a9985bf   registry.cn-beijing.aliyuncs.com/wl_666/app:health-check-v1   "/bin/bash start.sh"     2 weeks ago      Up 4 seconds                  0.0.0.0:9091->3000/tcp, :::9091->3000/tcp   funny_diffie

2、服务接口信息如下:

# curl -s http://192.168.100.210:9091 | jq
{
  "/info": "服务运行信息",
  "/ops/v1/check": "健康检查接口状态",
  "/ops/v1/down": "服务下线",
  "/ops/v1/on": "服务上线",
  "describe": "请调用一下接口"
}

3、nginx配置如下:

# cat nginx_upstream_check.conf
upstream cluster{
    server 192.168.100.210:9091;
    server 192.168.100.210:9092;
    check interval=3000 rise=2 fall=2 timeout=3000 type=http;
    check_http_send "GET /ops/v1/check HTTP/1.0\r\n\r\n ";
    check_http_expect_alive http_2xx http_3xx;
}


server {
    listen       8888;
    server_name  localhost;
    #charset koi8-r;
    access_log  logs/nginx_upstream_check.log  main;

    location / {
        root   html;
        index  index.html;
    }

    location ^~ /nginxServer/ {
        proxy_pass http://cluster/;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header REMOTE-HOST $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass_request_body on;
        proxy_set_header   Cookie $http_cookie;
        real_ip_header X-Real-IP;
    }

    location /nginx_status {
        check_status;
        access_log off;
    }
}

8、上线演示

1、服务刚启动还未调用上线接口时,nginx状态如下,通过nginx调用后端接口502。

# curl http://192.168.100.210:8888/nginxServer/info
<html>
<head><title>502 Bad Gateway</title></head>
<body>
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx</center>
</body>
</html>

# curl -I http://192.168.100.210:8888/nginxServer/info
HTTP/1.1 502 Bad Gateway
Server:
Date: Wed, 07 Aug 2024 13:00:09 GMT
Content-Type: text/html
Content-Length: 150
Connection: keep-alive

2、将第一个服务上线后:

查看上线前的chek接口状态码
# curl -s http://192.168.100.210:9091/ops/v1/check  | jq
{
  "url": "/ops/v1/check",
  "url_code": "599",
  "time": "2024-08-07 21:03:13"
}
调用上线接口
[root@node-210 ~]# curl -s http://192.168.100.210:9091/ops/v1/on  | jq
{
  "url": "/ops/v1/on",
  "url_code": "200",
  "time": "2024-08-07 21:03:18"
}
调用上线后的check接口状态码
[root@node-210 ~]# curl -s http://192.168.100.210:9091/ops/v1/check  | jq
{
  "url": "/ops/v1/check",
  "url_code": "200",
  "time": "2024-08-07 21:03:21"
}

通过nginx调用后端接口
# curl -s http://192.168.100.210:8888/nginxServer/info | jq
{
  "time": "2024-08-07 21:05:27",
  "hostname": "2c691a9985bf",
  "ipaddress": "172.17.0.3",
  "version": "v1"
}

3、第二个服务同样方式上线

# curl -s http://192.168.100.210:9092/ops/v1/on  | jq
{
  "url": "/ops/v1/on",
  "url_code": "200",
  "time": "2024-08-07 21:06:42"
}

[root@node-210 ~]# curl -s http://192.168.100.210:9092/ops/v1/check  | jq
{
  "url": "/ops/v1/check",
  "url_code": "200",
  "time": "2024-08-07 21:06:52"
}

通过nginx调用后端接口:都会调用到了,注意返回version字段

[root@node-210 ~]# curl -s http://192.168.100.210:8888/nginxServer/info | jq
{
  "time": "2024-08-07 21:07:48",
  "hostname": "2c691a9985bf",
  "ipaddress": "172.17.0.3",
  "version": "v1"
}
[root@node-210 ~]# curl -s http://192.168.100.210:8888/nginxServer/info | jq
{
  "time": "2024-08-07 21:07:50",
  "hostname": "15cadf1009a6",
  "ipaddress": "172.17.0.2",
  "version": "v2"
}

9、下线演示

1、下线一个服务

下线前check接口状态码:200
[root@node-210 ~]# curl -s http://192.168.100.210:9092/ops/v1/check  | jq
{
  "url": "/ops/v1/check",
  "url_code": "200",
  "time": "2024-08-07 21:11:00"
}

调用下线接口
[root@node-210 ~]# curl -s http://192.168.100.210:9092/ops/v1/down  | jq
{
  "url": "/ops/v1/down",
  "url_code": "404",
  "time": "2024-08-07 21:11:08"
}
下线后check接口状态码:404
[root@node-210 ~]# curl -s http://192.168.100.210:9092/ops/v1/check  | jq
{
  "url": "/ops/v1/check",
  "url_code": "404",
  "time": "2024-08-07 21:11:12"
}

nginx已经从upstream中将此节点摘除了

文章多多少少会有不足的地方,请多多见谅!ღ ღ ღ ღ ღ

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值