Python依赖注入容器构建异步监控守护进程教程

Python依赖注入容器构建异步监控守护进程教程

python-dependency-injector Dependency injection framework for Python python-dependency-injector 项目地址: https://gitcode.com/gh_mirrors/py/python-dependency-injector

概述

本文将介绍如何使用Python依赖注入容器(dependency-injector)构建一个基于asyncio的监控守护进程。我们将创建一个能够定期检查网站可用性的监控服务,通过这个实际案例展示依赖注入在异步编程中的应用。

项目目标

我们将构建一个监控守护进程,主要功能包括:

  • 定期向目标网站发送HTTP请求
  • 记录响应状态码、内容长度和响应时间
  • 使用异步I/O提高监控效率
  • 采用依赖注入管理组件依赖关系

技术栈

  • Python 3
  • asyncio (异步I/O框架)
  • aiohttp (异步HTTP客户端)
  • dependency-injector (依赖注入框架)
  • Docker (容器化部署)

环境准备

项目结构

首先创建项目基础结构:

asyncio-daemon-tutorial/
├── monitoringdaemon/
│   ├── __init__.py
│   ├── __main__.py
│   └── containers.py
├── config.yml
├── docker-compose.yml
├── Dockerfile
└── requirements.txt

依赖配置

在requirements.txt中添加以下依赖:

dependency-injector
aiohttp
pyyaml
pytest
pytest-asyncio
pytest-cov

Docker配置

创建Dockerfile:

FROM python:3.13-bookworm

ENV PYTHONUNBUFFERED=1

WORKDIR /code
COPY . /code/

RUN apt-get install openssl \
 && pip install --upgrade pip \
 && pip install -r requirements.txt \
 && rm -rf ~/.cache

CMD ["python", "-m", "monitoringdaemon"]

docker-compose.yml配置:

services:
  monitor:
    build: ./
    image: monitoring-daemon
    volumes:
      - "./:/code"

核心组件实现

1. 依赖注入容器

容器是应用的核心,管理所有组件及其依赖关系。首先创建基础容器:

# containers.py
import logging
import sys
from dependency_injector import containers, providers

class Container(containers.DeclarativeContainer):
    config = providers.Configuration(yaml_files=["config.yml"])
    
    logging = providers.Resource(
        logging.basicConfig,
        stream=sys.stdout,
        level=config.log.level,
        format=config.log.format,
    )

2. 主程序入口

# __main__.py
from dependency_injector.wiring import Provide, inject
from .dispatcher import Dispatcher
from .containers import Container

@inject
def main(dispatcher: Dispatcher = Provide[Container.dispatcher]) -> None:
    dispatcher.run()

if __name__ == "__main__":
    container = Container()
    container.init_resources()
    container.wire(modules=[__name__])
    main()

3. 监控调度器

调度器负责管理所有监控任务:

# dispatcher.py
import asyncio
import logging
import signal
import time
from typing import List
from .monitors import Monitor

class Dispatcher:
    def __init__(self, monitors: List[Monitor]) -> None:
        self._monitors = monitors
        self._monitor_tasks: List[asyncio.Task] = []
        self._logger = logging.getLogger(self.__class__.__name__)
        self._stopping = False

    def run(self) -> None:
        asyncio.run(self.start())

    async def start(self) -> None:
        self._logger.info("Starting up")
        for monitor in self._monitors:
            self._monitor_tasks.append(
                asyncio.create_task(self._run_monitor(monitor)),
            )
        asyncio.get_event_loop().add_signal_handler(signal.SIGTERM, self.stop)
        asyncio.get_event_loop().add_signal_handler(signal.SIGINT, self.stop)
        await asyncio.gather(*self._monitor_tasks, return_exceptions=True)
        self.stop()

    # 其他方法...

4. HTTP监控实现

创建HTTP客户端和监控器:

# http.py
from aiohttp import ClientSession, ClientTimeout, ClientResponse

class HttpClient:
    async def request(self, method: str, url: str, timeout: int) -> ClientResponse:
        async with ClientSession(timeout=ClientTimeout(timeout)) as session:
            async with session.request(method, url) as response:
                return response

# monitors.py
import logging
import time
from typing import Dict, Any
from .http import HttpClient

class HttpMonitor(Monitor):
    def __init__(self, http_client: HttpClient, options: Dict[str, Any]) -> None:
        self._client = http_client
        self._method = options.pop("method")
        self._url = options.pop("url")
        self._timeout = options.pop("timeout")
        super().__init__(check_every=options.pop("check_every"))

    async def check(self) -> None:
        time_start = time.time()
        response = await self._client.request(
            method=self._method,
            url=self._url,
            timeout=self._timeout,
        )
        # 记录监控结果...

配置监控目标

在config.yml中配置监控目标:

log:
  level: "INFO"
  format: "[%(asctime)s] [%(levelname)s] [%(name)s]: %(message)s"

monitors:
  example:
    method: "GET"
    url: "http://example.com"
    timeout: 5
    check_every: 10

运行与测试

构建并运行容器:

docker compose build
docker compose up

总结

通过本教程,我们实现了一个基于依赖注入的异步监控守护进程,展示了:

  1. 如何使用dependency-injector管理组件依赖
  2. 如何构建asyncio守护进程
  3. 如何实现可扩展的监控系统
  4. 容器化部署的最佳实践

这个架构具有良好的扩展性,可以方便地添加新的监控类型或调整监控策略。

python-dependency-injector Dependency injection framework for Python python-dependency-injector 项目地址: https://gitcode.com/gh_mirrors/py/python-dependency-injector

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

顾涓轶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值