前端构建和部署
约 3559 字大约 12 分钟
前端构建和部署
CI/CD流程详解 🟢
1. 持续集成(CI)基础概念
持续集成(Continuous Integration)是一种软件开发实践,它要求开发人员频繁地将代码集成到共享仓库中。每次集成都通过自动化构建(包括编译、发布、自动化测试)来验证,从而尽早地发现集成错误。这种实践可以大大减少集成问题,让团队更快地交付软件。
1.1 CI的主要目标和优势
- 提高代码质量
- 通过自动化测试及早发现问题:在代码提交后立即运行测试,快速发现潜在问题
- 保证代码风格一致性:使用ESLint、Prettier等工具强制代码规范
- 减少集成冲突:频繁集成减少了大规模合并的风险
- 提高代码可维护性:统一的构建过程确保了代码的一致性
- 加快开发节奏
- 自动化构建和测试:减少人工操作,提高效率
- 快速反馈:开发人员可以立即知道自己的修改是否破坏了现有功能
- 减少重复工作:自动化流程减少了手动操作的需求
- 提高团队效率:自动化流程让团队专注于开发工作
- 降低项目风险
- 及早发现问题:问题在开发初期就能被发现,降低修复成本
- 减少集成问题:持续集成减少了代码集成时的问题
- 保证代码质量:自动化测试确保代码质量
- 提高项目稳定性:频繁的测试和部署提高了项目的稳定性
1.2 CI工具选择及对比
在选择CI工具时,需要考虑团队规模、项目需求、基础设施等多个因素。以下是主流CI工具的详细对比:
- Jenkins 优点:
- 开源免费,社区活跃:拥有庞大的社区支持和丰富的插件生态
- 插件丰富,扩展性强:几乎可以满足所有CI/CD需求
- 高度可定制:支持通过Groovy脚本自定义构建流程
- 支持分布式构建:可以横向扩展构建能力
- 支持多种版本控制系统:Git、SVN等都有良好支持
缺点:
- 配置复杂:需要较深的专业知识
- 维护成本高:需要专人维护服务器和配置
- UI相对陈旧:界面不够现代化
- 需要自己搭建服务器:增加了基础设施成本
Jenkins配置示例:
pipeline {
agent any
environment {
NODE_VERSION = '16.14.0'
}
stages {
stage('Install') {
steps {
sh 'npm install'
}
}
stage('Test') {
parallel {
stage('Unit Tests') {
steps {
sh 'npm run test:unit'
}
}
stage('E2E Tests') {
steps {
sh 'npm run test:e2e'
}
}
}
}
stage('Build') {
steps {
sh 'npm run build'
}
}
stage('Deploy') {
when {
branch 'master'
}
steps {
sh './deploy.sh production'
}
}
}
post {
always {
cleanWs()
}
success {
slackSend channel: '#deploy',
color: 'good',
message: "部署成功: ${env.JOB_NAME} ${env.BUILD_NUMBER}"
}
failure {
slackSend channel: '#deploy',
color: 'danger',
message: "部署失败: ${env.JOB_NAME} ${env.BUILD_NUMBER}"
}
}
}
- GitLab CI 优点:
- 与GitLab深度集成:无缝对接GitLab的代码管理
- 配置简单,易于使用:通过YAML文件即可配置
- 支持Docker:原生支持容器化构建
- 自动扩展:支��自动扩缩容
- 界面友好:现代化的用户界面
缺点:
- 与GitLab绑定:不适合使用其他代码托管服务的团队
- 功能相对简单:相比Jenkins功能较少
- 插件生态不如Jenkins:扩展性较差
GitLab CI配置示例:
# 定义阶段
stages:
- install
- test
- build
- deploy
# 定义变量
variables:
NODE_VERSION: "16.14.0"
# 缓存配置
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
# 安装依赖
install:
stage: install
script:
- npm ci
artifacts:
paths:
- node_modules/
# 运行测试
test:
stage: test
script:
- npm run test:unit
- npm run test:e2e
coverage: '/Coverage: \d+.\d+%/'
# 构建项目
build:
stage: build
script:
- npm run build
artifacts:
paths:
- dist/
only:
- master
- develop
# 部署到测试环境
deploy_staging:
stage: deploy
script:
- ./deploy.sh staging
environment:
name: staging
only:
- develop
# 部署到生产环境
deploy_production:
stage: deploy
script:
- ./deploy.sh production
environment:
name: production
only:
- master
when: manual
- GitHub Actions 优点:
- 与GitHub深度集成:完美配合GitHub工作流
- 社区活跃,模板丰富:大量现成的工作流模板
- 配置灵活:支持复杂的工作流程
- 免费额度大:对开源项目完全免费
- 无需维护服务器:云服务模式
缺点:
- 仅支持GitHub:不支持其他代码托管平台
- 商业项目收费:超出免费额度需付费
- 运行时间有限制:单次作业有时间限制
[接下来继续补充...]
前端构建优化 🔴
1. Webpack优化策略
1.1 构建速度优化
- 缓存优化:
// webpack.config.js
module.exports = {
cache: {
type: 'filesystem', // 使用文件系统缓存
buildDependencies: {
config: [__filename] // 构建依赖
},
name: 'production-cache' // 缓存名称
},
module: {
rules: [{
test: /\.js$/,
use: 'babel-loader',
options: {
cacheDirectory: true // babel-loader缓存
}
}]
}
};
- 多进程构建:
// webpack.config.js
const ThreadLoader = require('thread-loader');
ThreadLoader.warmup({
// 预热线程池
workers: 4,
workerParallelJobs: 50
}, [
'babel-loader',
'@babel/preset-env'
]);
module.exports = {
module: {
rules: [{
test: /\.js$/,
use: [
{
loader: 'thread-loader',
options: {
workers: 4,
workerParallelJobs: 50
}
},
'babel-loader'
]
}]
}
};
- 优化模块查找路径:
// webpack.config.js
module.exports = {
resolve: {
modules: [
path.resolve(__dirname, 'src'),
'node_modules'
],
extensions: ['.js', '.jsx', '.ts', '.tsx'],
alias: {
'@': path.resolve(__dirname, 'src')
}
}
};
1.2 构建产物优化
- 代码分割:
// webpack.config.js
module.exports = {
optimization: {
splitChunks: {
chunks: 'all',
minSize: 20000,
minChunks: 1,
maxAsyncRequests: 30,
maxInitialRequests: 30,
cacheGroups: {
defaultVendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10,
reuseExistingChunk: true
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
}
}
};
- 压缩优化:
// webpack.config.js
const TerserPlugin = require('terser-webpack-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
parallel: true,
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true
}
}
}),
new CssMinimizerPlugin({
parallel: true,
minimizerOptions: {
preset: ['default', {
discardComments: { removeAll: true }
}]
}
})
]
}
};
2. 构建工具链优化
2.1 ESBuild集成
// build.config.js
const esbuild = require('esbuild');
const { nodeExternalsPlugin } = require('esbuild-node-externals');
async function build() {
try {
await esbuild.build({
entryPoints: ['src/index.ts'],
bundle: true,
minify: true,
sourcemap: true,
platform: 'node',
target: ['node14'],
outdir: 'dist',
plugins: [nodeExternalsPlugin()],
metafile: true
});
} catch (error) {
process.exit(1);
}
}
build();
2.2 Rollup配置优化
// rollup.config.js
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import typescript from '@rollup/plugin-typescript';
import { terser } from 'rollup-plugin-terser';
export default {
input: 'src/index.ts',
output: [
{
file: 'dist/bundle.cjs.js',
format: 'cjs',
sourcemap: true
},
{
file: 'dist/bundle.esm.js',
format: 'es',
sourcemap: true
}
],
plugins: [
resolve(),
commonjs(),
typescript({
tsconfig: './tsconfig.json'
}),
terser()
],
external: ['react', 'react-dom']
};
自动化部署进阶 🔴
1. Docker部署优化
1.1 多阶段构建
# 构建阶段
FROM node:16-alpine as builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# 生产阶段
FROM nginx:alpine
# 复制构建产物
COPY --from=builder /app/dist /usr/share/nginx/html
# 复制Nginx配置
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
1.2 Docker Compose配置
version: '3.8'
services:
frontend:
build:
context: .
dockerfile: Dockerfile
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf
networks:
- app-network
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 30s
timeout: 10s
retries: 3
networks:
app-network:
driver: bridge
2. Kubernetes部署
2.1 基础配置
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend-deployment
spec:
replicas: 3
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: frontend
image: frontend:latest
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
readinessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 15
periodSeconds: 20
2.2 服务配置
apiVersion: v1
kind: Service
metadata:
name: frontend-service
spec:
selector:
app: frontend
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: frontend-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80
3. 自动化部署流程
3.1 GitLab CI/CD完整配置
image: node:16-alpine
variables:
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: ""
stages:
- test
- build
- deploy
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
- .npm/
test:
stage: test
script:
- npm ci
- npm run lint
- npm run test:coverage
coverage: '/Lines\s*:\s*([0-9.]+)%/'
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage/cobertura-coverage.xml
build:
stage: build
script:
- npm ci
- npm run build
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
only:
- master
- develop
deploy_staging:
stage: deploy
script:
- kubectl config use-context staging
- envsubst < k8s/deployment.yaml | kubectl apply -f -
- kubectl rollout status deployment/frontend-deployment
environment:
name: staging
only:
- develop
deploy_production:
stage: deploy
script:
- kubectl config use-context production
- envsubst < k8s/deployment.yaml | kubectl apply -f -
- kubectl rollout status deployment/frontend-deployment
environment:
name: production
only:
- master
when: manual
3.2 GitHub Actions完整配置
name: CI/CD Pipeline
on:
push:
branches: [ master, develop ]
pull_request:
branches: [ master ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: '16'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm run test:coverage
- name: Upload coverage
uses: codecov/codecov-action@v2
build:
needs: test
runs-on: ubuntu-latest
if: github.event_name == 'push'
steps:
- uses: actions/checkout@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v2
with:
push: true
tags: user/app:latest
cache-from: type=registry,ref=user/app:buildcache
cache-to: type=registry,ref=user/app:buildcache,mode=max
deploy:
needs: build
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/master'
steps:
- uses: actions/checkout@v2
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Deploy to EKS
run: |
aws eks update-kubeconfig --name cluster-name
kubectl apply -f k8s/
kubectl rollout status deployment/frontend-deployment
监控告警系统 🔴
1. 性能监控
1.1 前端监控SDK
class PerformanceMonitor {
constructor() {
this.metrics = {};
this.init();
}
init() {
// 性能指标监控
this.observePerformance();
// 错误监控
this.observeErrors();
// 资源加载监控
this.observeResources();
}
observePerformance() {
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
// 记录性能指标
this.metrics[entry.name] = entry.startTime;
// 上报数据
this.report({
type: 'performance',
name: entry.name,
value: entry.startTime
});
}
});
observer.observe({
entryTypes: ['paint', 'largest-contentful-paint', 'first-input']
});
}
observeErrors() {
window.addEventListener('error', (event) => {
this.report({
type: 'error',
message: event.message,
filename: event.filename,
lineno: event.lineno,
colno: event.colno
});
});
window.addEventListener('unhandledrejection', (event) => {
this.report({
type: 'unhandledrejection',
message: event.reason
});
});
}
observeResources() {
const resourceObserver = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (entry.initiatorType === 'resource') {
this.report({
type: 'resource',
name: entry.name,
duration: entry.duration,
transferSize: entry.transferSize
});
}
}
});
resourceObserver.observe({ entryTypes: ['resource'] });
}
report(data) {
// 使用 Beacon API 上报数据
navigator.sendBeacon('/api/metrics', JSON.stringify({
...data,
timestamp: Date.now(),
url: location.href
}));
}
}
1.2 监控数据聚合
class MetricsAggregator {
constructor() {
this.metrics = new Map();
}
aggregate(data) {
const key = `${data.type}_${data.name}`;
if (!this.metrics.has(key)) {
this.metrics.set(key, {
count: 0,
sum: 0,
min: Infinity,
max: -Infinity,
values: []
});
}
const metric = this.metrics.get(key);
metric.count++;
metric.sum += data.value;
metric.min = Math.min(metric.min, data.value);
metric.max = Math.max(metric.max, data.value);
metric.values.push(data.value);
// 计算百分位数
if (metric.values.length > 100) {
this.calculatePercentiles(metric);
}
}
calculatePercentiles(metric) {
const sorted = metric.values.sort((a, b) => a - b);
metric.p50 = sorted[Math.floor(sorted.length * 0.5)];
metric.p90 = sorted[Math.floor(sorted.length * 0.9)];
metric.p99 = sorted[Math.floor(sorted.length * 0.99)];
// 清理原始数据,避免内存占用
metric.values = [];
}
getMetrics() {
const result = {};
for (const [key, metric] of this.metrics.entries()) {
result[key] = {
avg: metric.sum / metric.count,
min: metric.min,
max: metric.max,
p50: metric.p50,
p90: metric.p90,
p99: metric.p99
};
}
return result;
}
}
2. 告警系统
2.1 告警规则配置
class AlertRule {
constructor(config) {
this.metric = config.metric;
this.operator = config.operator;
this.threshold = config.threshold;
this.duration = config.duration;
this.severity = config.severity;
}
evaluate(value) {
switch (this.operator) {
case '>':
return value > this.threshold;
case '<':
return value < this.threshold;
case '>=':
return value >= this.threshold;
case '<=':
return value <= this.threshold;
default:
return false;
}
}
}
class AlertManager {
constructor() {
this.rules = new Map();
this.alerts = new Map();
}
addRule(name, config) {
this.rules.set(name, new AlertRule(config));
}
evaluate(metrics) {
for (const [name, rule] of this.rules.entries()) {
const value = metrics[rule.metric];
if (rule.evaluate(value)) {
this.createAlert(name, rule, value);
} else {
this.resolveAlert(name);
}
}
}
createAlert(name, rule, value) {
if (!this.alerts.has(name)) {
this.alerts.set(name, {
name,
rule,
value,
startTime: Date.now(),
notified: false
});
}
const alert = this.alerts.get(name);
if (!alert.notified &&
Date.now() - alert.startTime >= rule.duration) {
this.notify(alert);
alert.notified = true;
}
}
resolveAlert(name) {
if (this.alerts.has(name)) {
const alert = this.alerts.get(name);
if (alert.notified) {
this.notifyResolved(alert);
}
this.alerts.delete(name);
}
}
notify(alert) {
// 发送告警通知
const message = {
title: `告警: ${alert.name}`,
content: `指标 ${alert.rule.metric}
当前值 ${alert.value}
超过阈值 ${alert.rule.threshold}`,
severity: alert.rule.severity,
time: new Date().toISOString()
};
// 可以集成不同的通知渠道
this.sendToSlack(message);
this.sendToEmail(message);
}
notifyResolved(alert) {
const message = {
title: `告警恢复: ${alert.name}`,
content: `指标 ${alert.rule.metric} 已恢复正常`,
severity: alert.rule.severity,
time: new Date().toISOString()
};
this.sendToSlack(message);
this.sendToEmail(message);
}
}
构建工具链优化 🔴
1. 构建工具选择指南
1.1 不同构建工具对比
- Webpack 优点:
- 生态系统最完善
- 配置灵活度高
- 支持各种资源模块
- 插件系统强大
缺点:
- 配置复杂
- 构建速度较慢
- 学习成本高
- 内存占用大
- Vite 优点:
- 开发环境启动快
- 配置简单直观
- 原生ESM支持
- HMR性能好
缺点:
- 生态不如Webpack
- 生产构建依赖Rollup
- 部分插件兼容性问题
- 不支持一些特殊场景
- Rollup 优点:
- Tree-shaking效果好
- 输出代码干净
- 适合库开发
- 配置简单
缺点:
- 不适合复杂应用
- 插件生态较小
- 开发体验一般
- HMR支持有限
- esbuild 优点:
- 构建速度极快
- 内存占用低
- 配置简单
- 支持主流功能
缺点:
- 生态系统小
- 功能相对简单
- 插件机制限制多
- 不适合复杂场景
1.2 工具选择建议
- 应用场景分析
- 中大型应用:Webpack
- 现代Web应用:Vite
- 类库开发:Rollup
- 简单项目:esbuild
- 技术栈考虑
- React项目:Webpack/Vite
- Vue项目:Vite
- TypeScript项目:全部适用
- 传统多页面:Webpack
2. 构建性能优化
2.1 Webpack优化策略
// webpack.config.js
const path = require('path');
const webpack = require('webpack');
const TerserPlugin = require('terser-webpack-plugin');
const CompressionPlugin = require('compression-webpack-plugin');
const HardSourceWebpackPlugin = require('hard-source-webpack-plugin');
module.exports = {
// 缓存配置
cache: {
type: 'filesystem',
buildDependencies: {
config: [__filename]
},
name: 'production-cache'
},
// 优化配置
optimization: {
minimizer: [
new TerserPlugin({
parallel: true,
terserOptions: {
compress: {
drop_console: true
}
}
})
],
splitChunks: {
chunks: 'all',
minSize: 20000,
maxSize: 244000,
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name(module) {
const packageName = module.context.match(
/[\\/]node_modules[\\/](.*?)([\\/]|$)/
)[1];
return `vendor.${packageName.replace('@', '')}`;
}
},
common: {
minChunks: 2,
priority: -20
}
}
}
},
// 插件配置
plugins: [
new HardSourceWebpackPlugin(),
new webpack.IgnorePlugin({
resourceRegExp: /^\.\/locale$/,
contextRegExp: /moment$/
}),
new CompressionPlugin({
test: /\.(js|css|html|svg)$/,
threshold: 10240
})
],
// 模块解析优化
resolve: {
modules: [
path.resolve(__dirname, 'src'),
'node_modules'
],
extensions: ['.js', '.jsx', '.ts', '.tsx'],
alias: {
'@': path.resolve(__dirname, 'src')
}
}
};
2.2 Vite优化策略
// vite.config.js
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import legacy from '@vitejs/plugin-legacy';
import { visualizer } from 'rollup-plugin-visualizer';
export default defineConfig({
plugins: [
vue(),
legacy({
targets: ['ie >= 11'],
additionalLegacyPolyfills: ['regenerator-runtime/runtime']
}),
visualizer()
],
build: {
target: 'es2015',
minify: 'terser',
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true
}
},
rollupOptions: {
output: {
manualChunks: {
'vendor': ['vue', 'vue-router', 'vuex'],
'utils': ['lodash', 'axios']
}
}
},
chunkSizeWarningLimit: 500
},
optimizeDeps: {
include: ['vue', 'vue-router', 'vuex', 'axios'],
exclude: ['your-local-package']
},
server: {
hmr: {
overlay: false
}
}
});
3. 自动化部署进阶
3.1 Docker多阶段构建
# 构建阶段
FROM node:16-alpine as builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# 测试阶段
FROM builder as tester
RUN npm run test
# 生产阶段
FROM nginx:alpine
# 复制构建产物
COPY --from=builder /app/dist /usr/share/nginx/html
# 复制Nginx配置
COPY nginx.conf /etc/nginx/conf.d/default.conf
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost/ || exit 1
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
3.2 Kubernetes配置
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
labels:
app: frontend
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: frontend
image: frontend:latest
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
readinessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 15
periodSeconds: 20
env:
- name: NODE_ENV
value: "production"
- name: API_URL
valueFrom:
configMapKeyRef:
name: frontend-config
key: api_url
volumeMounts:
- name: config
mountPath: /app/config
volumes:
- name: config
configMap:
name: frontend-config
---
apiVersion: v1
kind: Service
metadata:
name: frontend-service
spec:
selector:
app: frontend
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: frontend-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts:
- example.com
secretName: frontend-tls
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80
4. 监控告警系统进阶
4.1 Prometheus监控配置
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'frontend'
static_configs:
- targets: ['frontend:80']
metrics_path: '/metrics'
scheme: 'http'
relabel_configs:
- source_labels: [__address__]
target_label: instance
regex: '(.*):.*'
replacement: '${1}'
- job_name: 'node-exporter'
static_configs:
- targets: ['node-exporter:9100']
alerting:
alertmanagers:
- static_configs:
- targets: ['alertmanager:9093']
4.2 Grafana仪表盘配置
{
"annotations": {
"list": []
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"links": [],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "prometheus",
"uid": "prometheus"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": true,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 0
},
"id": 1,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "prometheus"
},
"expr": "rate(http_requests_total[5m])",
"refId": "A"
}
],
"title": "HTTP Request Rate",
"type": "timeseries"
}
],
"refresh": "5s",
"schemaVersion": 38,
"style": "dark",
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Frontend Dashboard",
"version": 0,
"weekStart": ""
}
[未完待续...]