Hyperf 官方提供了容器镜像,配置选项又非常开放,将 Hyperf 部署于云端本身并不复杂。下面我们以 Kubernetes 为例,对 Hyperf 默认的骨架包进行一些改造,使它可以优雅的运行于 Kubernetes 上。本文不是 Kubernetes 的入门介绍,需要读者已经对 Kubernetes 有一定了解。
生命周期
容器在 Kubernetes 上启动以后,Kubernetes 会对容器进行两项检查: Liveness Probe 和Readiness Probe。Liveness Probe 如果没有通过,容器会被重启,而 Readiness Probe 没有通过,则会暂时将服务从发现列表中移除。当 Hyperf 作为HTTP Web Server 启动时,我们只需要添加两条路由就行了。
<?php namespace App\Controller; class HealthCheckController extends AbstractController {
public function liveness() {
return 'ok'; } public function readiness() {
return 'ok'; }}
<?php // in config/Routes.phpRouter::addRoute(['GET', 'HEAD'], '/liveness', 'App\Controller\HealthCheckController@liveness');Router::addRoute(['GET', 'HEAD'], '/readiness', 'App\Controller\HealthCheckController@readiness');
在 Kubernetes 的 deployment 上配置:
livenessProbe: httpGet: path: /liveness port: 9501 failureThreshold: 1 periodSeconds: 10readinessProbe: httpGet: path: /readiness port: 9501 failureThreshold: 1 periodSeconds: 10
当然这里我们只是简单了返回 ‘ok’,显然不能真正检查出健康状况。实际的检查要考虑业务具体场景和业务依赖的资源。例如对于重数据库服务我们可以检查数据库的连接池,如果连接池已满就暂时在 Readiness Probe 返回状态码 503。
服务在 Kubernetes 销毁时,Kubernetes 会先发来 SIGTERM 信号。进程有terminationGracePeriodSeconds
这么长的时间(默认60秒)来自行结束。如果到时间后还没结束,Kubernetes 就会发来SIGINT信号来强制杀死进程。Swoole 本身是可以正确响应 SIGTERM 结束服务的,正常情况下不会丢失任何运行中的连接。实际生产中,如果 Swoole 没有响应 SIGTERM 退出,很有可能是因为服务端注册的定时器没有被清理。我们可以在 OnWorkerExit 处清理定时器来保证顺利退出。
<?php // config/autoload/server.php // ...'callbacks' => [ SwooleEvent::ON_BEFORE_START => [Hyperf\Framework\