基于Python+Django+psutil的轻量化服务器自动化监控平台实战

一、项目背景与痛点

日常运维工作中,服务器状态巡检是保障业务稳定运行的核心工作。中小团队大多依赖人工定时登录服务器查看资源状态,大型运维监控平台又部署复杂、成本高昂,日常运维存在大量难以解决的痛点:

1.1 传统运维监控的痛点

  • 人工巡检效率低下,无法7×24值守:运维人员需要早晚定时登录每台服务器,手动输入命令查看CPU、内存、磁盘、网络状态,夜间、节假日无人值守,故障无法第一时间发现;
  • 故障发现滞后,极易引发业务雪崩:服务器内存溢出、磁盘爆满、核心进程挂掉、端口异常等问题,往往等到业务报错才被发现,故障持续时间长,影响线上业务稳定性;
  • 商用监控平台太重,部署成本高:Prometheus+Grafana、Zabbix等专业监控组件部署繁琐、学习成本高,低配服务器无法承载,小团队没必要部署重型监控系统;
  • 无历史数据留存,无法复盘故障:人工巡检无历史指标记录,服务器突发卡顿、负载飙升后,无法追溯之前的资源变化曲线,难以定位故障根因;
  • 告警方式单一,无法及时触达运维:传统监控大多仅后台页面告警,运维人员不登录后台就无法感知故障,错过最佳故障处理时机。

1.2 项目解决方案

针对以上运维巡检痛点,本次基于Python系统监控库 + Django4.2后端框架,搭建轻量化服务器自动化监控巡检平台,依托psutil采集服务器硬件资源指标、进程状态、端口监控数据,搭配Celery定时任务实现分钟级自动巡检,支持后台可视化图表展示、异常阈值判定、邮件+钉钉机器人双渠道告警。

项目特点

  • 无需复杂中间件、部署零难度
  • 完美适配中小团队单机/多服务器轻量化运维监控需求
  • 补齐Django运维自动化实战方向
  • 和往期所有项目无任何功能重合

二、核心目标与定位

2.1 核心目标

搭建轻量化、开箱即用的服务器无人值守监控系统,实现以下全流程自动化:

  1. 定时采集:服务器CPU/内存/磁盘/网络/进程/端口六大核心指标
  2. 指标入库存储:MySQL持久化存储历史监控数据
  3. 可视化展示:ECharts渲染实时趋势曲线
  4. 告警判定:自定义告警阈值智能判断
  5. 异常推送:多渠道实时告警通知
  6. 报表导出:自动生成每日巡检报告

最终效果:替代人工日常巡检,故障告警响应时间缩短至1分钟内。

2.2 项目定位

  • 精准定位:轻量级单机/分布式服务器运维监控平台
  • 技术理念:摒弃重型监控架构,纯Python原生psutil采集指标
  • 部署优势:Django快速搭建管理后台,无需额外部署时序数据库
  • 模式支持:支持单服务器本地监控、多服务器分布式监控两种模式
  • 使用体验:运维人员可通过网页端随时查看服务器实时状态与历史走势

2.3 核心设计理念

  • 轻量无依赖:最小化外部依赖,低配服务器也能稳定运行
  • 定时自动采集:Celery实现无人值守定时巡检
  • 可视化直观展示:ECharts图表直观展示资源变化趋势
  • 异常多渠道告警:钉钉+邮件双渠道确保告警触达
  • 历史数据可追溯:完整留存监控历史,支持故障复盘

三、整体技术方案

3.1 系统架构设计

项目采用Django MVT基础架构 + Celery定时任务,Python原生psutil库完成系统指标无侵入采集,前端ECharts渲染监控曲线图,整体分层架构如下:
#mermaid-svg-H1fW1OV03y9NoF8G{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-H1fW1OV03y9NoF8G .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-H1fW1OV03y9NoF8G .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-H1fW1OV03y9NoF8G .error-icon{fill:#552222;}#mermaid-svg-H1fW1OV03y9NoF8G .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-H1fW1OV03y9NoF8G .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-H1fW1OV03y9NoF8G .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-H1fW1OV03y9NoF8G .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-H1fW1OV03y9NoF8G .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-H1fW1OV03y9NoF8G .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-H1fW1OV03y9NoF8G .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-H1fW1OV03y9NoF8G .marker{fill:#333333;stroke:#333333;}#mermaid-svg-H1fW1OV03y9NoF8G .marker.cross{stroke:#333333;}#mermaid-svg-H1fW1OV03y9NoF8G svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-H1fW1OV03y9NoF8G p{margin:0;}#mermaid-svg-H1fW1OV03y9NoF8G .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-H1fW1OV03y9NoF8G .cluster-label text{fill:#333;}#mermaid-svg-H1fW1OV03y9NoF8G .cluster-label span{color:#333;}#mermaid-svg-H1fW1OV03y9NoF8G .cluster-label span p{background-color:transparent;}#mermaid-svg-H1fW1OV03y9NoF8G .label text,#mermaid-svg-H1fW1OV03y9NoF8G span{fill:#333;color:#333;}#mermaid-svg-H1fW1OV03y9NoF8G .node rect,#mermaid-svg-H1fW1OV03y9NoF8G .node circle,#mermaid-svg-H1fW1OV03y9NoF8G .node ellipse,#mermaid-svg-H1fW1OV03y9NoF8G .node polygon,#mermaid-svg-H1fW1OV03y9NoF8G .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-H1fW1OV03y9NoF8G .rough-node .label text,#mermaid-svg-H1fW1OV03y9NoF8G .node .label text,#mermaid-svg-H1fW1OV03y9NoF8G .image-shape .label,#mermaid-svg-H1fW1OV03y9NoF8G .icon-shape .label{text-anchor:middle;}#mermaid-svg-H1fW1OV03y9NoF8G .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-H1fW1OV03y9NoF8G .rough-node .label,#mermaid-svg-H1fW1OV03y9NoF8G .node .label,#mermaid-svg-H1fW1OV03y9NoF8G .image-shape .label,#mermaid-svg-H1fW1OV03y9NoF8G .icon-shape .label{text-align:center;}#mermaid-svg-H1fW1OV03y9NoF8G .node.clickable{cursor:pointer;}#mermaid-svg-H1fW1OV03y9NoF8G .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-H1fW1OV03y9NoF8G .arrowheadPath{fill:#333333;}#mermaid-svg-H1fW1OV03y9NoF8G .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-H1fW1OV03y9NoF8G .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-H1fW1OV03y9NoF8G .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-H1fW1OV03y9NoF8G .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-H1fW1OV03y9NoF8G .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-H1fW1OV03y9NoF8G .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-H1fW1OV03y9NoF8G .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-H1fW1OV03y9NoF8G .cluster text{fill:#333;}#mermaid-svg-H1fW1OV03y9NoF8G .cluster span{color:#333;}#mermaid-svg-H1fW1OV03y9NoF8G div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-H1fW1OV03y9NoF8G .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-H1fW1OV03y9NoF8G rect.text{fill:none;stroke-width:0;}#mermaid-svg-H1fW1OV03y9NoF8G .icon-shape,#mermaid-svg-H1fW1OV03y9NoF8G .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-H1fW1OV03y9NoF8G .icon-shape p,#mermaid-svg-H1fW1OV03y9NoF8G .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-H1fW1OV03y9NoF8G .icon-shape .label rect,#mermaid-svg-H1fW1OV03y9NoF8G .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-H1fW1OV03y9NoF8G .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-H1fW1OV03y9NoF8G .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-H1fW1OV03y9NoF8G :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 定时任务调度层

Celery分钟级巡检
系统指标采集层

psutil采集硬件指标
指标阈值判断层

匹配自定义告警阈值
数据持久化层

MySQL存储历史监控数据
可视化图表层

ECharts渲染趋势曲线
多渠道告警层

钉钉机器人+邮件告警
巡检报表导出层

自动生成每日巡检报告

3.2 技术栈清单

后端服务
  • 开发语言:Python 3.11
  • Web框架:Django 4.2 + Django原生后台管理
  • 指标采集:psutil 原生Python系统监控库,无侵入采集服务器硬件资源
  • 定时任务:Celery 5.2 + Redis 7.0,支持自定义巡检频率
  • 数据存储:MySQL存储历史监控指标,Redis缓存实时最新监控数据
前端与可视化
  • 数据可视化:ECharts 前端渲染CPU/内存/磁盘实时趋势折线图
  • 报表生成:python-docx 自动生成每日服务器巡检Word报告
告警服务
  • 即时通讯:钉钉自定义机器人Webhook推送
  • 邮件通知:Python内置smtplib邮件告警服务
权限管控
  • 用户管理:Django原生登录权限系统
  • 角色区分:管理员和只读运维账号权限分离

四、核心能力模块详解

4.1 多维度服务器指标自动采集模块

基于psutil无侵入采集服务器全维度运行指标,无需安装服务器插件,兼容Windows和Linux双系统服务器,覆盖运维核心关注指标:

采集指标范围
  • CPU指标:实时使用率、单核/多核负载、运行总时长
  • 内存指标:总内存、已用内存、剩余内存、内存使用率
  • 磁盘指标:磁盘总容量、已用容量、磁盘使用率、磁盘读写速率
  • 网络指标:实时上行/下行网速、总收发流量
  • 进程监控:核心业务进程存活状态、进程CPU/内存占用
  • 端口监控:自定义业务端口存活检测,防止端口监听异常

4.2 自定义告警阈值配置模块

运维人员可在后台可视化配置各项指标告警红线,适配不同服务器硬件配置差异,无需修改代码即可调整告警规则:

告警配置策略
  • 默认阈值:CPU使用率≥85%、内存使用率≥90%、磁盘使用率≥90%触发告警
  • 进程告警:核心业务进程意外退出,立即触发紧急告警
  • 告警防抖机制:短时间内连续异常仅推送一次告警,避免消息轰炸运维人员
  • 告警分级:分为一般警告、严重故障两级,差异化推送告警文案

4.3 Celery无人值守定时巡检模块

依托Celery定时任务实现无人值守巡检,支持自由配置巡检频率,全程无需人工干预:

定时任务策略
  • 高频实时巡检:1分钟一次采集核心资源指标,保证监控实时性
  • 每日定点报表:每日凌晨自动生成昨日全天服务器巡检报告
  • 历史数据自动清理:定时清理30天前过期监控数据,避免数据库数据堆积拖慢系统速度

4.4 前端可视化监控大盘模块

整合ECharts实现一站式监控大屏,直观展示服务器运行状态,告别枯燥命令行数据:

监控大屏功能
  • 实时卡片展示:首页直观展示当前各项指标实时数值
  • 趋势折线图:展示近1小时、近24小时CPU/内存波动曲线,快速定位资源峰值
  • 告警日志面板:集中展示所有历史告警记录,包含告警时间、异常指标、恢复时间
  • 服务器状态总览:一键查看所有接入服务器在线/离线状态

4.5 双渠道异常告警推送模块

打破后台告警局限,故障第一时间触达运维人员,保证夜间、节假日故障及时处理:

告警推送机制
  • 钉钉机器人告警:服务器异常实时推送告警消息至运维钉钉群
  • 邮件告警:同步发送详细故障邮件,附带故障时刻完整指标数据
  • 故障恢复通知:服务器指标恢复正常后,自动推送恢复消息,形成告警闭环

4.6 自动化巡检报表模块

系统每日自动生成Word格式服务器巡检报告,包含全天指标均值、峰值、告警次数、故障时长,支持一键下载归档,满足运维每日工作汇报、机房巡检台账归档需求。


五、创新价值与亮点

5.1 技术优势对比

特性 传统监控平台 本项目方案 优势对比
部署复杂度 高(需部署时序数据库、中间件) 低(纯Python+Django) 部署简单,零门槛
资源消耗 高(占用大量服务器资源) 低(1核2G即可运行) 适合低配服务器
侵入性 高(需安装代理插件) 无(psutil原生采集) 无服务器侵入
告警渠道 单一(通常仅后台告警) 双渠道(钉钉+邮件) 告警触达率高
历史追溯 依赖额外配置 内置完整历史曲线 故障复盘方便

5.2 核心亮点

  1. 极致轻量化,低配服务器也能跑:对比Zabbix、Prometheus重型监控平台,本项目无复杂依赖、无时序数据库要求,1核2G低配服务器即可稳定运行,零部署门槛;
  2. 原生Python采集,无服务器侵入:依托psutil原生库采集数据,无需在被监控服务器安装代理插件,部署简单快捷;
  3. 双渠道告警,不漏任何故障:钉钉群实时弹窗+邮件详细报告双重告警,彻底解决运维人员看不到后台告警的痛点;
  4. 可视化趋势追溯,故障可复盘:完整留存历史监控曲线,能够精准复盘服务器卡顿、负载飙升的根因;
  5. 开箱即用免配置:内置默认告警阈值,部署即可直接使用,同时支持后台可视化自定义规则,适配各类业务服务器。

六、应用前景与落地场景

6.1 适用场景

  • 中小研发团队线上服务器监控:替代人工日常巡检,7×24小时值守线上业务服务器,保障后端项目稳定运行;
  • 个人云服务器运维监控:个人阿里云/腾讯云轻量服务器自用监控,及时发现服务器异常;
  • 机房内网服务器统一巡检:内网批量接入多台服务器,统一大屏监控所有设备运行状态;
  • Django运维自动化实战项目:补齐定时任务、系统运维采集、消息推送、数据可视化运维方向,区别于常规业务管理系统,简历项目亮点突出。

6.2 部署模式

单机监控模式
bash 复制代码
# 单服务器本地监控部署
python manage.py runserver 0.0.0.0:8000
celery -A monitor_project worker --loglevel=info
分布式监控模式
bash 复制代码
# 多服务器分布式监控
# 主控服务器运行Web服务
python manage.py runserver 0.0.0.0:8000

# 被监控服务器运行采集客户端
python client_collector.py --server-id=server001

七、完整代码结构示例

7.1 项目整体目录结构

bash 复制代码
django-server-monitor/
├── manage.py
├── monitor_project/              # 项目全局配置目录
│   ├── settings.py               # Celery定时任务、告警机器人、数据库配置
│   ├── urls.py                   # 前后端路由分发
│   └── celery.py                 # 定时任务全局初始化配置
├── apps/                         # 模块化业务应用
│   ├── server_collect/           # 服务器指标采集核心模块
│   ├── alert_config/             # 告警阈值配置、告警日志模块
│   ├── message_push/             # 钉钉、邮件消息推送模块
│   ├── monitor_dashboard/        # ECharts可视化大盘模块
│   └── report_export/            # 自动巡检报表生成与下载模块
├── core/                         # 公共工具封装
│   ├── system_collect.py         # psutil系统指标采集工具类
│   ├── dingtalk_alert.py         # 钉钉机器人告警工具
│   ├── email_alert.py            # 邮件告警工具
│   └── monitor_task.py           # Celery定时巡检主任务
├── static/                       # ECharts图表静态资源
├── templates/                    # 监控大盘前端页面模板
├── media/report/                 # 自动生成的巡检报表存储目录
├── requirements.txt              # Python项目依赖清单
└── docker-compose.yml            # 一键容器化部署脚本

7.2 核心可运行代码片段

示例1:psutil服务器全指标采集工具类(core/system_collect.py)
python 复制代码
import psutil
import time

class ServerMonitorCollect:
    """服务器硬件资源指标采集工具类"""

    @staticmethod
    def get_cpu_info():
        """获取CPU使用率与负载"""
        cpu_percent = psutil.cpu_percent(interval=1)
        load_avg = psutil.getloadavg()
        return {
            "cpu_percent": cpu_percent,
            "load_1m": load_avg[0],
            "load_5m": load_avg[1],
            "load_15m": load_avg[2]
        }

    @staticmethod
    def get_memory_info():
        """获取内存使用信息"""
        mem = psutil.virtual_memory()
        return {
            "mem_total": round(mem.total / 1024 / 1024 / 1024, 2),
            "mem_used": round(mem.used / 1024 / 1024 / 1024, 2),
            "mem_percent": mem.percent
        }

    @staticmethod
    def get_disk_info():
        """获取磁盘使用信息"""
        disk = psutil.disk_usage('/')
        return {
            "disk_total": round(disk.total / 1024 / 1024 / 1024, 2),
            "disk_used": round(disk.used / 1024 / 1024 / 1024, 2),
            "disk_percent": disk.percent
        }

    @staticmethod
    def get_net_info():
        """获取网络收发流量"""
        net_before = psutil.net_io_counters()
        time.sleep(1)
        net_after = psutil.net_io_counters()
        sent_speed = round((net_after.bytes_sent - net_before.bytes_sent) / 1024, 2)
        recv_speed = round((net_after.bytes_recv - net_before.bytes_recv) / 1024, 2)
        return {"sent_speed": sent_speed, "recv_speed": recv_speed}

    @classmethod
    def get_all_server_info(cls):
        """一次性获取全部服务器监控指标"""
        return {
            "cpu": cls.get_cpu_info(),
            "memory": cls.get_memory_info(),
            "disk": cls.get_disk_info(),
            "network": cls.get_net_info(),
            "collect_time": time.strftime("%Y-%m-%d %H:%M:%S")
        }
示例2:Celery定时巡检主任务(core/monitor_task.py)
python 复制代码
from celery import shared_task
from core.system_collect import ServerMonitorCollect
from core.dingtalk_alert import DingTalkAlert
from apps.alert_config.models import AlertThreshold, AlertLog
from django.utils import timezone

# 读取后台配置的告警阈值
THRESHOLD = AlertThreshold.objects.first()

@shared_task
def server_auto_monitor_task():
    """Celery定时服务器巡检主任务"""
    # 1. 采集全量服务器指标
    monitor_data = ServerMonitorCollect.get_all_server_info()
    cpu_per = monitor_data["cpu"]["cpu_percent"]
    mem_per = monitor_data["memory"]["mem_percent"]
    disk_per = monitor_data["disk"]["disk_percent"]

    # 2. 阈值判断,触发告警
    alert_msg = ""
    if cpu_per >= THRESHOLD.cpu_threshold:
        alert_msg += f"【CPU异常】当前CPU使用率:{cpu_per}%,超过告警阈值{THRESHOLD.cpu_threshold}%\n"
    if mem_per >= THRESHOLD.mem_threshold:
        alert_msg += f"【内存异常】当前内存使用率:{mem_per}%,超过告警阈值{THRESHOLD.mem_threshold}%\n"
    if disk_per >= THRESHOLD.disk_threshold:
        alert_msg += f"【磁盘异常】当前磁盘使用率:{disk_per}%,超过告警阈值{THRESHOLD.disk_threshold}%\n"

    # 3. 存在异常则推送钉钉告警并写入告警日志
    if alert_msg:
        full_msg = f"⚠️服务器监控告警通知\n告警时间:{timezone.now()}\n异常详情:\n{alert_msg}"
        DingTalkAlert.send_message(full_msg)
        # 写入告警日志
        AlertLog.objects.create(
            alert_content=alert_msg,
            alert_level="严重故障",
            alert_status="未恢复"
        )
        return {"status": "alert", "msg": "服务器存在资源异常,已推送告警消息"}
    return {"status": "normal", "msg": "服务器运行状态正常"}
示例3:钉钉机器人消息推送工具(core/dingtalk_alert.py)
import 复制代码
class DingTalkAlert:
    """钉钉机器人消息推送工具"""
    # 替换为自己的钉钉机器人Webhook地址
    DING_WEBHOOK = "https://oapi.dingtalk.com/robot/send?access_token=xxxxxxx"

    @staticmethod
    def send_message(content: str):
        """发送文本告警消息至钉钉群"""
        headers = {"Content-Type": "application/json"}
        data = {
            "msgtype": "text",
            "text": {
                "content": content
            }
        }
        try:
            res = requests.post(DingTalkAlert.DING_WEBHOOK, json=data, headers=headers, timeout=5)
            return res.json()
        except Exception as e:
            print(f"钉钉消息推送失败:{str(e)}")
            return None

八、总结与展望

本篇博客基于Python+Django+psutil打造轻量化服务器自动化监控平台,聚焦运维自动化赛道,和往期笔记系统、校园商城、AI图像处理、代码评审等业务类、AI类项目完全区分,填补了Django运维监控实战项目的空白。

项目完整覆盖Python系统运维采集、Celery定时任务调度、第三方消息接口对接、ECharts数据可视化、告警日志台账管理、自动化报表生成六大核心后端能力,代码通俗易懂、业务逻辑贴合真实运维工作,既可以直接部署用于线上服务器值守,也能作为简历中差异化极强的后端实战项目,避开烂大街的商城、管理系统项目。

相关推荐
梦奇不是胖猫1 小时前
[ 计算机网络 | 第四章 ] 网络层 02 网际协议IP
运维·服务器·网络·网络协议·tcp/ip·计算机网络
愿天垂怜1 小时前
【C++脚手架】etcd 的介绍与使用
java·linux·服务器·c语言·c++·中间件·etcd
烤代码的吐司君1 小时前
Redis 简介和安装
python
春生野草1 小时前
Socket、Servlet、Tomcat
运维·服务器·网络
小则又沐风a1 小时前
进程篇: 进程概念的补充(了解环境变量和虚拟地址空间)
linux·运维·服务器·c++
say_fall1 小时前
深入理解Linux内核进程调度:从基础概念到O(1)调度算法
linux·运维·服务器·算法·计算机组成
毕设做完了吗?1 小时前
YOLO+paddlecor的智能车牌识别系统
人工智能·python·yolo·目标检测·计算机视觉
li星野1 小时前
RAG优化系列:自适应检索(Adaptive Retrieval)——让系统智能选择是否检索
人工智能·python·学习
青梅橘子皮1 小时前
Linux---命令行参数和环境变量
linux·运维·服务器