一、理解不同部署环境

1. 开发环境

  • 用途:用于本地开发和调试
  • 特点:具有热模块替换(HMR)功能,支持实时重载,提供详细的错误提示和源代码映射,便于调试
  • 配置:较为宽松,便于快速迭代和调试

2. 测试环境

  • 用途:用于集成测试和质量保证
  • 特点:模拟生产环境的配置,但包含额外的日志和调试信息,便于问题排查。使用独立的数据库和服务,防止测试数据污染生产数据
  • 配置:接近生产环境,但加入了测试工具和框架

3. 生产环境

  • 用途:最终用户访问的正式环境
  • 特点:经过严格优化,去除了不必要的调试信息和日志,启用各种安全措施,保证高可用性和稳定性
  • 配置:最为严格,所有的调试信息和未使用的代码都会被剔除

二、部署前的准备工作

1. 环境变量配置详解

在Vue项目根目录下创建不同的环境配置文件:

# .env.development - 开发环境配置文件
NODE_ENV=development                    # 设置Node.js环境为开发环境
VUE_APP_API_URL=http://localhost:3000   # 开发环境的后端API地址
VUE_APP_CURRENTMODE=development         # 当前环境模式标识
VUE_APP_VERSION=1.0.0-dev               # 开发版本号

# .env.test - 测试环境配置文件  
NODE_ENV=production                     # 设置为生产环境(测试环境也使用生产模式构建)
VUE_APP_API_URL=http://test.api.example.com  # 测试环境的后端API地址
VUE_APP_CURRENTMODE=test                # 当前环境模式标识
outputDir=dist-test                     # 测试环境构建输出目录名
VUE_APP_VERSION=1.0.0-test              # 测试版本号

# .env.production - 生产环境配置文件
NODE_ENV=production                     # 设置Node.js环境为生产环境
VUE_APP_API_URL=http://api.example.com  # 生产环境的后端API地址
VUE_APP_CURRENTMODE=production          # 当前环境模式标识
outputDir=dist                          # 生产环境构建输出目录名
VUE_APP_VERSION=1.0.0                   # 生产版本号

环境变量使用说明:

// 在Vue组件中使用环境变量
const apiUrl = process.env.VUE_APP_API_URL;        // 获取API地址
const currentMode = process.env.VUE_APP_CURRENTMODE; // 获取当前环境模式
const version = process.env.VUE_APP_VERSION;       // 获取版本号

// 根据环境执行不同逻辑
if (process.env.NODE_ENV === 'development') {
  // 开发环境特定逻辑
  console.log('当前处于开发环境');
}

2. Package.json脚本配置详解

{
  "scripts": {
    "serve": "vue-cli-service serve",                    // 启动开发服务器
    "build:test": "vue-cli-service build --mode test",   // 构建测试环境版本
    "build": "vue-cli-service build",                    // 构建生产环境版本(默认)
    "build:analyze": "vue-cli-service build --mode analyze", // 构建并分析包大小
    "preview": "vite preview --port 4173",               // 预览生产构建
    "deploy:test": "npm run build:test && node ./scripts/deploy-test.js", // 部署到测试环境
    "deploy:prod": "npm run build && node ./scripts/deploy-prod.js",      // 部署到生产环境
    "test:unit": "vitest",                               // 运行单元测试
    "test:e2e": "cypress run"                            // 运行端到端测试
  }
}

三、项目打包流程详解

1. Vue配置文件详细注释

创建或修改vue.config.js文件:

const { defineConfig } = require('@vue/cli-service')

module.exports = defineConfig({
  // 部署应用包时的基本URL
  // 如果你打算将项目部署到子路径(如:https://www.example.com/my-app/),需要设置这个值
  // 开发环境通常为 '/',生产环境根据实际部署路径设置
  publicPath: process.env.NODE_ENV === 'production' ? '/your-project/' : '/',
  
  // 构建输出目录(打包后文件存放的文件夹)
  // 默认是 'dist',可以通过环境变量动态设置
  outputDir: process.env.outputDir || 'dist',
  
  // 放置生成的静态资源(js、css、img、fonts)的目录
  // 相对于 outputDir 的路径
  assetsDir: 'static',
  
  // 是否在生产环境构建中生成 source map
  // true:会生成,便于调试但文件更大
  // false:不生成,生产环境推荐关闭以提高性能和安全性
  productionSourceMap: false,
  
  // 配置CSS相关选项
  css: {
    // 是否将组件中的CSS提取到独立的CSS文件中
    // 生产环境建议true,开发环境建议false(以便支持热重载)
    extract: true,
    
    // 是否为CSS开启source map
    // 生产环境建议关闭以提高性能
    sourceMap: false,
    
    // 向CSS loader传递选项
    loaderOptions: {
      sass: {
        // 全局注入sass变量和mixins,这样在所有组件中都可以使用
        additionalData: `@import "@/styles/variables.scss";`
      }
    }
  },
  
  // 开发服务器配置
  devServer: {
    port: 8080,           // 开发服务器端口
    host: 'localhost',    // 开发服务器主机名
    open: true,           // 启动后是否自动打开浏览器
    proxy: {              // 配置代理,解决开发环境跨域问题
      '/api': {
        target: 'http://localhost:3000',  // 后端API地址
        changeOrigin: true,               // 允许跨域
        pathRewrite: {
          '^/api': ''                     // 重写路径,去掉/api前缀
        }
      }
    }
  },
  
  // 配置Webpack
  configureWebpack: {
    // 配置解析别名
    resolve: {
      alias: {
        '@': path.resolve(__dirname, 'src')  // 将@指向src目录
      }
    },
    
    // 生产环境特定配置
    ...(process.env.NODE_ENV === 'production' ? {
      // 生产环境优化配置
      optimization: {
        splitChunks: {
          chunks: 'all',                    // 对所有类型的chunk进行分割
          cacheGroups: {
            vendor: {
              name: 'chunk-vendors',        // 第三方库打包成的chunk名
              test: /[\/]node_modules[\/]/, // 从node_modules引入的库
              priority: 10,                 // 优先级,数值越大优先级越高
              chunks: 'initial'             // 只打包初始依赖
            },
            common: {
              name: 'chunk-common',         // 公共代码chunk名
              minChunks: 2,                 // 至少被2个chunk引用的模块
              priority: 5,                  // 优先级
              chunks: 'initial'             // 只打包初始依赖
            }
          }
        }
      }
    } : {})
    // 开发环境使用默认配置
  },
  
  // 链式操作Webpack配置(更细粒度的控制)
  chainWebpack: config => {
    // 配置HTML模板
    config.plugin('html').tap(args => {
      args[0].title = '我的Vue应用'         // 设置HTML标题
      args[0].minify = {                    // 生产环境HTML压缩配置
        removeComments: true,               // 移除注释
        collapseWhitespace: true,           // 折叠空白字符
        removeAttributeQuotes: true         // 移除属性引号
      }
      return args
    })
  }
})

2. Vite配置详解(如果使用Vite)

创建vite.config.js文件:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'

// https://vitejs.dev/config/
export default defineConfig(({ mode }) => ({
  // 插件配置
  plugins: [vue()],
  
  // 项目根目录
  root: process.cwd(),
  
  // 开发服务器配置
  server: {
    port: 3000,                            // 开发服务器端口
    host: 'localhost',                     // 开发服务器主机
    open: true,                            // 启动时自动打开浏览器
    cors: true,                            // 允许跨域
    proxy: {                               // 代理配置
      '/api': {
        target: 'http://localhost:8080',   // 后端API地址
        changeOrigin: true,                // 允许跨域
        rewrite: (path) => path.replace(/^/api/, '')  // 路径重写
      }
    }
  },
  
  // 构建配置
  build: {
    outDir: 'dist',                        // 输出目录
    assetsDir: 'assets',                   // 静态资源目录
    sourcemap: false,                      // 是否生成source map
    minify: 'terser',                      // 代码压缩工具
    terserOptions: {                       // terser压缩配置
      compress: {
        drop_console: true,                // 移除console.log
        drop_debugger: true                // 移除debugger
      }
    },
    rollupOptions: {                       // Rollup打包配置
      output: {
        // 代码分割配置
        manualChunks: {
          vue: ['vue', 'vue-router', 'pinia'],  // Vue相关库打包到一起
          utils: ['lodash', 'axios']            // 工具库打包到一起
        },
        // 入口文件配置
        entryFileNames: 'js/[name]-[hash].js',
        chunkFileNames: 'js/[name]-[hash].js',
        assetFileNames: (assetInfo) => {
          // 静态资源分类输出
          const extType = assetInfo.name.split('.')[1]
          if (/png|jpe?g|svg|gif|tiff|bmp|ico/i.test(extType)) {
            return 'img/[name]-[hash][extname]'
          }
          return 'assets/[name]-[hash][extname]'
        }
      }
    }
  },
  
  // 解析配置
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src'),   // 路径别名
      '~': path.resolve(__dirname, 'public') // 公共文件别名
    }
  },
  
  // 环境变量前缀
  envPrefix: 'VUE_APP_',
  
  // CSS配置
  css: {
    preprocessorOptions: {
      scss: {
        additionalData: '@import "@/styles/variables.scss";'  // 全局SCSS变量
      }
    }
  }
}))

四、测试部署详细配置

1. 本地测试服务器配置

创建scripts/serve-local.js文件:

const express = require('express')
const path = require('path')
const history = require('connect-history-api-fallback')

const app = express()

// 使用history模式中间件,解决Vue Router history模式刷新404问题
app.use(history())

// 设置静态文件目录(指向打包后的dist目录)
app.use(express.static(path.join(__dirname, '../dist')))

// 添加安全头
app.use((req, res, next) => {
  // 防止XSS攻击
  res.setHeader('X-XSS-Protection', '1; mode=block')
  // 防止点击劫持
  res.setHeader('X-Frame-Options', 'DENY')
  // 防止MIME类型嗅探
  res.setHeader('X-Content-Type-Options', 'nosniff')
  next()
})

// 启动服务器
const port = process.env.PORT || 4399
app.listen(port, () => {
  console.log(`本地测试服务器已启动`)
  console.log(`访问地址: http://localhost:${port}`)
  console.log(`静态文件目录: ${path.join(__dirname, '../dist')}`)
})

2. 自动化测试环境配置

创建vitest.config.js单元测试配置:

import { defineConfig } from 'vitest/config'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [vue()],
  
  // 测试配置
  test: {
    globals: true,                    // 启用全局API
    environment: 'jsdom',             // 测试环境(模拟浏览器环境)
    
    // 覆盖率配置
    coverage: {
      reporter: ['text', 'json', 'html'],  // 覆盖率报告格式
      exclude: [                           // 排除不需要测试覆盖的文件
        'node_modules/',
        'tests/',
        '**/*.d.ts'
      ]
    },
    
    // 测试文件匹配模式
    include: ['src/**/*.{test,spec}.{js,ts}'],
    
    // 测试超时时间(毫秒)
    testTimeout: 10000,
    
    // 设置全局测试变量
    setupFiles: ['./tests/setup.js']
  },
  
  // 解析配置
  resolve: {
    alias: {
      '@': new URL('./src', import.meta.url).pathname  // 路径别名
    }
  }
})

创建Cypress端到端测试配置cypress.config.js

const { defineConfig } = require('cypress')

module.exports = defineConfig({
  e2e: {
    baseUrl: 'http://localhost:4399',           // 测试服务器地址
    specPattern: 'cypress/e2e/**/*.cy.{js,jsx,ts,tsx}', // 测试文件模式
    supportFile: 'cypress/support/e2e.js',      // 支持文件
    fixturesFolder: 'cypress/fixtures',         // 测试数据文件夹
    downloadsFolder: 'cypress/downloads',       // 下载文件文件夹
    screenshotsFolder: 'cypress/screenshots',   // 截图文件夹
    videosFolder: 'cypress/videos',             // 视频文件夹
    
    // 配置测试任务
    setupNodeEvents(on, config) {
      // 在这里可以注册事件监听器
      
      // 环境变量配置
      config.env = {
        ...config.env,
        test_mode: process.env.NODE_ENV || 'development'
      }
      
      return config
    }
  },
  
  // 组件测试配置
  component: {
    devServer: {
      framework: 'vue',           // 使用的框架
      bundler: 'vite'             // 使用的打包工具
    }
  },
  
  // 视口设置
  viewportWidth: 1280,            // 视口宽度
  viewportHeight: 720,            // 视口高度
  
  // 截图配置
  screenshotOnRunFailure: true,   // 测试失败时自动截图
  trashAssetsBeforeRuns: true     // 运行测试前清理资源
})

五、生产环境Nginx配置详解

创建完整的Nginx配置文件nginx.conf

# 运行Nginx的用户,通常设置为nginx或者www-data
user nginx;

# 工作进程数,通常设置为CPU核心数
worker_processes auto;

# 错误日志文件路径和日志级别
error_log /var/log/nginx/error.log warn;

# PID文件路径(存储Nginx主进程ID)
pid /var/run/nginx.pid;

# 事件模块配置
events {
    # 每个工作进程的最大连接数
    worker_connections 1024;
    
    # 使用epoll事件模型(Linux系统高效模型)
    use epoll;
    
    # 允许同时接受多个网络连接
    multi_accept on;
}

# HTTP服务器配置
http {
    # 包含MIME类型定义
    include /etc/nginx/mime.types;
    
    # 默认MIME类型
    default_type application/octet-stream;
    
    # 日志格式定义
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';
    
    # 访问日志路径和格式
    access_log /var/log/nginx/access.log main;
    
    # 基础性能优化配置
    sendfile on;                    # 启用高效文件传输
    tcp_nopush on;                  # 在sendfile模式下,保证数据包被完整发送
    tcp_nodelay on;                 # 禁用Nagle算法,提高响应速度
    keepalive_timeout 65;           # 保持连接超时时间
    types_hash_max_size 2048;       # types哈希表大小
    
    # Gzip压缩配置
    gzip on;                        # 启用Gzip压缩
    gzip_vary on;                   # 根据请求头Vary: Accept-Encoding
    gzip_min_length 1024;           # 最小压缩文件大小
    gzip_comp_level 6;              # 压缩级别(1-9,数字越大压缩率越高但CPU消耗越大)
    gzip_types                      # 需要压缩的MIME类型
        application/javascript
        application/json
        application/xml
        text/css
        text/javascript
        text/plain
        text/xml;
    
    # 上游服务器配置(如果需要代理到后端)
    upstream backend {
        server 127.0.0.1:8080;      # 后端服务器地址
        keepalive 32;               # 保持的连接数
    }
    
    # HTTP服务器配置(80端口,重定向到HTTPS)
    server {
        listen 80;                  # 监听80端口
        server_name yourdomain.com www.yourdomain.com;  # 域名配置
        
        # 重定向所有HTTP请求到HTTPS
        return 301 https://$server_name$request_uri;
    }
    
    # HTTPS服务器配置(443端口,主要服务)
    server {
        listen 443 ssl http2;       # 监听443端口,启用SSL和HTTP/2
        server_name yourdomain.com www.yourdomain.com;
        
        # SSL证书配置
        ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
        
        # SSL安全配置
        ssl_protocols TLSv1.2 TLSv1.3;                    # 允许的SSL协议版本
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;  # 加密套件
        ssl_prefer_server_ciphers off;                    # 优先使用服务器加密套件
        ssl_session_cache shared:SSL:10m;                 # SSL会话缓存
        ssl_session_timeout 10m;                          # SSL会话超时时间
        
        # 安全头配置
        add_header X-Frame-Options DENY always;           # 防止点击劫持
        add_header X-Content-Type-Options nosniff always; # 防止MIME类型嗅探
        add_header X-XSS-Protection "1; mode=block" always; # XSS保护
        add_header Strict-Transport-Security "max-age=63072000" always; # HSTS
        
        # 根路径配置 - Vue应用主入口
        location / {
            root /var/www/your_project/dist;     # Vue打包文件所在目录
            index index.html index.htm;          # 默认索引文件
            
            # 对于Vue Router的history模式,需要配置这个
            # 当请求的文件不存在时,返回index.html,让Vue处理路由
            try_files $uri $uri/ /index.html;
            
            # 缓存静态资源
            location ~* .(js|css|png|jpg|jpeg|gif|ico|svg)$ {
                expires 1y;                      # 缓存1年
                add_header Cache-Control "public, immutable";
            }
        }
        
        # API代理配置 - 将API请求转发到后端服务器
        location /api/ {
            proxy_pass http://backend/;          # 转发到上游服务器
            proxy_http_version 1.1;              # 使用HTTP/1.1
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_cache_bypass $http_upgrade;
            
            # 代理超时配置
            proxy_connect_timeout 60s;           # 连接超时时间
            proxy_send_timeout 60s;              # 发送超时时间
            proxy_read_timeout 60s;              # 读取超时时间
        }
        
        # 静态资源缓存配置
        location /static/ {
            root /var/www/your_project/dist;
            expires 1y;                          # 长期缓存
            add_header Cache-Control "public, immutable";
            access_log off;                      # 关闭访问日志,减少IO
        }
        
        # 安全配置 - 隐藏敏感文件
        location ~ /.(git|htaccess|htpasswd) {
            deny all;                            # 拒绝访问
            return 404;
        }
        
        # 健康检查端点
        location /health {
            access_log off;                      # 关闭日志
            return 200 "healthyn";              # 返回健康状态
            add_header Content-Type text/plain;
        }
    }
}

六、自动化部署脚本详解

1. 生产环境部署脚本

创建scripts/deploy-prod.js文件:

const { execSync } = require('child_process')
const fs = require('fs')
const path = require('path')
const scpClient = require('scp2')
const ora = require('ora')
const chalk = require('chalk')

// 服务器配置
const serverConfig = {
  host: '192.168.1.100',           // 服务器IP地址
  port: 22,                        // SSH端口,默认22
  username: 'root',                // 服务器用户名
  password: 'your_password',       // 服务器密码(建议使用密钥认证)
  path: '/var/www/your_project/'   // 服务器上项目部署路径
}

// 备份配置
const backupConfig = {
  enabled: true,                   // 是否启用备份
  backupDir: '/var/www/backups/',  // 备份目录
  keepBackups: 5                   // 保留的备份数量
}

// 部署状态跟踪
class Deployment {
  constructor() {
    this.startTime = new Date()
    this.steps = []
  }
  
  addStep(step, status, message) {
    this.steps.push({
      step,
      status,
      message,
      timestamp: new Date()
    })
  }
  
  logSuccess(step, message) {
    this.addStep(step, 'success', message)
    console.log(chalk.green(` ${step}: ${message}`))
  }
  
  logError(step, message) {
    this.addStep(step, 'error', message)
    console.log(chalk.red(` ${step}: ${message}`))
  }
  
  logInfo(step, message) {
    this.addStep(step, 'info', message)
    console.log(chalk.blue(`ℹ ${step}: ${message}`))
  }
  
  generateReport() {
    const duration = new Date() - this.startTime
    console.log(chalk.cyan('n=== 部署报告 ==='))
    console.log(`开始时间: ${this.startTime.toLocaleString()}`)
    console.log(`持续时间: ${(duration / 1000).toFixed(2)} 秒`)
    console.log(`执行步骤: ${this.steps.length}`)
    
    const successSteps = this.steps.filter(s => s.status === 'success').length
    const errorSteps = this.steps.filter(s => s.status === 'error').length
    
    console.log(chalk.green(`成功: ${successSteps}`))
    console.log(chalk.red(`失败: ${errorSteps}`))
    
    if (errorSteps > 0) {
      console.log(chalk.red('n部署过程中出现错误,请检查以上错误信息!'))
      process.exit(1)
    } else {
      console.log(chalk.green('n部署成功完成!'))
    }
  }
}

// 创建部署实例
const deployment = new Deployment()

// 主部署函数
async function deploy() {
  try {
    deployment.logInfo('初始化', '开始生产环境部署流程')
    
    // 步骤1: 检查当前Git状态
    deployment.logInfo('Git检查', '检查Git工作区状态')
    try {
      const gitStatus = execSync('git status --porcelain').toString()
      if (gitStatus) {
        deployment.logError('Git检查', '工作区有未提交的更改,请先提交更改')
        process.exit(1)
      }
      deployment.logSuccess('Git检查', '工作区干净')
    } catch (error) {
      deployment.logError('Git检查', 'Git命令执行失败')
      process.exit(1)
    }
    
    // 步骤2: 安装依赖
    deployment.logInfo('依赖安装', '开始安装项目依赖')
    try {
      execSync('npm install', { stdio: 'inherit' })
      deployment.logSuccess('依赖安装', '依赖安装完成')
    } catch (error) {
      deployment.logError('依赖安装', '依赖安装失败')
      process.exit(1)
    }
    
    // 步骤3: 运行测试
    deployment.logInfo('测试', '运行单元测试和E2E测试')
    try {
      execSync('npm run test:unit', { stdio: 'inherit' })
      execSync('npm run test:e2e', { stdio: 'inherit' })
      deployment.logSuccess('测试', '所有测试通过')
    } catch (error) {
      deployment.logError('测试', '测试失败,部署中止')
      process.exit(1)
    }
    
    // 步骤4: 构建项目
    deployment.logInfo('构建', '开始构建生产版本')
    try {
      execSync('npm run build', { stdio: 'inherit' })
      
      // 检查构建结果
      const distPath = path.join(__dirname, '../dist')
      if (!fs.existsSync(distPath)) {
        throw new Error('构建输出目录不存在')
      }
      
      const files = fs.readdirSync(distPath)
      if (files.length === 0) {
        throw new Error('构建输出目录为空')
      }
      
      deployment.logSuccess('构建', `构建完成,生成 ${files.length} 个文件`)
    } catch (error) {
      deployment.logError('构建', `构建失败: ${error.message}`)
      process.exit(1)
    }
    
    // 步骤5: 上传到服务器
    deployment.logInfo('上传', '开始上传文件到生产服务器')
    const spinner = ora('上传文件中...').start()
    
    try {
      await new Promise((resolve, reject) => {
        scpClient.scp('./dist/', serverConfig, (err) => {
          if (err) {
            reject(err)
          } else {
            resolve()
          }
        })
      })
      
      spinner.succeed('文件上传成功')
      deployment.logSuccess('上传', '所有文件已上传到服务器')
    } catch (error) {
      spinner.fail('文件上传失败')
      deployment.logError('上传', `上传失败: ${error.message}`)
      process.exit(1)
    }
    
    // 步骤6: 生成部署报告
    deployment.generateReport()
    
  } catch (error) {
    deployment.logError('部署流程', `部署过程出现未知错误: ${error.message}`)
    deployment.generateReport()
    process.exit(1)
  }
}

// 执行部署
deploy()

2. 测试环境部署脚本

创建scripts/deploy-test.js文件:

const { execSync } = require('child_process')
const chalk = require('chalk')

console.log(chalk.blue('开始测试环境部署...'))

try {
  // 1. 安装依赖
  console.log(chalk.yellow('1. 安装依赖...'))
  execSync('npm install', { stdio: 'inherit' })
  
  // 2. 构建测试版本
  console.log(chalk.yellow('2. 构建测试版本...'))
  execSync('npm run build:test', { stdio: 'inherit' })
  
  // 3. 运行测试
  console.log(chalk.yellow('3. 运行测试...'))
  execSync('npm run test:unit', { stdio: 'inherit' })
  
  // 4. 部署到测试服务器
  console.log(chalk.yellow('4. 部署到测试服务器...'))
  // 这里可以添加测试服务器部署逻辑
  
  console.log(chalk.green(' 测试环境部署完成!'))
} catch (error) {
  console.log(chalk.red(' 测试环境部署失败:', error.message))
  process.exit(1)
}

七、部署后监控配置

1. 健康检查脚本

创建scripts/health-check.js

const https = require('https')
const chalk = require('chalk')

// 健康检查配置
const endpoints = [
  {
    name: '生产环境主站',
    url: 'https://yourdomain.com',
    timeout: 5000
  },
  {
    name: '生产环境API',
    url: 'https://yourdomain.com/api/health',
    timeout: 3000
  },
  {
    name: '测试环境',
    url: 'https://test.yourdomain.com',
    timeout: 5000
  }
]

// 执行健康检查
async function healthCheck() {
  console.log(chalk.blue('开始健康检查...n'))
  
  const results = []
  
  for (const endpoint of endpoints) {
    const startTime = Date.now()
    
    try {
      const result = await checkEndpoint(endpoint)
      results.push({
        ...result,
        responseTime: Date.now() - startTime
      })
    } catch (error) {
      results.push({
        name: endpoint.name,
        status: 'down',
        error: error.message,
        responseTime: Date.now() - startTime
      })
    }
  }
  
  // 输出检查结果
  printResults(results)
}

// 检查单个端点
function checkEndpoint(endpoint) {
  return new Promise((resolve, reject) => {
    const timeout = setTimeout(() => {
      reject(new Error('请求超时'))
    }, endpoint.timeout)
    
    https.get(endpoint.url, (res) => {
      clearTimeout(timeout)
      
      if (res.statusCode === 200) {
        resolve({
          name: endpoint.name,
          status: 'up',
          statusCode: res.statusCode
        })
      } else {
        resolve({
          name: endpoint.name,
          status: 'down',
          statusCode: res.statusCode
        })
      }
    }).on('error', (error) => {
      clearTimeout(timeout)
      reject(error)
    })
  })
}

// 打印检查结果
function printResults(results) {
  results.forEach(result => {
    if (result.status === 'up') {
      console.log(chalk.green(` ${result.name}`))
      console.log(`  状态: 运行正常`)
      console.log(`  响应时间: ${result.responseTime}ms`)
      console.log(`  状态码: ${result.statusCode}n`)
    } else {
      console.log(chalk.red(` ${result.name}`))
      console.log(`  状态: 服务异常`)
      console.log(`  错误: ${result.error}`)
      console.log(`  响应时间: ${result.responseTime}msn`)
    }
  })
  
  // 总结
  const upServices = results.filter(r => r.status === 'up').length
  const totalServices = results.length
  
  console.log(chalk.cyan('=== 健康检查总结 ==='))
  console.log(`总服务数: ${totalServices}`)
  console.log(`健康服务: ${upServices}`)
  console.log(`异常服务: ${totalServices - upServices}`)
  
  if (upServices === totalServices) {
    console.log(chalk.green(' 所有服务运行正常!'))
  } else {
    console.log(chalk.yellow(' 有服务出现异常,请及时检查!'))
    process.exit(1)
  }
}

// 执行健康检查
healthCheck()
本站提供的所有下载资源均来自互联网,仅提供学习交流使用,版权归原作者所有。如需商业使用,请联系原作者获得授权。 如您发现有涉嫌侵权的内容,请联系我们 邮箱:[email protected]