const axios = require('axios'); const fs = require('fs'); const path = require('path'); const yaml = require('js-yaml'); // 配置 const NACOS_SERVER = 'http://192.168.31.101:8848'; // 你的 Nacos 地址 const NAMESPACE = 'public'; const SERVICES = ['main-app', 'app-product', 'app-shared']; // 三个模块的服务名 const TRAEFIK_DYNAMIC_CONFIG = path.join(__dirname, './dynamic.yml'); const CHECK_INTERVAL = 5000; // 10秒检查一次服务变化 console.log('配置文件路径:', TRAEFIK_DYNAMIC_CONFIG); if (!TRAEFIK_DYNAMIC_CONFIG) { throw new Error('配置文件路径生成失败,路径为空'); } // 通用中间件配置(可根据服务特性调整) const commonMiddlewares = { // 限流中间件(独立配置,关键修复) rateLimit: { rateLimit: { average: 100, burst: 200, period: '1s', sourceCriterion: { ipStrategy: {depth: 2} } } }, // 压缩中间件 compress: { compress: { excludedContentTypes: ['text/event-stream'], minResponseBodyBytes: 1024 } }, // IP白名单中间件(示例:允许本地和192.168.31网段) ipWhiteList: { ipWhiteList: { sourceRange: ['127.0.0.1/32', '192.168.31.0/24'] } }, // // 重定向中间件(HTTP→HTTPS) // redirectToHttps: { // redirectScheme: { // scheme: 'https', // permanent: true // } // }, // 重试中间件(关键修复:将重试配置移到这里) retries: { retry: { attempts: 3, initialInterval: '200ms' } } }; // 从 Nacos 获取服务实例 async function getServiceInstances(serviceName) { try { const res = await axios.get(`${NACOS_SERVER}/nacos/v1/ns/instance/list`, { params: {serviceName, namespaceId: NAMESPACE}, }); return res.data.hosts || []; } catch (err) { console.error(`获取 ${serviceName} 实例失败:`, err.message); return []; } } // 生成 traefik 动态配置 async function generateTraefikConfig() { const config = { http: { routers: {}, services: {}, middlewares: commonMiddlewares } }; for (const serviceName of SERVICES) { const instances = await getServiceInstances(serviceName); if (instances.length === 0) { console.warn(`服务 ${serviceName} 无可用实例`); continue; } // 1. 配置服务(服务名 + 实例列表) config.http.services[`${serviceName}-service`] = { loadBalancer: { servers: instances.map(inst => ({ url: `http://${inst.ip}:${inst.port}`, })), // 熔断配置 // healthCheck: { // path: '/health', // 假设服务有健康检查接口 // interval: '30s', // timeout: '5s', // unhealthyThreshold: 3, // healthyThreshold: 2 // } } }; // 2. 配置路由(路径前缀 + 绑定服务) config.http.routers[`${serviceName}-router`] = { rule: `PathPrefix(\`/${serviceName}\`)`, // 如 /main、/product service: `${serviceName}-service`, entryPoints: ['web'], // 应用中间件(压缩、IP白名单、限流、重试等) middlewares: ['compress', 'ipWhiteList', 'rateLimit', 'retries'], }; } // 将对象转换为 YAML 字符串 const yamlString = yaml.dump(config, { indent: 2, // 缩进空格数 skipInvalid: true, // 跳过无效类型 noRefs: true // 禁止引用(防止循环引用问题) }); console.log("yamlString: ", yamlString) // 写入动态配置文件 fs.writeFileSync(TRAEFIK_DYNAMIC_CONFIG, yamlString, "utf8"); console.log('动态配置已更新'); } // 定时检查并更新配置 setInterval(generateTraefikConfig, CHECK_INTERVAL); // 立即执行一次 generateTraefikConfig();