前言
Node.js作為Web端一個重要的運行時環境,通常被當做BFF(Backend For FrontEnd)來使用,而鮮有與後端微服務進行共同融合開發的場景。然而,不同團隊中配置人員佔比及任務分配的不同,有時也會需要多種後端語言(如:Go、Python、Java、Node.js等)共同來提供提供BFD(Backend For Database)的能力。因此,本文主要介紹筆者基於Node.js實現的Web服務在Java微服務架構中的實踐。
架構
傳統Java微服務通常採用服務器端的發現模式,客户端通過負載均衡器向服務發起請求,負載均衡器查詢服務註冊表,並將請求路由轉發到對應的服務實例。
對於註冊方式,通常包括自我註冊方式和第三方註冊模式。其中,自我註冊模式使用較為簡單,但服務實例與服務註冊表卻緊密耦合;第三方註冊模式可以實現服務和註冊的分離,但卻需要額外的三方協調組件。
目錄
├─ 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的包來進行服務註冊,代碼如下:
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能力!
參考
- 微服務的靈魂擺渡者——Nacos,來一篇原理全攻略
- 要學習微服務的服務發現?先來了解一些科普知識吧
- Nacos SDK for Node.js 使用指南
- Serverless單體架構的崛起
- 詳解Nacos和Eureka的區別