109 lines
3.2 KiB
JavaScript
109 lines
3.2 KiB
JavaScript
const config = require("../config")
|
||
const http = require("../http")
|
||
const yaml = require("js-yaml");
|
||
const path = require('path');
|
||
const fs = require('fs');
|
||
|
||
|
||
class Utils {
|
||
|
||
// 存储 Nacos上 服务列表 的服务名称
|
||
ServiceNameList = []
|
||
|
||
constructor() {
|
||
this.getServiceName()
|
||
}
|
||
|
||
/**
|
||
* 获取Nacos上的服务名称数组
|
||
* @returns {Promise<void>}
|
||
*/
|
||
async getServiceName() {
|
||
console.log("1: [getServiceName] 从Nacos 获取服务名..")
|
||
const {doms} = await http.get({
|
||
url: config.nacosApi.apiList.serviceList,
|
||
data: {pageNo: 1, pageSize: 20},
|
||
});
|
||
if (doms.length === 0) {
|
||
throw new Error("No service found for service list");
|
||
}
|
||
this.serviceName = doms;
|
||
console.log("2: [getServiceName] 服务名为:", this.serviceName)
|
||
await this.generateTraefikConfig()
|
||
}
|
||
|
||
/**
|
||
* 从 Nacos 获取服务实例
|
||
* @param serviceName
|
||
* @returns {Promise<*|*[]>}
|
||
*/
|
||
async getServiceInstances(serviceName) {
|
||
const {hosts} = await http.get({
|
||
url: config.nacosApi.apiList.instanceInfo,
|
||
data: {serviceName, namespaceId: config.nacosConfig.nameSpace},
|
||
});
|
||
return hosts || []
|
||
}
|
||
|
||
|
||
/**
|
||
* 生成 traefik 动态配置
|
||
* @returns {Promise<void>}
|
||
*/
|
||
async generateTraefikConfig() {
|
||
const traefikConf = {
|
||
http: {
|
||
routers: {},
|
||
services: {},
|
||
middlewares: config.traefikConfig.middlewaresConfig,
|
||
}
|
||
};
|
||
|
||
for (const serviceName of this.serviceName) {
|
||
const instances = await this.getServiceInstances(serviceName);
|
||
if (instances.length === 0) {
|
||
console.warn(`服务 ${serviceName} 无可用实例`);
|
||
continue;
|
||
}
|
||
|
||
// 1. 配置服务(服务名 + 实例列表)
|
||
traefikConf.http.services[`${serviceName}-service`] = {
|
||
loadBalancer: {
|
||
servers: instances.map(inst => ({
|
||
url: `http://${inst.ip}:${inst.port}`,
|
||
})),
|
||
}
|
||
};
|
||
|
||
// 2. 配置路由(路径前缀 + 绑定服务)
|
||
traefikConf.http.routers[`${serviceName}-router`] = {
|
||
rule: `PathPrefix(\`/${serviceName}\`)`, // 如 /main、/product
|
||
service: `${serviceName}-service`,
|
||
entryPoints: ['web'],
|
||
// 应用中间件(压缩、IP白名单、限流、重试等)
|
||
middlewares: config.traefikConfig.middlewaresStr,
|
||
};
|
||
}
|
||
|
||
this.stringToYaml(traefikConf)
|
||
}
|
||
|
||
/**
|
||
* 生成 yaml 配置文件
|
||
* @param conf
|
||
*/
|
||
stringToYaml(conf) {
|
||
console.log("3: [stringToYaml] 生成配置:", JSON.stringify(conf, null, 2));
|
||
console.log()
|
||
console.log()
|
||
|
||
const yamlString = yaml.dump(conf, {
|
||
indent: 2, // 缩进空格数
|
||
skipInvalid: true, // 跳过无效类型
|
||
noRefs: true // 禁止引用(防止循环引用问题)
|
||
});
|
||
fs.writeFileSync(config.filePath, yamlString, "utf8");
|
||
}
|
||
}
|
||
|
||
module.exports = Utils |