Node.js的Web服务在Nacos中的实践

前言

Node.js作为Web端一个重要的运行时环境,通常被当做BFF(Backend For FrontEnd)来使用,而鲜有与后端微服务进行共同融合开发的场景。然而,不同团队中配置人员占比及任务分配的不同,有时也会需要多种后端语言(如:Go、Python、Java、Node.js等)共同来提供提供BFD(Backend For Database)的能力。因此,本文主要介绍笔者基于Node.js实现的Web服务在Java微服务架构中的实践。

架构

传统Java微服务通常采用服务器端的发现模式,客户端通过负载均衡器向服务发起请求,负载均衡器查询服务注册表,并将请求路由转发到对应的服务实例。

对于注册方式,通常包括自我注册方式和第三方注册模式。其中,自我注册模式使用较为简单,但服务实例与服务注册表却紧密耦合;第三方注册模式可以实现服务和注册的分离,但却需要额外的三方协调组件。

目录

plain 复制代码
├─ server                                 // 基于Node.js的Web服务器
|   ├─ keys                               // HTTPS相关证书
|   ├─ routes                             // 服务模块
|   ├─ utils
|   ├─ app.js                             // Web服务实例
|   ├─ config.js
├─ main.js                                // Web服务导出及Nacos服务注册

实践

目前,Java的微服务服务注册中心通常以NacosEureka为主,二者有联系但也有区别,感兴趣的小伙伴可以参考《详解Nacos和Eureka的区别》这篇文章来学习。

这里,我们以Nacos为例来进行介绍。对于Node.js来说,我们使用nacos的包来进行服务注册,代码如下:

javascript 复制代码
const yaml = require("js-yaml");
const fs = require("fs");

// 注册服务到Nacos服务器
const { NacosNamingClient } = require("nacos");

const { address } = require("ip");
const logger = console;

// 动态获取本机 IP 地址
const ipAddr = address();
// 我们当前的端口号
const port = server.port;

// 服务名称,后面消费方调用的时候通过这个服务名进行服务查询。
const providerServiceName = "inspection-nodejs";

// 读取 YAML 文件内容
const yamlContent = fs.readFileSync(
  `./deploy/${process.env.SERVER_MODE}/config.yaml`,
  "utf8"
);

// 解析 YAML
const config = yaml.load(yamlContent);

const client = new NacosNamingClient({
  logger,
  serverList: config.data["spring.cloud.nacos.discovery.server-addr"],
  namespace: config.data["spring.cloud.nacos.discovery.namespace"],
  username: config.data["spring.cloud.nacos.discovery.username"],
  password: config.data["spring.cloud.nacos.discovery.password"],
});
console.log("[Nacos] 注册Nacos服务");
async () => {
  const allinstance = await client.getAllInstances();
  console.log("[Nacos]----allinstance----", allinstance);
};
(async () => {
  try {
    await client.ready();
    // 注册服务和实例
    await client.registerInstance(providerServiceName, {
      ip: ipAddr,
      port,
    });
    // 这里也可以传入group,不传默认就是 DEFAULT_GROUP
    // const groupName = 'nodejs';
    // await client.registerInstance(providerServiceName, {
    // ip: ipAddr,
    // port
    // }, groupName);
    console.log(`[Nacos] Nacos服务注册实例成功: ${ipAddr}:${port}`);
  } catch (err) {
    console.log("[Nacos] Nacos服务注册实例失败: " + err.toString());
  }
})();

我们通过Nacos的服务注册中心界面可以看到,当前服务已经注册成功。

我们尝试不加token和添加token的方式进行访问,可以看到微服务的拦截及转发功能均已成功。

总结

传统微服务场景下利用多语言优势,可以提供不同能力的服务特性。在主体结构相对一致的情况下,前端工程师的开发范围可能会进一步扩展,除了常见的BFF场景,也可以提供BFD,以及更加广泛的Serverless能力!

参考

相关推荐
郑州光合科技余经理15 分钟前
海外O2O系统源码剖析:多语言、多货币架构设计与二次开发实践
java·开发语言·前端·小程序·系统架构·uni-app·php
arvin_xiaoting5 小时前
OpenClaw学习总结_I_核心架构_8:SessionPruning详解
前端·chrome·学习·系统架构·ai agent·openclaw·sessionpruning
工程师老罗6 小时前
Image(图像)的用法
java·前端·javascript
swipe7 小时前
把 JavaScript 原型讲透:从 `[[Prototype]]`、`prototype` 到 `constructor` 的完整心智模型
前端·javascript·面试
问道飞鱼8 小时前
【前端知识】React 组件生命周期:从底层原理到实践场景
前端·react.js·前端框架·生命周期
CHU7290358 小时前
定制专属美丽时刻:美容预约商城小程序的贴心设计
前端·小程序
浩~~8 小时前
反射型XSS注入
前端·xss
AwesomeDevin9 小时前
AI时代,我们的任务不应沉溺于与 AI 聊天,🤔 从“对话式编程”迈向“数字软件工厂”
前端·后端·架构
harrain9 小时前
antvG2折线图和区间range标记同时绘制
前端·javascript·vue.js·antv·g2
德育处主任Pro9 小时前
从重复搭建到高效生产,RollCode的H5开发新范式
前端