Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

supervisor & gunicorn #18

Open
unaheidi opened this issue Jun 8, 2021 · 4 comments
Open

supervisor & gunicorn #18

unaheidi opened this issue Jun 8, 2021 · 4 comments

Comments

@unaheidi
Copy link
Owner

unaheidi commented Jun 8, 2021

背景

AI 团队有个应用,需要手工安装部分组件,其次,除了 python 运行环境还需要 Java 运行环境,因此,CI/CD 的时候,这个应用不能直接基于公司统一的 python 基础镜像来创建部署镜像,得自己团队手工把镜像 push 到 hub 来部署实例。
用我们公共发布系统部署实例的时候,实例总是点火失败,应用的 owner 向我们寻求帮助。

哪些因素影响排障效率

  1. 用户和支持人员是否熟悉部署环境
  2. 支持人员和用户关注点是否相同

用户和我对 Python 的部署环境,只知道皮毛。
我的关注点一直在:用户是自定义镜像,他自制的镜像是否遵守公司 python 部署规范呢?
用户一开始关注 Java 环境,这一点被我忽略掉了。事后发现后面引入的问题和用户准备这个 Java 环境有直接关系。

问题解决过程

  1. 用户先报 ”ModuleNotFound: no module name ...“ 的错误
    这个应该是用户选择了没有安装组件的某个 python 版本导致的。当我搭建测试环境帮用户查找问题的时候,我发现并没有这个问题。估计用户自己搞定了。
  2. 有编码类型的报错
    image
    这个用户一看是编码的问题,把文件里面的中文改为英文后,不再报错。
  3. 用户看了 gunicorn.log 告诉我 ”进程一直在重启“,web 服务没有启动
    image
    我上网查了,告诉用户,可以加个 --preload ,会有 gunicorn 详细报错。
    /opt/app/.venv/bin/python3 /opt/app/.venv/bin/gunicorn -c /etc/gunicorn.conf.py --preload wsgi:application
    image
  4. 上述编码问题搞定后,用户的 web 服务是能正常运行的。
  5. 遗留一个问题:实例重启后,用户要的 web 服务进程根本没启动。
  6. 先检查了用户容器的部署文件是否符合公司部署要求。
    用户的构建目录和文件、以及 wsgi.py 内 wsgi 接口实例以及按要求命名为 application。
  7. 知识点补漏。
    在这个时候,逼着我把和 web 服务运行相关的一些东西搞搞清楚。
  • 用户的 web 服务是没启动,但是,supervisor 这个进程一直都在。
    root 12 1 0 Jun07 ? 00:00:14 /usr/bin/python /usr/bin/supervisord -c /etc/supervisord.conf
  • 正常的话,supervisor 这个进程会调用 python 的 web 进程。
    为何总是没有 python 的进程呢?并且 gunicorn.log 没有内容。估计,实例启动后,gunicorn 就没在工作。
  • 是否该查一下 supervisor 的运行日志呢?
    真实好主意,我感觉解决问题的思路越来越清晰了。
    find / -name supervisor.log
    image
  • Root Cause 终于出来了
    用户为了设置 Java 运行环境,修改了 /etc/profile 文件,并且在 /etc/supervisord.d/gunicorn.ini 文件中增加了下面的内容:
    command=source /etc/profile && /opt/app/.venv/bin/gunicorn -c /etc/gunicorn.conf.py wsgi:application
    这就是 supervisor.log 报错的原因了。
@unaheidi unaheidi changed the title 搞定 supervisor + gunicorn 容器部署问题 搞定 supervisor & gunicorn 容器部署问题 Jun 8, 2021
@unaheidi unaheidi changed the title 搞定 supervisor & gunicorn 容器部署问题 supervisor & gunicorn Jun 8, 2021
@unaheidi
Copy link
Owner Author

unaheidi commented Jun 8, 2021

本案例的排查过程,为什么给人倒着走的感觉?如果一上来就看 supervisor.log , 问题不就很快就能定位了吗?
🤣 思考了一下,原因如下:

  1. 不知道 supervisor 确切的作用。
    是在查问题的过程中,发现这个 supervisor 一直都在,标准 python 应用也有这个进程。才知道应该从这个 supervisor 开始查。
  2. 用户是自定义的镜像,让人很想查看一下他定义的镜像是否符合公司部署规范。

@unaheidi
Copy link
Owner Author

unaheidi commented Jun 8, 2021

😆 这里还有一个很好的问题:为什么公司部署规范中,要求 ”wsgi.py 内 wsgi 接口实例以及按要求命名为 application“ 呢?
😃 其实这个就是公司 python 部署的约定,用相同的配置文件启动 web 服务罢了。看一下 /etc/supervisord.d/gunicorn.ini 文件就能发现这个小密码了。

@unaheidi
Copy link
Owner Author

unaheidi commented Jun 11, 2021

supervisord 进程的日志究竟吐到哪里去了?
这个问题可以抽象为:linux 系统上某个进程,日志吐到哪里怎么查看呢?
lsof -p 进程id | grep .log

为啥返回是 /tensorflow-serving/supervisord.log 这么个怪的路径 ?

@unaheidi
Copy link
Owner Author

今天,在帮用户搞定多语言运行环境的过程中,我自己验证了 ~/.bashrc 和 ~/.bash_profile 的区别。
容器中把 java 执行路径等环境配置项分别写在 /home/user/.bashrc 和 /home/user/.bash_profile 这两个文件,然后创建镜像A镜像B
基于镜像A创建的容器,通过公司堡垒机用管理员账号登录后,切换到 user,发现 java 可用。
基于镜像B创建的容器,通过公司堡垒机用管理员账号登录后,切换到 user,发现 java 不可用。

看来,在公司这种环境下,适合把环境变量配置到 /home/user/.bashrc 这个文件中。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant