• DevOps(十一)Jenkins实战之Web发布脚本优化与Supervisor


    目录

    一、Supervisor详解

    主要特性

    安装 Supervisor

    配置 Supervisor

    修改配置文件

    启动 Supervisor

    使用 supervisorctl 管理进程

    二、修改和优化发布过程

    1、创建django.conf

    2、优化Jenkins脚本

    3、示例代码详解

    4、执行任务,并看结果


    在《DevOps(十)Jenkins实战之发布Django开发Web应用》的博文中,我们学习了创建一个简单的Jenkins脚本用来发布Django开发Web应用,在Jenkins任务执行的时候会有一个问题,就是git拉取代码以后,启动django应用以后会卡住,不会执行后面的步骤了,jenkins一直在等待django应用执行的结果,导致后面的任务无法执行。怎么解决这个问题呢?我们需要引进一个工具Supervisor,这个工具是用来管理进程,一般和Python应用一起配合使用,可以确保django应用在服务器后台运行。本篇博文当中我们首先介绍Supervisor,然后用给大家演示修改Jenkins脚本,优化这个发布任务。

    一、Supervisor详解

    Supervisor是一个用Python编写的客户端/服务器系统,用于监控和控制UNIX-like操作系统上的多个进程。它主要用于管理长时间运行的后台进程,并且广泛应用于Python web应用程序(如Django、Flask等)的生产环境中。

    主要特性

    1. 自动重启: 如果被监控的进程意外崩溃,Supervisor可以自动重启它们。
    2. 日志记录: 自动管理每个管理的进程的标准输入、输出和错误日志。
    3. 进程分组: 将相关的进程组合为一个组,可以同时管理。
    4. Web界面: 提供一个可选的web界面,用于查看进程状态和发送控制命令。
    5. 事件监听: 可以配置事件监听器,响应进程状态的改变。
    6. 易于配置: 使用INI风格的配置文件进行进程管理。

    安装 Supervisor

    Supervisor 可以通过 Python 的包管理工具 pip 安装。首先确保你的系统中安装了 Python 和 pip。

    sudo apt-get install python-pip  # Debian/Ubuntu
    

    然后使用 pip 安装 Supervisor:

    sudo pip install supervisor
    

    配置 Supervisor

    安装完成后,你需要创建一个配置文件。Supervisor 提供了一个工具 echo_supervisord_conf,用于生成默认的配置文件:

    echo_supervisord_conf > /etc/supervisord.conf
    

    你可以将此文件放在任何地方,但通常放在 /etc/supervisord.conf

    修改配置文件

    打开 /etc/supervisord.conf,进行以下基本配置:

    • [unix_http_server]: 配置http服务器,用于内部通信。

      1. ;http://localhost:9001
      2. file=/tmp/supervisor.sock ; (the path to the socket file)
    • [supervisord]: 主进程的日志配置。

      1. logfile=/var/log/supervisor/supervisord.log ; (main log file path)
      2. logfile_maxbytes=50MB ; (max log file bytes b4 rotation)
      3. logfile_backups=10 ; (num of main logfile rotation backups)
      4. loglevel=info ; (logging level)
      5. pidfile=/var/run/supervisord.pid ; (pidfile path)
    • [supervisorctl]: 控制工具的配置。

      serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL  for a unix socket
      
    • [program:x]: 定义要管理的程序。

      1. [program:yourprogramname]
      2. command=/path/to/command ; the program (relative uses PATH, can take args)
      3. autostart=true ; start at supervisord start (default: true)
      4. autorestart=true ; retstart at unexpected quit (default: true)
      5. stderr_logfile=/var/log/yourprogramname/err.log
      6. stdout_logfile=/var/log/yourprogramname/out.log

    启动 Supervisor

    配置文件设置完成后,可以使用以下命令启动 Supervisor:

    supervisord -c /etc/supervisord.conf
    

    使用 supervisorctl 管理进程

    supervisorctl 是一个命令行客户端工具,用于与 Supervisord 交互。一些基本的命令包括:

    1. supervisorctl status # 查看所有程序的状态
    2. supervisorctl stop all # 停止所有程序
    3. supervisorctl start all # 启动所有程序
    4. supervisorctl restart all # 重启所有程序
    5. supervisorctl update # 重新载入配置文件并添加/删除管理的程序

    二、修改和优化发布过程

    我们这次在源码增加一个Supervisor的配置django.conf文件,然后git将所有源码拉下来以后,将源码拷到一个python应用发布的目录比如/opt/HelloWorld,然后将django.conf复制到/etc/supervisor/conf.d/目录,然后重新载入配置文件,重启django应用。具体步骤如下:

    1、创建django.conf

    在源码根目录新建一个配置文件django.conf,内容如下:

    1. [program:django]
    2. command=python manage.py runserver 0.0.0.0:8081
    3. directory=/opt/HelloWorld
    4. user=jenkins
    5. autostart=true
    6. autorestart=true
    7. stderr_logfile=/var/log/django/django.err.log
    8. stdout_logfile=/var/log/django/django.out.log

    这个配置是在 Supervisor 配置文件中定义的,用于管理一个名为 "django" 的程序。这里,配置指定了如何启动、运行、监控和记录 Django 应用的日志。下面是每个配置项的详细解释:

    • [program:django]: 这一行定义了一个新的程序部分,名为 "django"。在 Supervisor 中,每个被管理的程序都需要在配置文件中以 [program:name] 的形式独立设置。

    • command: 指定启动程序的命令。在这个例子中,命令是 python manage.py runserver 0.0.0.0:8000,这是启动 Django 开发服务器的标准方式,监听所有可用 IP 的 8000 端口。注意,实际生产环境中不推荐使用 Django 自带的开发服务器,而应该使用像 Gunicorn 或 uWSGI 这样的生产级应用服务器。

    • directory: 设置程序执行时的工作目录。对于这个 Django 应用,工作目录被设置为 /opt/HelloWorld。Supervisor 会在启动程序前切换到这个目录。

    • user: 指定运行该程序的用户。这里配置为 jenkins,意味着 Django 应用将以 jenkins 用户的权限运行。这有助于限制程序的权限,增加系统的安全性。

    • autostart: 表示 Supervisor 会在启动时自动启动这个程序。设置为 true,确保每次 Supervisor 启动时,Django 应用也会自动启动。

    • autorestart: 配置程序在退出时是否自动重启。设置为 true,意味着如果 Django 应用意外停止或崩溃,Supervisor 会自动重新启动它。

    • stderr_logfile: 指定标准错误流的日志文件路径。在这个配置中,所有标准错误输出将被重定向到 /var/log/django/django.err.log。这对于调试和记录错误非常有用。

    • stdout_logfile: 指定标准输出流的日志文件路径。在这个配置中,所有标准输出将被记录在 /var/log/django/django.out.log。这可以帮助您审查程序的运行输出。

    这个配置是一个典型的例子,展示了如何使用 Supervisor 来管理一个 Django 应用。通过这种方式,您可以确保应用的持续运行,并且能够在出现问题时迅速响应。在设置完这些配置后,您需要确保相应的日志目录存在,并且 jenkins 用户有权写入这些目录。

    注意:需要在jenkins服务器创建/var/log/django目录,并给这个目录jenkin所有权。完成脚本以后,提交发布到gitlab。

    2、优化Jenkins脚本

    打开jenkins管理界面,选择前面我们创建的jenkins任务HelloWorld。

    点击配置按钮,进入配置界面。

    编写jenkins脚本,然后保存。

    Jenkins脚本代码如下:

    1. pipeline {
    2. agent any
    3. stages {
    4. stage('Checkout') {
    5. steps {
    6. git branch: 'main', credentialsId: 'sean', url: 'http://gitlab.povison-pro.com/Sean/helloworld.git'
    7. }
    8. }
    9. stage('Stop Application') {
    10. steps {
    11. script {
    12. // 检查 Django 服务是否存在
    13. def serviceStatus = sh(script: "sudo supervisorctl status django || true", returnStdout: true).trim()
    14. if (serviceStatus.contains("RUNNING")) {
    15. // 如果服务正在运行,尝试停止它
    16. sh 'sudo supervisorctl stop django'
    17. } else {
    18. echo "Django process not running or does not exist."
    19. }
    20. }
    21. }
    22. }
    23. stage('Prepare Deployment') {
    24. steps {
    25. // 清理旧代码并复制新代码到 /opt/HelloWorld
    26. sh 'sudo rm -rf /opt/HelloWorld/*'
    27. sh 'sudo cp -R . /opt/HelloWorld'
    28. }
    29. }
    30. stage('Configure Supervisor') {
    31. steps {
    32. // 假设 django.conf 已经准备好,在源码根目录
    33. sh 'sudo cp /opt/HelloWorld/django.conf /etc/supervisor/conf.d/django.conf'
    34. sh 'sudo supervisorctl reread'
    35. sh 'sudo supervisorctl update'
    36. }
    37. }
    38. stage('Restart Application') {
    39. steps {
    40. sh 'sudo supervisorctl restart django'
    41. }
    42. }
    43. }
    44. post {
    45. always {
    46. // 清理工作,可选
    47. echo 'Build completed.'
    48. }
    49. }
    50. }

    3、示例代码详解

    上面 Jenkins Pipeline 脚本的详细解析:

    声明和代理

    • pipeline: 声明这是一个 Jenkins Pipeline 脚本。
    • agent any: 指定 Pipeline 可以在任何可用的 Jenkins Agent 上运行。

    阶段定义

    • Pipeline 包含五个阶段:Checkout、Stop Application、Prepare Deployment、Configure Supervisor 和 Restart Application。

    Checkout 阶段

    • 使用 Git 插件从指定的 Git 仓库克隆代码到 Jenkins 工作空间。
    • branch: 指定要克隆的分支名称。
    • credentialsId: 指定用于访问 Git 仓库的凭证 ID。
    • url: 指定 Git 仓库的 URL。

    Stop Application 阶段

    • 使用 script 块执行 Groovy 代码:
      • serviceStatus: 运行 supervisorctl status django 命令检查 Django 服务状态,并使用 || true 忽略可能的错误。
      • 如果 serviceStatus 包含 "RUNNING",则使用 supervisorctl stop django 命令停止 Django 服务。
      • 否则,输出信息表示 Django 进程未运行或不存在。

     Prepare Deployment 阶段

    • 使用 sh 步骤执行 shell 命令:
      • sudo rm -rf /opt/HelloWorld/*: 删除 /opt/HelloWorld/ 目录中的所有文件。
      • sudo cp -R . /opt/HelloWorld: 将 Jenkins 工作空间中的所有文件复制到 /opt/HelloWorld/ 目录。

    Configure Supervisor 阶段

    • 使用 sh 步骤执行 shell 命令:
      • sudo cp /opt/HelloWorld/django.conf /etc/supervisor/conf.d/django.conf: 将 django.conf 文件复制到 supervisord 配置目录。
      • sudo supervisorctl reread: 重新读取 supervisord 配置文件。
      • sudo supervisorctl update: 更新 supervisord 进程。

    Restart Application 阶段

    • 使用 sh 步骤执行 shell 命令:
      • sudo supervisorctl restart django: 重启 django 进程。

    后处理 (Post)

    • always: 无论 Pipeline 执行成功或失败,都会执行此块中的步骤。
    • echo 'Build completed.': 输出信息表示构建已完成。

    这个 Jenkins Pipeline 脚本实现了以下功能:

    • 从 Git 仓库克隆代码。
    • 停止正在运行的 Django 服务。
    • 将新代码部署到 /opt/HelloWorld/ 目录。
    • 配置 supervisord 以管理 Django 进程。
    • 重启 Django 服务。

    请根据您的实际环境和需求调整脚本,例如文件路径、Git 仓库 URL、凭证 ID 和 supervisord 配置。

    4、执行任务,并看结果

     执行这个修改保存后的jenkins任务,我们看到任务执行成功了。

    然后在浏览器访问一下这个页面,http://192.168.110.170:8081/hello/就能看到我们想要的页面了。

  • 相关阅读:
    【Android知识笔记】插件化专题(二)
    多视图聚类的论文阅读(一)
    从压测碰到的诡异断连问题聊聊Nginx的连接管理
    【数据结构】二叉树OJ练习
    本地开发环境大小写不敏感引发的问题
    MySQL-锁机制
    IDEA配置Maven
    管理学精要
    HTTParty库数据抓取代码示例
    基于事件驱动的微服务教程
  • 原文地址:https://blog.csdn.net/benshu_001/article/details/138142369