https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/ liveness: The kubelet uses liveness probes to know when to restart a Container. For example, liveness probes could catch a deadlock, where an application is running, but unable to make progress. Restarting a Container in such a state can help to make the application more available despite bugs. readiness: The kubelet uses readiness probes to know when a Container is ready to start accepting traffic. A Pod is considered ready when all of its Containers are ready. One use of this signal is to control which Pods are used as backends for Services. When a Pod is not ready, it is removed from Service load balancers.
简单来说 liveness 代表应用是不是挂了,readiness 代表应用是不是可访问的。
启动 启动依赖目前 egg 使用 ready 来代表插件是否启动完成,应用是否启动完成。目前在插件依赖关系复杂的情况下,应用启动时间很长。原因是不管什么插件,是否是弱依赖的,都需要准备完成。而事实上是部分插件在不 ready 的情况下应用也应该是可访问的。
举个例子:有个缓存插件,会阻塞应用启动。但是业务场景是无缓存的时候可以 fallback 到 db 去。
// cache-plugin
// app.js
module.exports = () => {
app.beforeStart(async () => {
await app.cache.ready();
});
};
// cache.js
module.exports = app => {
return class Cache extends Base {
async _init() {
await app.cacheConn.ready();
}
async fetchCache(key) {
return app.cacheConn.get(key);
}
}
};
可以做如下修改,在弱依赖的时候,不阻塞应用的启动。
// config.default.js
module.exports = {
const config = {
cache: {
dependency: false,
},
};
return config;
};
// sdk-base.js
...
async ready() {
if (this.options.dependency === false) {
return true;
}
...
}
get isReady() {
...
}
...
// cache.js
module.exports = app => {
return class Cache extends Base {
async _init() {
await app.cacheConn.ready();
}
async fetchCache(key) {
return app.cacheConn.isReady && app.cacheConn.get(key);
}
}
};
启动过程
目前的启动过程是,master 会去监听 cluster 的 listening 事件,在 worker 监听了正确的端口之后,就会认为启动是完成了。 按照 liveness 和 readiness,应该是 worker 在启动时候就要开始监听端口,liveness 是通了,然后会去访问 worker 的 readiness 接口判断是否 ready 了。 但是受限于 node 的多进程模型,可能 worker 进程的状态是不一致的,所以需要 master 进程对状态做聚合。
master 进程存活,则 liveness 是通的 有一个 worker 进程不是 readiness 的,则 readiness 就是不通的 访问Readiness probes runs on the container during its whole lifecycle.
目前的 ready 在应用启动完成之后就没有用了,但是 readiness 是在整个生命周期中都是会调用的。所以 ready 接口在插件、应用的状态发生改变之后,也需要做出变化,体现在 readiness 的返回结果上。
cc: @eggjs/core