初且实现一个以docker启动的seaweedfs对象存储服务

This commit is contained in:
chenqiang 2025-11-13 17:41:38 +08:00
commit 384171ea56
5 changed files with 851 additions and 0 deletions

38
.gitignore vendored Normal file
View File

@ -0,0 +1,38 @@
# 数据目录
filer_data/
master_data/
volume_data/
# 环境变量文件
.envrc
.env
.env.local
# 敏感信息
seaweedfs_password.enc
*_password.enc
# 备份文件
*_bak_*
*_backup_*
# Docker相关
.docker/
*.log
logs/
# IDE和编辑器文件
.idea/
.vscode/
*.swp
*.swo
*~
# macOS文件
.DS_Store
.AppleDouble
.LSOverride
# 其他临时文件
*.tmp
*.temp

120
README.md Normal file
View File

@ -0,0 +1,120 @@
# SeaweedFS 文件存储服务
本目录包含基于 [SeaweedFS](https://github.com/seaweedfs/seaweedfs) 的分布式文件存储服务配置提供S3兼容接口用于文件的存储和管理。
## 服务组件
SeaweedFS 服务由以下组件组成:
- **Master Server**: 负责管理卷服务器和文件分配
- **Volume Server**: 负责实际存储数据
- **Filer**: 提供文件系统接口
- **S3 Gateway**: 提供S3兼容接口
## 快速开始
### 1. 初始化环境
首先执行初始化脚本,设置环境变量和创建必要的配置文件:
```bash
cd /Users/chenqiang/workspace/work/项目记录/202510铁岭县内网文件分发/demo/server/oss
./init
```
初始化过程中会提示设置以下参数:
- S3服务端口默认25003
- S3访问密钥
- S3密钥会加密存储
### 2. 启动服务
使用提供的服务脚本启动SeaweedFS
```bash
./service start
```
### 3. 停止服务
```bash
./service stop
```
### 4. 查看服务状态
```bash
./service status
```
## 环境变量配置
初始化后,环境变量将保存在 `.envrc` 文件中。主要配置项包括:
- `SEAWEEDFS_VERSION`: SeaweedFS 版本
- `S3_PORT`: S3服务端口
- `S3_ACCESS_KEY`: S3访问密钥
- `S3_SECRET_KEY`: S3密钥加密存储
- 各容器名称配置
## 数据存储
- **Master数据**: `./master_data/`
- **Volume数据**: `./volume_data/`
- **Filer数据**: `./filer_data/`
> **注意**: 数据目录会被 `.gitignore` 忽略,不会提交到代码仓库。
## S3客户端配置
使用S3兼容的客户端访问服务时需要配置以下参数
- **Endpoint**: `http://localhost:8333`
- **Access Key**: 初始化时设置的值
- **Secret Key**: 初始化时设置的值
- **Region**: 可以使用任意值,如 `us-east-1`
## 安全注意事项
- S3密钥使用OpenSSL加密存储在 `seaweedfs_password.enc` 文件中
- 敏感配置文件(如 `.envrc``seaweedfs_password.enc`)已添加到 `.gitignore`
- 建议定期备份数据目录
## 故障排除
### 常见问题
1. **服务启动失败**
- 检查端口是否被占用
- 查看容器日志:`docker logs seaweedfs-master` 等
2. **S3访问认证失败**
- 确认访问密钥和密钥是否正确
- 检查 `.envrc` 文件中的配置
3. **数据丢失**
- 确保定期备份数据目录
- 避免直接修改数据目录中的文件
## 维护指南
### 更新SeaweedFS版本
1. 修改 `.envrc` 中的 `SEAWEEDFS_VERSION`
2. 重启服务:`./service restart`
### 清理旧数据
> **警告**: 清理数据前请确保已备份重要数据!
可以通过停止服务并清空数据目录来清理所有数据:
```bash
./service stop
rm -rf master_data/* volume_data/* filer_data/*
./service start
```
## 许可证
[MIT](LICENSE)

37
docker-compose.yml Normal file
View File

@ -0,0 +1,37 @@
version: '3.9'
services:
master:
image: chrislusf/seaweedfs:${SEAWEEDFS_VERSION:-4.00} # use a remote image
container_name: ${MASTER_CONTAINER_NAME:-seaweedfs-master}
volumes:
- ./master_data:/data
command: "master -ip=master -ip.bind=0.0.0.0 -metricsPort=9324"
volume:
image: chrislusf/seaweedfs:${SEAWEEDFS_VERSION:-4.00} # use a remote image
container_name: ${VOLUME_CONTAINER_NAME:-seaweedfs-volume}
volumes:
- ./volume_data:/data
command: 'volume -mserver="master:9333" -ip.bind=0.0.0.0 -port=8080 -metricsPort=9325'
depends_on:
- master
filer:
image: chrislusf/seaweedfs:${SEAWEEDFS_VERSION:-4.00} # use a remote image
container_name: ${FILER_CONTAINER_NAME:-seaweedfs-filer}
volumes:
- ./filer_data:/data
command: 'filer -master="master:9333" -ip.bind=0.0.0.0 -port=8888 -metricsPort=9326'
depends_on:
- master
- volume
s3:
image: chrislusf/seaweedfs:${SEAWEEDFS_VERSION:-4.00} # use a remote image
container_name: ${S3_CONTAINER_NAME:-seaweedfs-s3}
ports:
- ${S3_PORT:-8333}:8333 # 只映射S3服务端口给Spring Boot应用访问
environment:
- S3_ACCESS_KEY=${S3_ACCESS_KEY:-seaweedfs}
- S3_SECRET_KEY=${S3_SECRET_KEY:-seaweedfs}
command: 's3 -filer="filer:8888" -ip.bind=0.0.0.0 -metricsPort=9327'
depends_on:
- filer

260
init Executable file
View File

@ -0,0 +1,260 @@
#!/bin/bash
# SeaweedFS初始化脚本
# 用于初始化或重新初始化SeaweedFS配置环境
# 获取脚本所在目录的绝对路径
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
# 切换工作目录到脚本所在目录
cd $SCRIPT_DIR
# 检查必要的命令
check_commands() {
if ! command -v openssl &> /dev/null; then
echo "错误: 未找到openssl命令请先安装"
exit 1
fi
if ! command -v direnv &> /dev/null; then
echo "警告: 未找到direnv命令建议安装以获得最佳体验"
fi
if ! command -v docker-compose &> /dev/null; then
echo "错误: 未找到docker-compose命令请先安装"
exit 1
fi
}
# 创建必要的目录结构
create_directories() {
echo "创建必要的目录结构..."
mkdir -p ./master_data
mkdir -p ./volume_data
mkdir -p ./filer_data
echo "目录结构创建完成"
}
# 检查docker-compose.yml文件是否存在
check_docker_compose() {
if [ ! -f "docker-compose.yml" ]; then
echo "警告: 未找到docker-compose.yml文件请确保该文件已存在"
echo "提示: 请手动创建或复制正确的docker-compose.yml文件"
fi
}
# 初始化配置文件
initialize_files() {
# 提示用户输入S3访问密钥步骤1
default_access_key="seaweedfs"
read -p "请输入S3_ACCESS_KEY [$default_access_key]: " s3_access_key
# 如果用户直接回车,使用默认值
if [ -z "$s3_access_key" ]; then
s3_access_key="$default_access_key"
fi
echo "S3_ACCESS_KEY设置为: $s3_access_key"
# 提示用户输入S3密钥步骤2
read -s -p "请输入S3_SECRET_KEY: " s3_secret_key
echo
read -s -p "请再次输入密码确认: " s3_secret_key_confirm
echo
# 验证密码一致性
if [ "$s3_secret_key" != "$s3_secret_key_confirm" ]; then
echo "错误: 两次输入的密码不一致"
return 1
fi
# 验证密码强度(可选)
if [ ${#s3_secret_key} -lt 8 ]; then
echo "警告: 密码长度少于8个字符建议使用强密码"
read -p "是否继续使用此密码?(y/n): " continue
if [ "$continue" != "y" ]; then
return 1
fi
fi
# 创建加密文件步骤3
echo "创建加密的密码文件..."
echo "请为加密文件设置一个密码(主密钥):"
echo -n "$s3_secret_key" | openssl enc -aes-256-cbc -salt -pbkdf2 -iter 10000 -out seaweedfs_password.enc
# 检查加密是否成功
if [ $? -ne 0 ]; then
echo "错误: 创建加密文件失败"
return 1
fi
# 设置加密文件权限
chmod 600 seaweedfs_password.enc
echo "加密文件创建成功权限设置为600"
# 提示用户输入SeaweedFS镜像版本步骤4
default_version="4.00"
read -p "请输入SeaweedFS镜像版本 [$default_version]: " seaweedfs_version
# 如果用户直接回车,使用默认值
if [ -z "$seaweedfs_version" ]; then
seaweedfs_version="$default_version"
fi
echo "SeaweedFS镜像版本设置为: $seaweedfs_version"
# 提示用户输入S3服务映射端口号步骤5
default_port="8333"
read -p "请输入S3服务映射端口号 [$default_port]: " s3_port
# 如果用户直接回车,使用默认值
if [ -z "$s3_port" ]; then
s3_port="$default_port"
fi
echo "S3服务映射端口号设置为: $s3_port"
# 提示用户输入各个容器的名称步骤6
default_master_name="seaweedfs-master"
read -p "请输入master容器名称 [$default_master_name]: " master_container_name
# 如果用户直接回车,使用默认值
if [ -z "$master_container_name" ]; then
master_container_name="$default_master_name"
fi
echo "master容器名称设置为: $master_container_name"
default_volume_name="seaweedfs-volume"
read -p "请输入volume容器名称 [$default_volume_name]: " volume_container_name
# 如果用户直接回车,使用默认值
if [ -z "$volume_container_name" ]; then
volume_container_name="$default_volume_name"
fi
echo "volume容器名称设置为: $volume_container_name"
default_filer_name="seaweedfs-filer"
read -p "请输入filer容器名称 [$default_filer_name]: " filer_container_name
# 如果用户直接回车,使用默认值
if [ -z "$filer_container_name" ]; then
filer_container_name="$default_filer_name"
fi
echo "filer容器名称设置为: $filer_container_name"
default_s3_name="seaweedfs-s3"
read -p "请输入s3容器名称 [$default_s3_name]: " s3_container_name
# 如果用户直接回车,使用默认值
if [ -z "$s3_container_name" ]; then
s3_container_name="$default_s3_name"
fi
echo "s3容器名称设置为: $s3_container_name"
# 创建.envrc文件
echo "创建.envrc配置文件..."
cat > .envrc << EOF
# SeaweedFS配置环境变量
export SEAWEEDFS_VERSION=$seaweedfs_version
export S3_PORT=$s3_port
export S3_ACCESS_KEY=$s3_access_key
export S3_SECRET_KEY=\$(openssl enc -aes-256-cbc -d -pbkdf2 -iter 10000 -in seaweedfs_password.enc)
export MASTER_CONTAINER_NAME=$master_container_name
export VOLUME_CONTAINER_NAME=$volume_container_name
export FILER_CONTAINER_NAME=$filer_container_name
export S3_CONTAINER_NAME=$s3_container_name
EOF
# 设置.envrc文件权限
chmod 600 .envrc
echo ".envrc文件创建成功权限设置为600"
# 检查docker-compose.yml文件是否存在
check_docker_compose
# 自动执行direnv allow并提供状态反馈
if command -v direnv &> /dev/null; then
echo ""
echo "📝 初始化完成!自动配置环境变量..."
echo "正在执行 direnv allow..."
if direnv allow > /dev/null 2>&1; then
echo "✅ direnv allow 执行成功!环境变量已启用"
else
echo "❌ direnv allow 执行失败,请手动运行 'direnv allow' 来启用环境变量"
fi
else
echo ""
echo "初始化完成建议安装direnv以获得更好的使用体验"
echo " macOS: brew install direnv"
echo " Linux: apt-get install direnv 或 yum install direnv"
fi
return 0
}
# 清理旧的容器(可选)
clean_old_containers() {
# 检查是否有旧的容器运行
echo "检查并清理可能的旧容器..."
local containers=("seaweedfs-master" "seaweedfs-volume" "seaweedfs-filer" "seaweedfs-s3" "oss-master-1" "oss-volume-1" "oss-filer-1" "oss-s3-1")
for container in "${containers[@]}"; do
if docker ps -a | grep -q "$container"; then
echo "停止并移除容器: $container"
docker stop "$container" > /dev/null 2>&1 || true
docker rm "$container" > /dev/null 2>&1 || true
fi
done
# 不清理网络配置,保持与外部网络的兼容性
}
# 主函数
main() {
echo "SeaweedFS环境初始化脚本"
echo "==================================="
# 检查必要的命令
check_commands
# 检查文件是否存在
if [ -f "seaweedfs_password.enc" ] && [ -f ".envrc" ]; then
echo ""
echo "检测到seaweedfs_password.enc和.envrc文件已存在"
read -p "是否重新初始化?这将覆盖现有配置!(y/n): " reinitialize
if [ "$reinitialize" != "y" ]; then
echo "初始化取消"
exit 0
fi
# 备份现有文件
backup_suffix="_bak_$(date +%Y%m%d%H%M%S)"
echo "备份现有文件..."
cp seaweedfs_password.enc "seaweedfs_password.enc$backup_suffix" 2>/dev/null
cp .envrc ".envrc$backup_suffix" 2>/dev/null
echo "备份完成"
fi
# 创建目录结构
create_directories
# 初始化配置文件
while ! initialize_files; do
echo "请重新输入配置信息..."
done
# 清理旧的容器
clean_old_containers
echo ""
echo "==================================="
echo "初始化成功!"
echo "使用说明:"
echo "1. 使用 './service start' 启动服务"
echo "2. 使用 './service stop' 停止服务"
echo "3. 使用 './service status' 查看服务状态"
echo "4. 使用 './service restart' 重启服务"
echo ""
echo "S3服务访问地址将为: http://localhost:${s3_port:-8333}"
}
# 执行主函数
main

396
service Executable file
View File

@ -0,0 +1,396 @@
#!/bin/bash
# SeaweedFS服务管理脚本
# 用法: ./service start|stop|status|restart|help
# 定义颜色输出
echo_green() { echo -e "\033[32m$1\033[0m"; }
echo_yellow() { echo -e "\033[33m$1\033[0m"; }
echo_red() { echo -e "\033[31m$1\033[0m"; }
echo_blue() { echo -e "\033[34m$1\033[0m"; }
# 日志函数
log_info() { echo_blue "[INFO] $1"; }
log_success() { echo_green "[SUCCESS] $1"; }
log_warning() { echo_yellow "[WARNING] $1"; }
log_error() { echo_red "[ERROR] $1"; }
# 获取脚本所在目录的绝对路径
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
# 切换工作目录到脚本所在目录
cd "$SCRIPT_DIR" || {
log_error "无法切换到脚本目录"
exit 1
}
# 检查系统命令
system_commands=("docker" "docker-compose" "openssl")
check_system_commands() {
for cmd in "${system_commands[@]}"; do
if ! command -v "$cmd" &> /dev/null; then
log_error "命令 $cmd 未安装,请先安装"
return 1
fi
done
return 0
}
# 检查并加载环境变量
load_env_variables() {
# 检查必要的命令
if ! check_system_commands; then
return 1
fi
# 首先尝试加载.envrc中的环境变量
if [ -f ".envrc" ]; then
log_info "加载.envrc中的环境变量..."
# 检查是否安装了direnv
if command -v direnv &> /dev/null; then
log_info "使用direnv加载环境变量"
eval "$(direnv export bash)"
else
log_warning "direnv未安装直接加载.envrc中的环境变量"
# 手动加载.envrc中的环境变量排除包含$(...)的行
while IFS= read -r line || [ -n "$line" ]; do
if [[ $line == export* && ! $line =~ \$\(.*\) ]]; then
eval "$line"
fi
done < .envrc
fi
else
log_error ".envrc文件不存在"
return 1
fi
# 特殊处理S3_SECRET_KEY因为它包含解密命令
if [ -z "$S3_SECRET_KEY" ] && [ -f "seaweedfs_password.enc" ]; then
log_info "解密S3_SECRET_KEY..."
# 直接执行解密命令
export S3_SECRET_KEY=$(openssl enc -aes-256-cbc -d -pbkdf2 -iter 10000 -in seaweedfs_password.enc 2>/dev/null)
if [ $? -ne 0 ]; then
log_error "密码解密失败,请检查密码是否正确"
log_error "提示: 可能需要重新初始化密码文件"
return 1
fi
fi
# 定义默认环境变量(如果未设置)
export SEAWEEDFS_VERSION=${SEAWEEDFS_VERSION:-4.00}
export S3_PORT=${S3_PORT:-8333}
export S3_ACCESS_KEY=${S3_ACCESS_KEY:-seaweedfs}
export S3_SECRET_KEY=${S3_SECRET_KEY:-seaweedfs}
export MASTER_CONTAINER_NAME=${MASTER_CONTAINER_NAME:-seaweedfs-master}
export VOLUME_CONTAINER_NAME=${VOLUME_CONTAINER_NAME:-seaweedfs-volume}
export FILER_CONTAINER_NAME=${FILER_CONTAINER_NAME:-seaweedfs-filer}
export S3_CONTAINER_NAME=${S3_CONTAINER_NAME:-seaweedfs-s3}
log_info "环境变量加载完成:"
log_info " - SeaweedFS版本: $SEAWEEDFS_VERSION"
log_info " - S3端口: $S3_PORT"
log_info " - 容器名称:"
log_info " * Master: $MASTER_CONTAINER_NAME"
log_info " * Volume: $VOLUME_CONTAINER_NAME"
log_info " * Filer: $FILER_CONTAINER_NAME"
log_info " * S3: $S3_CONTAINER_NAME"
return 0
}
# 创建必要的目录
create_required_directories() {
log_info "创建必要的数据目录..."
mkdir -p ./master_data ./volume_data ./filer_data
if [ $? -eq 0 ]; then
log_success "数据目录创建成功"
return 0
else
log_error "数据目录创建失败"
return 1
fi
}
# 检查容器是否存在且运行中
is_container_running() {
local container_name=$1
docker ps --format "{{.Names}}" | grep -q "^$container_name$"
return $?
}
# 清理旧容器(避免名称冲突)
clean_old_containers() {
local containers=("$MASTER_CONTAINER_NAME" "$VOLUME_CONTAINER_NAME" "$FILER_CONTAINER_NAME" "$S3_CONTAINER_NAME")
local removed_containers=0
log_info "检查并清理可能存在的旧容器..."
for container in "${containers[@]}"; do
if docker ps -a --format "{{.Names}}" | grep -q "^$container$"; then
log_warning "发现旧容器: $container正在清理..."
docker rm -f "$container" > /dev/null
if [ $? -eq 0 ]; then
log_success "已移除旧容器: $container"
removed_containers=$((removed_containers + 1))
else
log_error "无法移除容器: $container"
fi
fi
done
# 清理可能存在的旧网络
local network_name="$(basename "$SCRIPT_DIR")_default"
if docker network ls --format "{{.Name}}" | grep -q "^$network_name$"; then
log_warning "发现旧网络: $network_name正在清理..."
docker network rm "$network_name" > /dev/null
if [ $? -eq 0 ]; then
log_success "已移除旧网络: $network_name"
fi
fi
if [ $removed_containers -gt 0 ]; then
log_success "已清理 $removed_containers 个旧容器"
else
log_info "没有需要清理的旧容器"
fi
}
# 启动服务
start_service() {
log_info "启动SeaweedFS服务..."
# 加载环境变量
if ! load_env_variables; then
log_error "环境变量加载失败,服务启动终止"
return 1
fi
# 创建必要的目录
if ! create_required_directories; then
return 1
fi
# 检查docker-compose.yml是否存在
if [ ! -f "docker-compose.yml" ]; then
log_error "docker-compose.yml文件不存在"
return 1
fi
# 清理旧容器,避免名称冲突
clean_old_containers
# 启动docker容器
log_info "使用docker-compose启动服务..."
docker-compose up -d
# 检查启动是否成功
if [ $? -ne 0 ]; then
log_error "SeaweedFS服务启动失败"
return 1
fi
# 等待几秒钟让容器完全启动
log_info "服务正在初始化,请稍候..."
sleep 3
# 再次检查状态以确保所有容器都已启动
status_service
local status_result=$?
if [ $status_result -eq 0 ]; then
log_success "SeaweedFS服务启动完成!"
log_success "S3服务访问地址: http://localhost:$S3_PORT"
return 0
else
log_warning "服务可能未完全启动,请检查容器状态"
return 1
fi
}
# 停止服务
stop_service() {
log_info "停止SeaweedFS服务..."
# 加载环境变量(包括密码验证)
if ! load_env_variables; then
log_error "环境变量加载失败,服务停止终止"
return 1
fi
# 首先检查服务是否正在运行
if ! docker-compose ps | grep -q "Up"; then
log_info "SeaweedFS服务已经停止或未运行"
return 0
fi
# 使用docker-compose down停止服务
log_info "使用docker-compose停止所有服务..."
docker-compose down
if [ $? -eq 0 ]; then
log_success "SeaweedFS服务已成功停止"
return 0
else
log_warning "docker-compose down命令失败尝试直接停止容器..."
# 尝试逐个停止并删除容器
local containers=("$S3_CONTAINER_NAME" "$FILER_CONTAINER_NAME" "$VOLUME_CONTAINER_NAME" "$MASTER_CONTAINER_NAME")
local stopped=0
for container in "${containers[@]}"; do
if is_container_running "$container"; then
log_info "直接停止容器: $container"
docker stop "$container" > /dev/null
if [ $? -eq 0 ]; then
docker rm "$container" > /dev/null
log_success "已停止并移除容器: $container"
stopped=$((stopped + 1))
else
log_error "无法停止容器: $container"
fi
fi
done
if [ $stopped -gt 0 ]; then
log_success "已成功停止 $stopped 个容器"
return 0
else
log_error "无法停止任何容器请检查Docker状态"
return 1
fi
fi
}
# 检查服务状态
status_service() {
log_info "检查SeaweedFS服务状态..."
# 加载环境变量
if ! load_env_variables; then
log_error "环境变量加载失败,无法检查状态"
return 2
fi
# 定义容器数组
local containers=("$MASTER_CONTAINER_NAME" "$VOLUME_CONTAINER_NAME" "$FILER_CONTAINER_NAME" "$S3_CONTAINER_NAME")
local container_names=("Master" "Volume" "Filer" "S3")
local running_containers=0
local all_containers=${#containers[@]}
log_info "详细状态检查:"
# 检查每个容器的状态
for i in "${!containers[@]}"; do
local container=${containers[$i]}
local name=${container_names[$i]}
if is_container_running "$container"; then
log_success "✅ $name 容器 ($container) 正在运行"
running_containers=$((running_containers + 1))
else
# 检查容器是否存在但已停止
if docker ps -a --format "{{.Names}}" | grep -q "^$container$"; then
log_warning "⚠️ $name 容器 ($container) 已停止"
# 获取停止原因
local exit_code=$(docker inspect --format='{{.State.ExitCode}}' "$container")
log_warning " 退出代码: $exit_code"
else
log_error "❌ $name 容器 ($container) 不存在"
fi
fi
done
# 输出总体状态
log_info "--------------------------------------------------"
if [ $running_containers -eq $all_containers ]; then
log_success "✅ SeaweedFS服务完全正常运行"
log_success "S3服务访问地址: http://localhost:$S3_PORT"
return 0
elif [ $running_containers -gt 0 ]; then
log_warning "⚠️ SeaweedFS服务部分运行 ($running_containers/$all_containers 容器运行中)"
return 1
else
log_error "❌ SeaweedFS服务未运行"
return 2
fi
}
# 重启服务
restart_service() {
log_info "重启SeaweedFS服务..."
# 先停止服务
stop_service
local stop_result=$?
# 停止成功后,启动服务
if [ $stop_result -eq 0 ]; then
log_info "正在启动SeaweedFS服务..."
start_service
return $?
else
log_error "服务停止失败,无法重启"
return 1
fi
}
# 显示帮助信息
show_help() {
echo ""
echo_blue "📦 SeaweedFS服务管理脚本"
echo ""
echo "用法: ./service [command]"
echo ""
echo "命令:"
echo " start 启动SeaweedFS服务"
echo " stop 停止SeaweedFS服务"
echo " status 检查SeaweedFS服务状态"
echo " restart 重启SeaweedFS服务"
echo " help 显示此帮助信息"
echo ""
echo "示例:"
echo " ./service start # 启动所有SeaweedFS服务"
echo " ./service status # 检查服务运行状态"
echo " ./service restart # 重启所有服务"
echo ""
}
# 检查命令参数
if [ $# -eq 0 ]; then
log_error "请指定命令"
show_help
exit 1
fi
# 执行对应的命令
case "$1" in
start)
start_service
exit $?
;;
stop)
stop_service
exit $?
;;
status)
status_service
exit $?
;;
restart)
restart_service
exit $?
;;
help|\
-h|\
--help)
show_help
exit 0
;;
*)
log_error "未知命令 '$1'"
show_help
exit 1
;;
esac