封装自动生成 traefik 代理配置的 nodejs 插件代码
This commit is contained in:
109
docker/traefik/src/utils/index.js
Normal file
109
docker/traefik/src/utils/index.js
Normal file
@@ -0,0 +1,109 @@
|
||||
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
|
||||
Reference in New Issue
Block a user