前言
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的微服务服务注册中心通常以Nacos和Eureka为主,二者有联系但也有区别,感兴趣的小伙伴可以参考《详解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能力!