第200集:Vue 3运维自动化脚本
概述
在本集中,我们将深入探讨Vue 3应用的运维自动化脚本设计与实现。自动化脚本是现代运维工作的核心,它可以提高工作效率、减少人为错误、确保操作一致性,并实现24/7不间断运行。我们将从脚本设计原则开始,逐步介绍系统监控、部署自动化、日志分析等方面的脚本实现。
一、脚本设计原则
1. 核心设计原则
| 原则 | 描述 | 实现方法 |
|---|---|---|
| 可读性 | 代码易于理解和维护 | 使用清晰的变量名、函数名和注释 |
| 可维护性 | 便于修改和扩展 | 模块化设计,避免硬编码 |
| 可靠性 | 脚本在各种情况下都能稳定运行 | 错误处理、边界检查、日志记录 |
| 可扩展性 | 容易添加新功能 | 函数式编程,参数化设计 |
| 安全性 | 防止安全漏洞 | 输入验证、权限控制、避免命令注入 |
| 可测试性 | 便于测试和验证 | 单元测试、模拟数据、测试环境 |
| 可移植性 | 在不同环境下都能运行 | 避免平台特定命令,使用标准工具 |
2. 脚本模板
#!/bin/bash
# script-template.sh
# 脚本模板,包含基本的错误处理和日志记录
# 配置信息
CONFIG_FILE="config.ini"
LOG_FILE="script.log"
VERBOSE=false
# 日志函数
log() {
local level="$1"
local message="$2"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $message" >> "$LOG_FILE"
if [ "$VERBOSE" = true ] || [ "$level" = "ERROR" ] || [ "$level" = "CRITICAL" ]; then
echo "[$level] $message"
fi
}
# 错误处理函数
error_handler() {
local exit_code="$1"
local message="$2"
log "ERROR" "$message"
log "ERROR" "脚本执行失败,退出码: $exit_code"
cleanup
exit "$exit_code"
}
# 清理函数
cleanup() {
log "INFO" "执行清理操作..."
# 在这里添加清理逻辑,如删除临时文件等
log "INFO" "清理完成"
}
# 参数解析
parse_args() {
while getopts "vch" opt; do
case "$opt" in
v) VERBOSE=true ;;
c) CONFIG_FILE="$OPTARG" ;;
h) usage ; exit 0 ;;
*) usage ; exit 1 ;;
esac
done
shift $((OPTIND - 1))
}
# 帮助信息
usage() {
echo "Usage: $0 [OPTIONS]"
echo ""
echo "Options:"
echo " -v 详细模式"
echo " -c FILE 指定配置文件"
echo " -h 显示帮助信息"
echo ""
echo "Example: $0 -v -c custom_config.ini"
}
# 主函数
main() {
log "INFO" "开始执行脚本..."
# 解析参数
parse_args "$@"
log "INFO" "使用配置文件: $CONFIG_FILE"
# 检查配置文件是否存在
if [ ! -f "$CONFIG_FILE" ]; then
error_handler 1 "配置文件不存在: $CONFIG_FILE"
fi
# 读取配置文件
log "INFO" "读取配置文件..."
# 在这里添加读取配置的逻辑
# 执行主要逻辑
log "INFO" "执行主要逻辑..."
# 在这里添加脚本的主要逻辑
log "INFO" "脚本执行成功!"
cleanup
exit 0
}
# 设置错误陷阱
trap 'error_handler $? "脚本执行过程中发生未捕获的错误"' ERR
# 执行主函数
main "$@"二、系统监控脚本
1. 系统资源监控脚本
#!/bin/bash
# system-monitor.sh
# 系统资源监控脚本,监控CPU、内存、磁盘和网络使用情况
# 配置
LOG_FILE="system-monitor.log"
CHECK_INTERVAL=60 # 检查间隔(秒)
THRESHOLDS="cpu=80,mem=90,disk=95" # 告警阈值
NOTIFICATION_EMAIL="admin@example.com"
# 日志函数
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
echo "$1"
}
# 发送告警邮件
send_alert() {
local subject="$1"
local message="$2"
echo "$message" | mail -s "$subject" "$NOTIFICATION_EMAIL"
log "发送告警邮件: $subject"
}
# 获取CPU使用率
get_cpu_usage() {
local cpu_usage=$(top -bn1 | grep "Cpu(s)" | sed "s/.*, *\([0-9.]*\)%* id.*/\1/" | awk '{print 100 - $1}')
echo "$(printf "%.1f" "$cpu_usage")"
}
# 获取内存使用率
get_mem_usage() {
local mem_total=$(free -m | grep Mem | awk '{print $2}')
local mem_used=$(free -m | grep Mem | awk '{print $3}')
local mem_usage=$(echo "scale=1; $mem_used / $mem_total * 100" | bc)
echo "$mem_usage"
}
# 获取磁盘使用率
get_disk_usage() {
local disk_usage=$(df -h / | grep / | awk '{print $5}' | sed 's/%//')
echo "$disk_usage"
}
# 获取网络流量
get_network_traffic() {
local rx_bytes=$(cat /proc/net/dev | grep eth0 | awk '{print $2}')
local tx_bytes=$(cat /proc/net/dev | grep eth0 | awk '{print $10}')
echo "rx:$rx_bytes tx:$tx_bytes"
}
# 监控主函数
monitor() {
log "开始系统监控..."
while true; do
local cpu_usage=$(get_cpu_usage)
local mem_usage=$(get_mem_usage)
local disk_usage=$(get_disk_usage)
local network=$(get_network_traffic)
# 记录当前状态
log "CPU: ${cpu_usage}% | 内存: ${mem_usage}% | 磁盘: ${disk_usage}% | 网络: ${network}"
# 检查CPU阈值
if (( $(echo "$cpu_usage > ${THRESHOLDS##*cpu=}" | bc -l) )); then
send_alert "CPU使用率告警" "CPU使用率过高: ${cpu_usage}%,超过阈值 ${THRESHOLDS##*cpu=}%"
fi
# 检查内存阈值
if (( $(echo "$mem_usage > ${THRESHOLDS##*mem=}" | bc -l) )); then
send_alert "内存使用率告警" "内存使用率过高: ${mem_usage}%,超过阈值 ${THRESHOLDS##*mem=}%"
fi
# 检查磁盘阈值
if (( $disk_usage > ${THRESHOLDS##*disk=} )); then
send_alert "磁盘使用率告警" "磁盘使用率过高: ${disk_usage}%,超过阈值 ${THRESHOLDS##*disk=}%"
fi
sleep "$CHECK_INTERVAL"
done
}
# 执行监控
monitor2. 服务状态监控脚本
#!/bin/bash
# service-monitor.sh
# 服务状态监控脚本,监控指定服务是否正常运行
# 配置
SERVICES=("nginx" "node" "mysql" "redis")
CHECK_INTERVAL=30
LOG_FILE="service-monitor.log"
RESTART_FAILED_SERVICES=true
# 日志函数
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
echo "$1"
}
# 检查服务状态
check_service() {
local service="$1"
log "检查服务: $service"
if systemctl is-active --quiet "$service"; then
log "服务 $service 运行正常"
return 0
else
log "ERROR: 服务 $service 未运行"
return 1
fi
}
# 重启服务
restart_service() {
local service="$1"
log "尝试重启服务: $service"
if systemctl restart "$service"; then
log "服务 $service 重启成功"
return 0
else
log "ERROR: 服务 $service 重启失败"
return 1
fi
}
# 监控主函数
monitor() {
log "开始服务监控..."
while true; do
for service in "${SERVICES[@]}"; do
if ! check_service "$service"; then
if [ "$RESTART_FAILED_SERVICES" = true ]; then
restart_service "$service"
# 检查重启是否成功
if ! check_service "$service"; then
log "CRITICAL: 服务 $service 重启失败,需要人工干预"
# 在这里可以添加告警逻辑,如发送邮件或短信
fi
else
log "CRITICAL: 服务 $service 未运行,且自动重启已禁用"
fi
fi
done
sleep "$CHECK_INTERVAL"
done
}
# 执行监控
monitor三、部署自动化脚本
1. 前端部署自动化脚本
#!/bin/bash
# frontend-deploy.sh
# Vue 3前端部署自动化脚本
# 配置
APP_DIR="/var/www/vue3-app"
GIT_REPO="git@github.com:example/vue3-app.git"
BRANCH="main"
BUILD_CMD="npm run build"
DEPLOY_DIR="/var/www/html"
BACKUP_DIR="/backup/vue3-app"
trap "echo '部署过程中发生错误'; exit 1" ERR
# 日志函数
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}
# 检查命令是否存在
check_command() {
if ! command -v "$1" &> /dev/null; then
log "错误:命令 $1 不存在"
exit 1
fi
}
# 备份当前部署
backup_current() {
log "备份当前部署..."
mkdir -p "$BACKUP_DIR"
backup_file="$BACKUP_DIR/vue3-app_$(date +%Y%m%d_%H%M%S).tar.gz"
tar -czf "$backup_file" "$DEPLOY_DIR"
log "备份完成: $backup_file"
}
# 部署主函数
deploy() {
log "开始部署Vue 3应用..."
# 检查必要命令
check_command "git"
check_command "npm"
# 1. 克隆或更新代码
log "更新代码..."
if [ -d "$APP_DIR" ]; then
cd "$APP_DIR" && git checkout "$BRANCH" && git pull
else
git clone -b "$BRANCH" "$GIT_REPO" "$APP_DIR"
fi
# 2. 安装依赖
log "安装依赖..."
cd "$APP_DIR" && npm ci
# 3. 构建应用
log "构建应用..."
cd "$APP_DIR" && npm run build
# 4. 备份当前部署
backup_current
# 5. 部署新版本
log "部署新版本..."
rm -rf "$DEPLOY_DIR"/*
cp -r "$APP_DIR/dist/*" "$DEPLOY_DIR/"
# 6. 重启服务(如果需要)
log "重启服务..."
systemctl restart nginx
# 7. 健康检查
log "健康检查..."
sleep 2
if curl -s -o /dev/null -w "%{http_code}" http://localhost/health == 200; then
log "部署成功!应用运行正常"
else
log "错误:部署后健康检查失败"
exit 1
fi
log "部署完成!"
}
# 执行部署
deploy2. Python部署自动化脚本
#!/usr/bin/env python3
# deploy.py
# 基于Python的部署自动化脚本
import os
import sys
import time
import logging
import subprocess
import argparse
from datetime import datetime
# 配置日志
logging.basicConfig(
level=logging.INFO,
format='[%(asctime)s] [%(levelname)s] %(message)s',
filename='deploy.log'
)
logger = logging.getLogger()
# 命令执行函数
def run_command(cmd, cwd=None, shell=True):
"""执行命令并返回结果"""
logger.info(f"执行命令: {cmd}")
try:
result = subprocess.run(
cmd,
cwd=cwd,
shell=shell,
check=True,
capture_output=True,
text=True
)
logger.info(f"命令执行成功: {cmd}")
if result.stdout:
logger.info(f"命令输出: {result.stdout.strip()}")
return True, result.stdout
except subprocess.CalledProcessError as e:
logger.error(f"命令执行失败: {cmd}")
logger.error(f"错误输出: {e.stderr.strip()}")
return False, e.stderr
# 备份函数
def backup_deployment(deploy_dir, backup_dir):
"""备份当前部署"""
logger.info("开始备份当前部署...")
os.makedirs(backup_dir, exist_ok=True)
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
backup_file = os.path.join(backup_dir, f"vue3_app_{timestamp}.tar.gz")
cmd = f"tar -czf {backup_file} {deploy_dir}"
success, _ = run_command(cmd)
if success:
logger.info(f"备份完成: {backup_file}")
return backup_file
else:
logger.error("备份失败")
return None
# 部署函数
def deploy(args):
"""执行部署流程"""
logger.info("开始部署Vue 3应用...")
# 1. 克隆或更新代码
logger.info("更新代码...")
if os.path.exists(args.app_dir):
# 更新代码
run_command(f"git checkout {args.branch}", cwd=args.app_dir)
run_command("git pull", cwd=args.app_dir)
else:
# 克隆代码
run_command(f"git clone -b {args.branch} {args.repo} {args.app_dir}")
# 2. 安装依赖
logger.info("安装依赖...")
run_command("npm ci", cwd=args.app_dir)
# 3. 构建应用
logger.info("构建应用...")
run_command("npm run build", cwd=args.app_dir)
# 4. 备份当前部署
backup_file = backup_deployment(args.deploy_dir, args.backup_dir)
if not backup_file:
logger.error("备份失败,取消部署")
return False
# 5. 部署新版本
logger.info("部署新版本...")
run_command(f"rm -rf {args.deploy_dir}/*")
run_command(f"cp -r {args.app_dir}/dist/* {args.deploy_dir}/")
# 6. 重启服务
logger.info("重启服务...")
run_command("systemctl restart nginx")
# 7. 健康检查
logger.info("健康检查...")
time.sleep(2)
success, _ = run_command("curl -s -o /dev/null -w '%{http_code}' http://localhost/health")
if success:
logger.info("部署成功!应用运行正常")
return True
else:
logger.error("部署后健康检查失败")
# 可以添加回滚逻辑
return False
# 主函数
def main():
parser = argparse.ArgumentParser(description="Vue 3应用部署脚本")
parser.add_argument("--app-dir", default="/var/www/vue3-app", help="应用代码目录")
parser.add_argument("--repo", default="git@github.com:example/vue3-app.git", help="Git仓库地址")
parser.add_argument("--branch", default="main", help="Git分支")
parser.add_argument("--deploy-dir", default="/var/www/html", help="部署目录")
parser.add_argument("--backup-dir", default="/backup/vue3-app", help="备份目录")
args = parser.parse_args()
success = deploy(args)
if success:
logger.info("部署完成!")
sys.exit(0)
else:
logger.error("部署失败!")
sys.exit(1)
if __name__ == "__main__":
main()四、日志分析脚本
1. Nginx日志分析脚本
#!/usr/bin/env python3
# nginx-log-analyzer.py
# Nginx日志分析脚本,分析访问日志和错误日志
import re
import argparse
import collections
from datetime import datetime
# 配置日志格式
NGINX_ACCESS_LOG_PATTERN = r'^(?P<ip>\S+) - - \[(?P<time>[^\]]+)\] "(?P<request>[^"]+)" (?P<status>\d+) (?P<size>\S+) "(?P<referrer>[^"]*)" "(?P<user_agent>[^"]*)"$'
# 统计数据
stats = {
'total_requests': 0,
'status_codes': collections.Counter(),
'top_ips': collections.Counter(),
'top_urls': collections.Counter(),
'top_user_agents': collections.Counter(),
'hourly_stats': collections.Counter(),
'total_bytes': 0
}
# 解析日志行
def parse_log_line(line):
match = re.match(NGINX_ACCESS_LOG_PATTERN, line)
if match:
return match.groupdict()
return None
# 分析日志文件
def analyze_log(file_path):
print(f"分析日志文件: {file_path}")
with open(file_path, 'r') as f:
for line in f:
log_entry = parse_log_line(line)
if log_entry:
process_log_entry(log_entry)
# 处理日志条目
def process_log_entry(entry):
stats['total_requests'] += 1
# 统计状态码
stats['status_codes'][entry['status']] += 1
# 统计IP
stats['top_ips'][entry['ip']] += 1
# 统计URL
request = entry['request'].split()[1] if len(entry['request'].split()) > 1 else entry['request']
stats['top_urls'][request] += 1
# 统计用户代理
stats['top_user_agents'][entry['user_agent']] += 1
# 统计每小时请求数
time_str = entry['time'].split()[0] # 格式: 15/Jun/2023:14:23:45
date_time = datetime.strptime(time_str, "%d/%b/%Y:%H:%M:%S")
hour_key = date_time.strftime("%Y-%m-%d %H:00")
stats['hourly_stats'][hour_key] += 1
# 统计总流量
if entry['size'] != '-':
stats['total_bytes'] += int(entry['size'])
# 打印统计结果
def print_stats():
print("\n" + "="*50)
print("Nginx日志分析结果")
print("="*50)
print(f"总请求数: {stats['total_requests']}")
print(f"总流量: {stats['total_bytes'] / (1024*1024):.2f} MB")
print("\n状态码分布:")
for status, count in stats['status_codes'].most_common():
percentage = (count / stats['total_requests']) * 100
print(f" {status}: {count} ({percentage:.2f}%)")
print("\n访问量最高的10个IP:")
for ip, count in stats['top_ips'].most_common(10):
print(f" {ip}: {count}")
print("\n访问量最高的10个URL:")
for url, count in stats['top_urls'].most_common(10):
print(f" {url}: {count}")
print("\n每小时请求数:")
for hour, count in sorted(stats['hourly_stats'].items()):
print(f" {hour}: {count}")
# 主函数
def main():
parser = argparse.ArgumentParser(description="Nginx日志分析脚本")
parser.add_argument("log_file", help="Nginx访问日志文件路径")
args = parser.parse_args()
analyze_log(args.log_file)
print_stats()
if __name__ == "__main__":
main()五、自动化最佳实践
1. 脚本管理与版本控制
- 使用Git管理脚本:将所有自动化脚本存储在Git仓库中,便于版本控制和团队协作
- 模块化设计:将常用功能封装为模块,便于复用和维护
- 文档化:为每个脚本编写详细的README文档,包括功能、配置、使用方法等
- 测试:为脚本编写单元测试,确保功能正确性
- 定期更新:定期更新脚本,适配新的环境和需求
2. 自动化工作流设计
# GitHub Actions工作流示例
name: Vue 3自动化部署
on:
push:
branches:
- main
schedule:
- cron: '0 2 * * *' # 每天凌晨2点执行
env:
APP_DIR: /var/www/vue3-app
DEPLOY_DIR: /var/www/html
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: 检出代码
uses: actions/checkout@v3
- name: 设置Node.js
uses: actions/setup-node@v3
with:
node-version: '16'
cache: 'npm'
- name: 安装依赖
run: npm ci
- name: 构建应用
run: npm run build
- name: 部署到生产环境
uses: easingthemes/ssh-deploy@v2
with:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
REMOTE_HOST: ${{ secrets.REMOTE_HOST }}
REMOTE_USER: ${{ secrets.REMOTE_USER }}
TARGET: ${{ env.DEPLOY_DIR }}
SOURCE: dist/
- name: 健康检查
run: curl -s -o /dev/null -w "%{http_code}" https://example.com/health
continue-on-error: false
- name: 发送部署通知
if: success()
run: |
curl -X POST -H "Content-Type: application/json" \
-d '{"text": "Vue 3应用部署成功!"}' \
${{ secrets.SLACK_WEBHOOK }}3. 自动化安全实践
- 最小权限原则:脚本执行使用最小权限账号
- 输入验证:对所有输入参数进行验证,防止注入攻击
- 加密存储敏感信息:使用环境变量或加密工具存储敏感信息
- 审计日志:记录脚本执行日志,便于审计和故障排查
- 定期安全扫描:对脚本进行安全扫描,发现潜在漏洞
六、常用自动化工具介绍
1. Ansible
Ansible是一款开源的自动化工具,用于配置管理、应用部署和任务自动化。
Ansible剧本示例:
---
# deploy-vue3.yml
- name: 部署Vue 3应用
hosts: webservers
become: yes
vars:
app_dir: /var/www/vue3-app
deploy_dir: /var/www/html
repo: git@github.com:example/vue3-app.git
branch: main
tasks:
- name: 安装必要依赖
apt:
name: [git, npm]
state: present
- name: 克隆或更新代码
git:
repo: "{{ repo }}"
dest: "{{ app_dir }}"
version: "{{ branch }}"
update: yes
- name: 安装npm依赖
npm:
path: "{{ app_dir }}"
ci: yes
- name: 构建Vue应用
command:
cmd: npm run build
chdir: "{{ app_dir }}"
- name: 部署构建产物
synchronize:
src: "{{ app_dir }}/dist/"
dest: "{{ deploy_dir }}"
delete: yes
- name: 重启Nginx
service:
name: nginx
state: restarted2. Terraform
Terraform是一款基础设施即代码工具,用于定义和部署云基础设施。
Terraform配置示例:
# main.tf
provider "aws" {
region = "us-east-1"
}
# 创建EC2实例
resource "aws_instance" "vue3_server" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = {
Name = "Vue3-Server"
}
}
# 创建S3存储桶用于静态资源
resource "aws_s3_bucket" "vue3_bucket" {
bucket = "vue3-app-bucket"
website {
index_document = "index.html"
error_document = "error.html"
}
tags = {
Name = "Vue3-App-Bucket"
}
}
# 输出EC2实例IP
output "instance_ip" {
value = aws_instance.vue3_server.public_ip
}
# 输出S3存储桶URL
output "bucket_url" {
value = aws_s3_bucket.vue3_bucket.website_endpoint
}七、总结
在本集中,我们深入探讨了Vue 3应用的运维自动化脚本设计与实现,包括:
- 脚本设计原则:可读性、可维护性、可靠性、可扩展性、安全性
- 系统监控脚本:资源监控和服务状态监控
- 部署自动化脚本:前端部署和Python实现的部署脚本
- 日志分析脚本:Nginx日志分析
- 自动化最佳实践:脚本管理、工作流设计、安全实践
- 常用自动化工具:Ansible和Terraform示例
通过自动化脚本,我们可以显著提高运维效率,减少人为错误,确保操作一致性,并实现24/7不间断运行。自动化是现代运维的核心趋势,掌握自动化脚本编写是每个运维工程师的必备技能。
随着技术的不断发展,自动化工具和技术也在不断演进,我们需要持续学习和适应新的工具和技术,不断优化自动化流程,提高自动化水平。
八、后续学习资源
脚本编程:
- Shell脚本编程指南
- Python自动化编程
- PowerShell脚本编程(Windows环境)
自动化工具:
- Ansible官方文档:https://docs.ansible.com/
- Terraform官方文档:https://www.terraform.io/docs
- Jenkins官方文档:https://www.jenkins.io/doc/
DevOps实践:
- 《DevOps实践指南》
- 《持续交付:发布可靠软件的系统方法》
- 《基础设施即代码》
监控与日志:
- Prometheus官方文档:https://prometheus.io/docs
- Grafana官方文档:https://grafana.com/docs/
- ELK Stack官方文档:https://www.elastic.co/guide/index.html
通过本集的学习,你已经掌握了Vue 3应用运维自动化脚本的设计和实现方法。希望你能够将这些知识应用到实际工作中,提高运维效率,确保应用的稳定运行。