1

我的公司从一个使用微服务的相对较小的项目开始。可以想象,代码共享的热门话题出现了,什么该共享,什么不该共享。争论的焦点之一是在一个库中共享实际的 express server listen() 代码并在多个服务中使用。我觉得这是错误的,因为我相信这通过共享初始化代码将两个服务紧密结合在一起。我同事天说我们已经加上快递了。这种共享方法是正确的做法吗?此外,他没有将路由和控制器分离到它们的结构中,是的,代码很小,但不确定如何快速找到路由。

以下是分享的内容。我对有更多经验的人对这种方法的看法很感兴趣。

let app = express();

let app_ready = false;
function check_alive(request, response, callback?:(req:any, resp:any) => void) {
    console.log("alive state requested");
    if (callback === undefined) {
        // no alive_check callback provided
        // use default
        if (app_ready) {
            response.status(200);
        } else {
            response.status(503);
        }
        response.json({ready: app_ready});
    } else {
        callback(request, response);
    }
}

function check_ready(request, response, callback:(req:any, resp:any) => void) {
    console.log("ready state requested");
    callback(request, response);
}

exports.instance = app;
exports.init = (ready_check: (req:any,resp:any) => void, alive_check?:(req:any,resp:any) => void) => {
// basic routing
    app.get("/liveness", (req, res) => {check_alive(req, res, alive_check);});
    app.post("/liveness", (req, res) => {check_alive(req, res, alive_check);});

    if (ready_check == undefined || ready_check == null) {
        app.get("/readiness", (req, res) => {check_alive(req, res);});
        app.post("/readiness", (req, res) => {check_alive(req, res);});
    } else {
        app.get("/readiness", (req, res) => {check_ready(req, res, ready_check);});
        app.post("/readiness", (req, res) => {check_ready(req, res, ready_check);});
    }
};

exports.listen = (port, callback) => {
        return app.listen(port, () => {
        app_ready = true;
        callback();
    });
}

exports.get = (url:string, callback:any) => {
    app.get(url, callback);
}

exports.post = (url:string, callback:any) => {
    app.post(url, callback);
}

编辑:所以虽然这段代码在技术上是正确的,但应用程序初始化函数是否应该包含在共享库中?如果不是,为什么不和什么应该和不应该共享?

我在 medium、devops 和这个网站上读过很多文章,说只要你可以独立部署、重启等,它就是一个微服务。

提前感谢您的任何见解。

4

1 回答 1

1

当一个单一的代码库变得太大而无法管理和团队理解时(即引入新的开发人员是一个很大的痛点),必须做点什么。

许多方法都是可能的,但大多数是“分而治之”类型:创建具有文档化和版本化 API 的黑匣子,这样程序员就不必了解所有细节。这些黑盒子可以是库、npm 包、微服务……只要它们是版本化和文档化的。

在 NodeJS Web API 的情况下,您可以想象将您的应用程序拆分为多个正确记录的 npm 包,这些包实现大部分逻辑,然后编写一个导入这些逻辑的 API。

每个团队,无论是在使用 npm 包还是在使用它们的 Web API 中工作,都不需要了解其他项目的内部工作原理。结果是一样的。

微服务(以及之前的 SOA)将其提升到了一个新的水平。他们没有使用库来分而治之,而是通过定义多个互连的 Web 服务来做到这一点。

这有一些好处,但也有很多缺点。

您支付 RPC 的(大)性能损失,以便代码不会在同一个进程中结束,需要编写更多代码,重构是一种痛苦(将功能从一个微服务移动到另一个微服务比重命名和移动更难围绕类...),在非平凡的项目中,您需要接受最终的一致性(不再有外键!)。

但是,您可以使用“每个工作的最佳工具”(Python 中的机器学习服务、Node 中的 API 等......)。比库(Swagger、GraphQL、...)更好的工具来记录和版本 Web API。可以更容易水平扩展(即使在大多数项目中很少需要这样做)。

对我来说,真正重要的是:

  • 您的微服务是否有明确的界限(即,如果您迁移数据库,是否需要迁移所有微服务?它们不应该共享状态/数据,否则它是“分布式单体”)。
  • 他们有版本化的 API 吗?(您确定迁移其中一项服务不需要您更新所有调用它的微服务吗?)
  • 它们是否记录在案(开发人员不必了解服务的内部工作原理即可使用它们,您是否从中受益?)

这是一个很长的答案,但我的观点是,不要对您的微服务是否共享 10 行代码感到迂腐。恕我直言“没关系”。

免责声明:我相信微服务是一个很好的模式,只要它们解决给定项目的实际问题,但由于炒作它被广泛过度使用,而且在我从事的大多数项目中,它们都不需要并添加很多复杂性和开发痛苦,收获甚微(我是一名自由职业者)。

于 2020-12-20T14:17:28.467 回答