健康检查

共享文件系统 API 服务的健康状况可以通过“健康检查”中间件来确定。该中间件默认情况下与软件打包的 api-paste 文件一起启用。因此,存在一个 /healthcheck 端点,如果 API 服务正常运行,则响应 GET 请求并以 HTTP 200 “OK” 作为正文。如果 API 服务无法运行,则响应为 HTTP 503 “服务不可用”。

负载均衡器可以轮询此 /healthcheck 端点来确定服务可用性。该端点的行为与 apache 中的 mod_status 非常相似。可以添加到 api-paste 文件中的示例配置如下。

[app:healthcheck]
paste.app_factory = oslo_middleware:Healthcheck.app_factory
backends = disable_by_file
disable_by_file_path = /etc/manila/healthcheck_disable
detailed = False

示例健康检查请求和响应

 $ curl -i -X GET http://203.0.113.30/share/healthcheck
 HTTP/1.1 200 OK
 Date: Wed, 20 Mar 2024 23:00:19 GMT
 Server: Apache/2.4.52 (Ubuntu)
 Content-Type: text/plain; charset=UTF-8
 Content-Length: 2
 Connection: close
 Vary: Accept-Encoding

 OK

 $ curl -i -X GET http://203.0.113.30/share/healthcheck -H "Accept: application/json"
 HTTP/1.1 200 OK
 Date: Wed, 20 Mar 2024 23:01:08 GMT
 Server: Apache/2.4.52 (Ubuntu)
 Content-Type: application/json
 Content-Length: 62
 Connection: close

 {
     "detailed": false,
     "reasons": [
         "OK"
     ]
 }

$ curl -i -X GET http://203.0.113.30/share/healthcheck -H "Accept: text/html"
 HTTP/1.1 200 OK
 Date: Wed, 20 Mar 2024 23:02:27 GMT
 Server: Apache/2.4.52 (Ubuntu)
 Content-Type: text/html; charset=UTF-8
 Content-Length: 239
 Connection: close
 Vary: Accept-Encoding

 <HTML>
 <HEAD><TITLE>Healthcheck Status</TITLE></HEAD>
 <BODY>

 <H2>Result of 1 checks:</H2>
 <TABLE bgcolor="#ffffff" border="1">
 <TBODY>
 <TR>

 <TH>
 Reason
 </TH>
 </TR>
 <TR>

     <TD>OK</TD>

 </TR>
 </TBODY>
 </TABLE>
 <HR></HR>

 </BODY>
 </HTML>

如果 [app:healthcheck] 部分的 api paste 配置文件中将 detailed 设置为 True,则可以请求“详细”响应。默认情况下不这样做。

$ curl -i -X GET http://203.0.113.30/share/healthcheck -H "Accept: application/json"
HTTP/1.1 200 OK
Date: Wed, 20 Mar 2024 23:06:19 GMT
Server: Apache/2.4.52 (Ubuntu)
Content-Type: application/json
Content-Length: 4177
Connection: close

{
    "detailed": true,
    "gc": {
        "counts": [
            400,
            5,
            0
        ],
        "threshold": [
            700,
            10,
            10
        ]
    },
    "greenthreads": [
        "  File \"/opt/stack/data/venv/lib/python3.10/site-packages/paste/urlmap.py\", line 216, in __call__\n    return app(environ, start_response)\n  File \"/opt/stack/data/venv/lib/python3.10/site-packages/webob/dec.py\", line 129, in __call__\n    resp = self.call_func(req, *args, **kw)\n  File \"/opt/stack/data/venv/lib/python3.10/site-packages/webob/dec.py\", line 193, in call_func\n    return self.func(req, *args, **kwargs)\n  File \"/opt/stack/data/venv/lib/python3.10/site-packages/oslo_middleware/base.py\", line 121, in __call__\n    response = self.process_request(req)\n  File \"/opt/stack/data/venv/lib/python3.10/site-packages/webob/dec.py\", line 146, in __call__\n    return self.call_func(req, *args, **kw)\n  File \"/opt/stack/data/venv/lib/python3.10/site-packages/webob/dec.py\", line 193, in call_func\n    return self.func(req, *args, **kwargs)\n  File \"/opt/stack/data/venv/lib/python3.10/site-packages/oslo_middleware/healthcheck/__init__.py\", line 582, in process_request\n    body, content_type = functor(results, healthy)\n  File \"/opt/stack/data/venv/lib/python3.10/site-packages/oslo_middleware/healthcheck/__init__.py\", line 510, in _make_json_response\n    body['greenthreads'] = self._get_greenstacks()\n  File \"/opt/stack/data/venv/lib/python3.10/site-packages/oslo_middleware/healthcheck/__init__.py\", line 464, in _get_greenstacks\n    traceback.print_stack(gt.gr_frame, file=buf)\n"
    ],
    "now": "2024-03-20 23:06:19.907279",
    "platform": "Linux-5.15.0-91-generic-x86_64-with-glibc2.35",
    "python_version": "3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0]",
    "reasons": [
        {
            "class": "HealthcheckResult",
            "details": "Path '/etc/manila/healthcheck_disable' was not found",
            "reason": "OK"
        }
    ],
    "threads": [
        "  File \"/usr/lib/python3.10/threading.py\", line 973, in _bootstrap\n    self._bootstrap_inner()\n  File \"/usr/lib/python3.10/threading.py\", line 1016, in _bootstrap_inner\n    self.run()\n  File \"/usr/lib/python3.10/threading.py\", line 953, in run\n    self._target(*self._args, **self._kwargs)\n  File \"/opt/stack/data/venv/lib/python3.10/site-packages/tooz/coordination.py\", line 208, in _beat_forever_until_stopped\n    self._dead.wait(has_to_sleep_for / 2.0)\n  File \"/usr/lib/python3.10/threading.py\", line 607, in wait\n    signaled = self._cond.wait(timeout)\n  File \"/usr/lib/python3.10/threading.py\", line 324, in wait\n    gotit = waiter.acquire(True, timeout)\n",
        "  File \"/opt/stack/data/venv/lib/python3.10/site-packages/paste/urlmap.py\", line 216, in __call__\n    return app(environ, start_response)\n  File \"/opt/stack/data/venv/lib/python3.10/site-packages/webob/dec.py\", line 129, in __call__\n    resp = self.call_func(req, *args, **kw)\n  File \"/opt/stack/data/venv/lib/python3.10/site-packages/webob/dec.py\", line 193, in call_func\n    return self.func(req, *args, **kwargs)\n  File \"/opt/stack/data/venv/lib/python3.10/site-packages/oslo_middleware/base.py\", line 121, in __call__\n    response = self.process_request(req)\n  File \"/opt/stack/data/venv/lib/python3.10/site-packages/webob/dec.py\", line 146, in __call__\n    return self.call_func(req, *args, **kw)\n  File \"/opt/stack/data/venv/lib/python3.10/site-packages/webob/dec.py\", line 193, in call_func\n    return self.func(req, *args, **kwargs)\n  File \"/opt/stack/data/venv/lib/python3.10/site-packages/oslo_middleware/healthcheck/__init__.py\", line 582, in process_request\n    body, content_type = functor(results, healthy)\n  File \"/opt/stack/data/venv/lib/python3.10/site-packages/oslo_middleware/healthcheck/__init__.py\", line 511, in _make_json_response\n    body['threads'] = self._get_threadstacks()\n  File \"/opt/stack/data/venv/lib/python3.10/site-packages/oslo_middleware/healthcheck/__init__.py\", line 452, in _get_threadstacks\n    traceback.print_stack(stack, file=buf)\n"
    ]
}

您可以通过创建一个名为 /etc/manila/healthcheck_disable 的文件来动态禁用健康检查端点。可以使用 api paste 配置文件中 [app:healthcheck] 部分的配置选项 disable_by_file_path 自定义此文件的名称。