• 项目部署上线指南
    • 准备上线
    • 更新服务器Python环境到3.x
    • 项目目录结构
    • uWSGI的配置
    • Nginx的配置
      • 负载均衡配置
    • Keepalived
    • MySQL主从复制
    • Docker
    • Supervisor
    • 其他服务

    项目部署上线指南

    准备上线

    1. 上线前的检查工作。

      1. python manage.py check --deploy
    2. 将DEBUG设置为False并配置ALLOWED_HOSTS。

      1. DEBUG = False
      2. ALLOWED_HOSTS = ['*']
    3. 安全相关的配置。

      1. # 保持HTTPS连接的时间
      2. SECURE_HSTS_SECONDS = 3600
      3. SECURE_HSTS_INCLUDE_SUBDOMAINS = True
      4. SECURE_HSTS_PRELOAD = True
      5. # 自动重定向到安全连接
      6. SECURE_SSL_REDIRECT = True
      7. # 避免浏览器自作聪明推断内容类型
      8. SECURE_CONTENT_TYPE_NOSNIFF = True
      9. # 避免跨站脚本攻击
      10. SECURE_BROWSER_XSS_FILTER = True
      11. # COOKIE只能通过HTTPS进行传输
      12. SESSION_COOKIE_SECURE = True
      13. CSRF_COOKIE_SECURE = True
      14. # 防止点击劫持攻击手段 - 修改HTTP协议响应头
      15. # 当前网站是不允许使用<iframe>标签进行加载的
      16. X_FRAME_OPTIONS = 'DENY'
    4. 敏感信息放到环境变量或文件中。

      1. SECRET_KEY = os.environ['SECRET_KEY']
      2. DB_USER = os.environ['DB_USER']
      3. DB_PASS = os.environ['DB_PASS']
      4. REDIS_AUTH = os.environ['REDIS_AUTH']

    更新服务器Python环境到3.x

    说明:如果需要清除之前的安装,就删除对应的文件和文件夹即可

    1. 安装底层依赖库。

      1. yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel libdb4-devel libpcap-devel xz-devel libffi-devel
    2. 下载Python源代码。

      1. wget https://www.python.org/ftp/python/3.7.1/Python-3.7.1.tar.xz
    3. 解压缩和解归档。

      1. xz -d Python-3.7.1.tar.xz
      2. tar -xvf Python-3.7.1.tar
    4. 执行配置生成Makefile(构建文件)。

      1. cd Python-3.7.1
      2. ./configure --prefix=/usr/local/python37 --enable-optimizations
    5. 构建和安装。

      1. make && make install
    6. 配置PATH环境变量(用户或系统环境变量)并激活。

      1. vim ~/.bash_profile
      2. vim /etc/profile
      1. ... 此处省略上面的代码...
      2. export PATH=$PATH:/usr/local/python37/bin
      3. ... 此处省略下面的代码...
      1. source ~/.bash_profile
      2. source /etc/profile
    7. 注册软链接(符号链接)- 这一步不是必须的,但通常会比较有用。

      1. ln -s /usr/local/python37/bin/python3 /usr/bin/python3
    8. 测试Python环境是否更新成功(安装Python 3一定不能破坏原来的Python 2)。

      1. python3 --version
      2. python --version

    项目目录结构

    假设项目文件夹为project,下面的五个子目录分别是:codeconflogsstatvenv分别用来保存项目的代码、配置文件、日志文件、静态资源和虚拟环境。其中,conf目录下的子目录cert中保存了配置HTTPS需要使用的证书和密钥;code目录下的项目代码可以通过版本控制工具从代码仓库中检出;虚拟环境可以通过工具(如:venv、virtualenv、pyenv等)进行创建。

    1. project
    2. ├── code
    3. └── fangtx
    4. ├── api
    5. ├── common
    6. ├── fangtx
    7. ├── forum
    8. ├── rent
    9. ├── user
    10. ├── manage.py
    11. ├── README.md
    12. ├── static
    13. └── templates
    14. ├── conf
    15. ├── cert
    16. ├── 214915882850706.key
    17. └── 214915882850706.pem
    18. ├── nginx.conf
    19. └── uwsgi.ini
    20. ├── logs
    21. ├── access.log
    22. ├── error.log
    23. └── uwsgi.log
    24. ├── stat
    25. └── css
    26. └── images
    27. └── js
    28. └── venv
    29. ├── bin
    30. ├── activate
    31. ├── activate.csh
    32. ├── activate.fish
    33. ├── celery
    34. ├── celerybeat
    35. ├── celeryd
    36. ├── celeryd-multi
    37. ├── coverage
    38. ├── coverage3
    39. ├── coverage-3.7
    40. ├── django-admin
    41. ├── django-admin.py
    42. ├── easy_install
    43. ├── easy_install-3.7
    44. ├── pip
    45. ├── pip3
    46. ├── pip3.7
    47. ├── __pycache__
    48. ├── pyrsa-decrypt
    49. ├── pyrsa-decrypt-bigfile
    50. ├── pyrsa-encrypt
    51. ├── pyrsa-encrypt-bigfile
    52. ├── pyrsa-keygen
    53. ├── pyrsa-priv2pub
    54. ├── pyrsa-sign
    55. ├── pyrsa-verify
    56. ├── python -> python3
    57. ├── python3 -> /usr/bin/python3
    58. └── uwsgi
    59. ├── include
    60. ├── lib
    61. └── python3.7
    62. ├── lib64 -> lib
    63. ├── pip-selfcheck.json
    64. └── pyvenv.cfg

    下面以阿里云为例,简单说明如何为项目注册域名、解析域名以及购买权威机构颁发的证书。

    1. 注册域名。

      第98天 项目部署上线和性能调优 - 图1

    2. 域名备案。

      第98天 项目部署上线和性能调优 - 图2

    3. 域名解析。

      第98天 项目部署上线和性能调优 - 图3

      第98天 项目部署上线和性能调优 - 图4

    4. 购买证书。

      第98天 项目部署上线和性能调优 - 图5

    可以使用类似于sftp的工具将证书上传到conf/cert目录,然后使用git克隆项目代码到code目录。

    1. cd code
    2. git clone <url>

    回到项目目录,创建并激活虚拟环境。

    1. python3 -m venv venv
    2. source venv/bin/activate

    重建项目依赖项。

    1. pip install -r code/teamproject/requirements.txt

    uWSGI的配置

    1. 安装uWSGI。

      1. pip install uwsgi
    2. 修改uWSGI的配置文件(/root/project/conf/uwsgi.ini)。

      1. [uwsgi]
      2. # 配置前导路径
      3. base=/root/project
      4. # 配置项目名称
      5. name=teamproject
      6. # 守护进程
      7. master=true
      8. # 进程个数
      9. processes=4
      10. # 虚拟环境
      11. pythonhome=%(base)/venv
      12. # 项目地址
      13. chdir=%(base)/code/%(name)
      14. # 指定python解释器
      15. pythonpath=%(pythonhome)/bin/python
      16. # 指定uwsgi文件
      17. module=%(name).wsgi
      18. # 通信的地址和端口(自己服务器的IP地址和端口)
      19. socket=172.18.61.250:8000
      20. # 日志文件地址
      21. logto=%(base)/logs/uwsgi.log

      说明:可以先将“通信的地址和端口”项等号前面改为http来进行测试,如果没有问题再改回 成socket,然后通过Nginx来实现项目的“动静分离”(静态资源交给Nginx处理,动态内容交给 uWSGI处理)。按照下面的方式可以启动uWSGI服务器。

    3. 启动服务器。

      1. uwsgi --ini conf/uwsgi.ini

    Nginx的配置

    1. 安装Nginx。

      1. yum -y install nginx
    2. 修改全局配置文件(/etc/nginx/nginx.conf)。

      1. # 配置用户
      2. user root;
      3. # 工作进程数(建议跟CPU的核数量一致)
      4. worker_processes auto;
      5. # 错误日志
      6. error_log /var/log/nginx/error.log;
      7. # 进程文件
      8. pid /run/nginx.pid;
      9. # 包含其他的配置
      10. include /usr/share/nginx/modules/*.conf;
      11. # 工作模式(多路IO复用方式)和连接上限
      12. events {
      13. use epoll;
      14. worker_connections 1024;
      15. }
      16. # HTTP服务器相关配置
      17. http {
      18. # 日志格式
      19. log_format main '$remote_addr - $remote_user [$time_local] "$request" '
      20. '$status $body_bytes_sent "$http_referer" '
      21. '"$http_user_agent" "$http_x_forwarded_for"';
      22. # 访问日志
      23. access_log /var/log/nginx/access.log main;
      24. # 开启高效文件传输模式
      25. sendfile on;
      26. # 用sendfile传输文件时有利于改善性能
      27. tcp_nopush on;
      28. # 禁用Nagle来解决交互性问题
      29. tcp_nodelay on;
      30. # 客户端保持连接时间
      31. keepalive_timeout 30;
      32. types_hash_max_size 2048;
      33. # 包含MIME类型的配置
      34. include /etc/nginx/mime.types;
      35. # 默认使用二进制流格式
      36. default_type application/octet-stream;
      37. # 包含其他配置文件
      38. include /etc/nginx/conf.d/*.conf;
      39. # 包含项目的Nginx配置文件
      40. include /root/project/conf/*.conf;
      41. }
    3. 编辑局部配置文件(/root/project/conf/nginx.conf)。

      1. server {
      2. listen 80;
      3. server_name _;
      4. access_log /root/project/logs/access.log;
      5. error_log /root/project/logs/error.log;
      6. location / {
      7. include uwsgi_params;
      8. uwsgi_pass 172.18.61.250:8000;
      9. }
      10. location /static/ {
      11. alias /root/project/stat/;
      12. expires 30d;
      13. }
      14. }
      15. server {
      16. listen 443;
      17. server_name _;
      18. ssl on;
      19. access_log /root/project/logs/access.log;
      20. error_log /root/project/logs/error.log;
      21. ssl_certificate /root/project/conf/cert/214915882850706.pem;
      22. ssl_certificate_key /root/project/conf/cert/214915882850706.key;
      23. ssl_session_timeout 5m;
      24. ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
      25. ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
      26. ssl_prefer_server_ciphers on;
      27. location / {
      28. include uwsgi_params;
      29. uwsgi_pass 172.18.61.250:8000;
      30. }
      31. location /static/ {
      32. alias /root/project/static/;
      33. expires 30d;
      34. }
      35. }

      到此为止,我们可以启动Nginx来访问我们的应用程序,HTTP和HTTPS都是没有问题的,如果Nginx已经运行,在修改配置文件后,我们可以用下面的命令重新启动Nginx。

    4. 重启Nginx服务器。

      1. nginx -s reload

      1. systemctl restart nginx

    说明:可以对Django项目使用python manage.py collectstatic命令将静态资源收集到指定目录下,要做到这点只需要在项目的配置文件settings.py中添加STATIC_ROOT配置即可。

    负载均衡配置

    下面的配置中我们使用Nginx实现负载均衡,为另外的三个Nginx服务器(通过Docker创建)提供反向代理服务。

    1. docker run -d -p 801:80 --name nginx1 nginx:latest
    2. docker run -d -p 802:80 --name nginx2 nginx:latest
    3. docker run -d -p 803:80 --name nginx3 nginx:latest
    1. user root;
    2. worker_processes auto;
    3. error_log /var/log/nginx/error.log;
    4. pid /run/nginx.pid;
    5. include /usr/share/nginx/modules/*.conf;
    6. events {
    7. worker_connections 1024;
    8. }
    9. # 为HTTP服务配置负载均衡
    10. http {
    11. upstream fangtx {
    12. server 172.18.61.250:801 weight=4;
    13. server 172.18.61.250:802 weight=2;
    14. server 172.18.61.250:803 weight=2;
    15. }
    16. server {
    17. listen 80 default_server;
    18. listen [::]:80 default_server;
    19. listen 443 ssl;
    20. listen [::]:443 ssl;
    21. ssl on;
    22. access_log /root/project/logs/access.log;
    23. error_log /root/project/logs/error.log;
    24. ssl_certificate /root/project/conf/cert/214915882850706.pem;
    25. ssl_certificate_key /root/project/conf/cert/214915882850706.key;
    26. ssl_session_timeout 5m;
    27. ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    28. ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    29. ssl_prefer_server_ciphers on;
    30. location / {
    31. proxy_set_header Host $host;
    32. proxy_set_header X-Real-IP $remote_addr;
    33. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    34. proxy_buffering off;
    35. proxy_pass http://fangtx;
    36. }
    37. }
    38. }

    说明:Nginx在配置负载均衡时,默认使用WRR(加权轮询算法),除此之外还支持ip_hash、fair(需要安装upstream_fair模块)和url_hash算法。此外,在配置upstream模块时可以指定服务器的状态值,包括:backup(备份机器,其他服务器不可用时才将请求分配到该机器)、down、fail_timeout(请求失败达到max_fails后的暂停服务时间)、max_fails(允许请求失败的次数)和weight(轮询的权重)。

    Keepalived

    当使用Nginx进行负载均衡配置时,要考虑负载均衡服务器宕机的情况。为此可以使用Keepalived来实现负载均衡主机和备机的热切换,从而保证系统的高可用性。Keepalived的配置还是比较复杂,通常由专门做运维的人进行配置,一个基本的配置可以参照《Keepalived的配置和使用》。

    MySQL主从复制

    下面还是基于Docker来演示如何配置MySQL主从复制。我们事先准备好MySQL的配置文件以及保存MySQL数据和运行日志的目录,然后通过Docker的数据卷映射来指定容器的配置、数据和日志文件的位置。

    1. root
    2. └── mysql
    3. ├── master
    4. ├── conf
    5. | └── data
    6. └── slave-1
    7. | ├── conf
    8. | └── data
    9. └── slave-2
    10. | ├── conf
    11. | └── data
    12. └── slave-3
    13. ├── conf
    14. └── data
    1. MySQL的配置文件(master和slave的配置文件需要不同的server-id)。

      1. [mysqld]
      2. pid-file=/var/run/mysqld/mysqld.pid
      3. socket=/var/run/mysqld/mysqld.sock
      4. datadir=/var/lib/mysql
      5. log-error=/var/log/mysql/error.log
      6. server-id=1
      7. log-bin=/var/log/mysql/mysql-bin.log
      8. expire_logs_days=30
      9. max_binlog_size=256M
      10. symbolic-links=0
      11. # slow_query_log=ON
      12. # slow_query_log_file=/var/log/mysql/slow.log
      13. # long_query_time=1
    2. 创建和配置master。

      1. docker run -d -p 3306:3306 --name mysql-master \
      2. -v /root/mysql/master/conf:/etc/mysql/mysql.conf.d \
      3. -v /root/mysql/master/data:/var/lib/mysql \
      4. -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
      5. docker exec -it mysql-master /bin/bash
      1. mysql -u root -p
      2. Enter password:
      3. Welcome to the MySQL monitor. Commands end with ; or \g.
      4. Your MySQL connection id is 1
      5. Server version: 5.7.23-log MySQL Community Server (GPL)
      6. Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
      7. Oracle is a registered trademark of Oracle Corporation and/or its
      8. affiliates. Other names may be trademarks of their respective
      9. owners.
      10. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
      11. mysql> grant replication slave on *.* to 'slave'@'%' identified by 'iamslave';
      12. Query OK, 0 rows affected, 1 warning (0.00 sec)
      13. mysql> flush privileges;
      14. Query OK, 0 rows affected (0.00 sec)
      15. mysql> show master status;
      16. +------------------+----------+--------------+------------------+-------------------+
      17. | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
      18. +------------------+----------+--------------+------------------+-------------------+
      19. | mysql-bin.000003 | 590 | | | |
      20. +------------------+----------+--------------+------------------+-------------------+
      21. 1 row in set (0.00 sec)
      22. mysql> quit
      23. Bye
      24. exit

      上面创建Docker容器时使用的-v参数(--volume)表示映射数据卷,冒号前是宿主机的目录,冒号后是容器中的目录,这样相当于将宿主机中的目录挂载到了容器中。

    3. 创建和配置slave。

      1. docker run -d -p 3308:3306 --name mysql-slave-1 \
      2. -v /root/mysql/slave-1/conf:/etc/mysql/mysql.conf.d \
      3. -v /root/mysql/slave-1/data:/var/lib/mysql \
      4. -e MYSQL_ROOT_PASSWORD=123456 \
      5. --link mysql-master:mysql-master mysql:5.7
      6. docker run -d -p 3309:3306 --name mysql-slave-2 \
      7. -v /root/mysql/slave-2/conf:/etc/mysql/mysql.conf.d \
      8. -v /root/mysql/slave-2/data:/var/lib/mysql \
      9. -e MYSQL_ROOT_PASSWORD=123456 \
      10. --link mysql-master:mysql-master mysql:5.7
      11. docker run -d -p 3310:3306 --name mysql-slave-3 \
      12. -v /root/mysql/slave-3/conf:/etc/mysql/mysql.conf.d \
      13. -v /root/mysql/slave-3/data:/var/lib/mysql \
      14. -e MYSQL_ROOT_PASSWORD=123456 \
      15. --link mysql-master:mysql-master mysql:5.7
      16. docker exec -it mysql-slave-1 /bin/bash
      1. mysql -u root -p
      2. Enter password:
      3. Welcome to the MySQL monitor. Commands end with ; or \g.
      4. Your MySQL connection id is 2
      5. Server version: 5.7.23-log MySQL Community Server (GPL)
      6. Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
      7. Oracle is a registered trademark of Oracle Corporation and/or its
      8. affiliates. Other names may be trademarks of their respective
      9. owners.
      10. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
      11. mysql> reset slave;
      12. Query OK, 0 rows affected (0.02 sec)
      13. mysql> change master to master_host='mysql-master', master_user='slave', master_password='iamslave', master_log_file='mysql-bin.000003', master_log_pos=590;
      14. Query OK, 0 rows affected, 2 warnings (0.03 sec)
      15. mysql> start slave;
      16. Query OK, 0 rows affected (0.01 sec)
      17. mysql> show slave status\G
      18. *************************** 1. row ***************************
      19. Slave_IO_State: Waiting for master to send event
      20. Master_Host: mysql57
      21. Master_User: slave
      22. Master_Port: 3306
      23. Connect_Retry: 60
      24. Master_Log_File: mysql-bin.000001
      25. Read_Master_Log_Pos: 590
      26. Relay_Log_File: f352f05eb9d0-relay-bin.000002
      27. Relay_Log_Pos: 320
      28. Relay_Master_Log_File: mysql-bin.000001
      29. Slave_IO_Running: Yes
      30. Slave_SQL_Running: Yes
      31. Replicate_Do_DB:
      32. Replicate_Ignore_DB:
      33. Replicate_Do_Table:
      34. Replicate_Ignore_Table:
      35. Replicate_Wild_Do_Table:
      36. Replicate_Wild_Ignore_Table:
      37. Last_Errno: 0
      38. Last_Error:
      39. Skip_Counter: 0
      40. Exec_Master_Log_Pos: 590
      41. Relay_Log_Space: 534
      42. Until_Condition: None
      43. Until_Log_File:
      44. Until_Log_Pos: 0
      45. Master_SSL_Allowed: No
      46. Master_SSL_CA_File:
      47. Master_SSL_CA_Path:
      48. Master_SSL_Cert:
      49. Master_SSL_Cipher:
      50. Master_SSL_Key:
      51. Seconds_Behind_Master: 0
      52. Master_SSL_Verify_Server_Cert: No
      53. Last_IO_Errno: 0
      54. Last_IO_Error:
      55. Last_SQL_Errno: 0
      56. Last_SQL_Error:
      57. Replicate_Ignore_Server_Ids:
      58. Master_Server_Id: 1
      59. Master_UUID: 30c38043-ada1-11e8-8fa1-0242ac110002
      60. Master_Info_File: /var/lib/mysql/master.info
      61. SQL_Delay: 0
      62. SQL_Remaining_Delay: NULL
      63. Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
      64. Master_Retry_Count: 86400
      65. Master_Bind:
      66. Last_IO_Error_Timestamp:
      67. Last_SQL_Error_Timestamp:
      68. Master_SSL_Crl:
      69. Master_SSL_Crlpath:
      70. Retrieved_Gtid_Set:
      71. Executed_Gtid_Set:
      72. Auto_Position: 0
      73. Replicate_Rewrite_DB:
      74. Channel_Name:
      75. Master_TLS_Version:
      76. 1 row in set (0.00 sec)
      77. mysql> quit
      78. Bye
      79. exit

      接下来可以如法炮制配置出slave2和slave3,这样就可以搭建起一个“一主带三从”的主从复制环境。上面创建创建容器时使用的--link参数用来配置容器在网络上的主机名(网络地址别名)。

    配置好主从复制后,写数据的操作应该master上执行,而读数据的操作应该在slave上完成。为此,在Django项目中需要配置DATABASE_ROUTERS并通过自定义的主从复制路由类来实现读写分离操作,如下所示:

    1. DATABASE_ROUTERS = [
    2. # 此处省略其他配置
    3. 'common.routers.MasterSlaveRouter',
    4. ]
    1. class MasterSlaveRouter(object):
    2. """主从复制路由"""
    3. @staticmethod
    4. def db_for_read(model, **hints):
    5. """
    6. Attempts to read auth models go to auth_db.
    7. """
    8. return random.choice(('slave1', 'slave2', 'slave3'))
    9. @staticmethod
    10. def db_for_write(model, **hints):
    11. """
    12. Attempts to write auth models go to auth_db.
    13. """
    14. return 'default'
    15. @staticmethod
    16. def allow_relation(obj1, obj2, **hints):
    17. """
    18. Allow relations if a model in the auth app is involved.
    19. """
    20. return None
    21. @staticmethod
    22. def allow_migrate(db, app_label, model_name=None, **hints):
    23. """
    24. Make sure the auth app only appears in the 'auth_db'
    25. database.
    26. """
    27. return True

    上面的内容参考了Django官方文档的DATABASE_ROUTERS配置,对代码进行了适当的调整。

    Docker

    事实上,项目上线中最为麻烦的事情就是配置软件运行环境,环境的差异会给软件的安装和部署带来诸多的麻烦,而Docker正好可以解决这个问题。关于Docker在之前的文档中我们已经介绍过了,接下来我们对Docker的知识做一些必要的补充。

    1. 创建镜像文件。

      将容器保存成镜像:

      1. docker commit -m "..." -a "jackfrued" <container-name> jackfrued/<image-name>

      使用Dockerfile构建镜像:

      1. # 指定基础镜像文件
      2. FROM centos:latest
      3. # 指定维护者信息
      4. MAINTAINER jackfrued
      5. # 执行命令
      6. RUN yum -y install gcc
      7. RUN cd ~
      8. RUN mkdir -p project/code
      9. RUN mkdir -p project/logs
      10. # 拷贝文件
      11. COPY ...
      12. # 暴露端口
      13. EXPOSE ...
      14. # 在容器启动时执行命令
      15. CMD ~/init.sh
      1. docker build -t jackfrued/<image-name> .
    2. 镜像的导入和导出。

      1. docker save -o <file-name>.tar <image-name>:<version>
      2. docker load -i <file-name>.tar
    3. 推送到DockerHub服务器。

      1. docker tag <image-name>:<version> jackfrued/<name>
      2. docker login
      3. docker push jackfrued/<name>
    4. 容器之间的通信。

      1. docker run --link <container-name>:<alias-name>

    如果我们能够在Docker中完成项目的部署,并且将整个部署好的容器打包成镜像文件进行分发和安装,这样就可以解决项目在多个节点上进行部署时可能遇到的麻烦,而且整个部署可以在很短的时间内完成。

    Supervisor

    Supervisor是一个用Python写的进程管理工具,可以很方便的用来在类Unix系统下启动、重启(自动重启程序)和关闭进程,目前Supervisor暂时还没有提供对Python 3的支持,可以通过Python 2来安装和运行Supervisor,再通过Supervisor来管理Python 3的程序。

    1. 安装Supervisor。

      1. pip install virtualenv
      2. virtualenv -p /usr/bin/python venv
      3. source venv/bin/activate
      4. pip install supervisor
    2. 查看Supervisor的配置文件。

      1. vim /etc/supervisord.conf
      1. ; 此处省略上面的代码
      2. ; The [include] section can just contain the "files" setting. This
      3. ; setting can list multiple files (separated by whitespace or
      4. ; newlines). It can also contain wildcards. The filenames are
      5. ; interpreted as relative to this file. Included files *cannot*
      6. ; include files themselves.
      7. [include]
      8. files = supervisord.d/*.ini

      可以看出自定义的管理配置代码可以放在/etc/supervisord.d目录中,并且文件名以ini作为后缀即可。

    3. 编写自己的配置文件fangtx.ini并放在/etc/supervisord.d目录中。

      1. [program:project]
      2. command=uwsgi --ini /root/project/conf/uwsgi.ini
      3. stopsignal=QUIT
      4. autostart=true
      5. autorestart=true
      6. redirect_stderr=true
      7. [program:celery]
      8. ; Set full path to celery program if using virtualenv
      9. command=/root/project/venv/bin/python manage.py celery -A fangtx worker
      10. user=root
      11. numprocs=1
      12. stdout_logfile=/var/log/supervisor/celery.log
      13. stderr_logfile=/var/log/supervisor/celery_error.log
      14. autostart=true
      15. autorestart=true
      16. startsecs=10
      17. ; Need to wait for currently executing tasks to finish at shutdown.
      18. ; Increase this if you have very long running tasks.
      19. ;stopwaitsecs = 600
      20. ; When resorting to send SIGKILL to the program to terminate it
      21. ; send SIGKILL to its whole process group instead,
      22. ; taking care of its children as well.
      23. killasgroup=true
      24. ; Set Celery priority higher than default (999)
      25. ; so, if rabbitmq is supervised, it will start first.
      26. priority=1000
    4. 启动Supervisor。

      1. supervisorctl -c /etc/supervisord.conf

    其他服务

    1. 常用开源软件。

      | 功能 | 开源方案 || —————————- | ————————————- || 版本控制工具 | Git、Mercurial、SVN || 缺陷管理 | Redmine、Mantis || 负载均衡 | Nginx、LVS、HAProxy || 邮件服务 | Postfix、Sendmail || HTTP服务 | Nginx、Apache || 消息队列 | RabbitMQ、ZeroMQ、Redis || 文件系统 | FastDFS || 基于位置服务(LBS) | MongoDB、Redis || 监控服务 | Nagios、Zabbix || 关系型数据库 | MySQL、PostgreSQL || 非关系型数据库 | MongoDB、Redis、Cassandra || 搜索引擎 | ElasticSearch、Solr || 缓存服务 | Mamcached、Redis |

    2. 常用云服务。

      | 功能 | 可用的云服务 || ——————— | ———————————————————- || 团队协作工具 | Teambition、钉钉 || 代码托管平台 | Github、Gitee、CODING || 邮件服务 | SendCloud || 云存储(CDN) | 七牛、OSS、LeanCloud、Bmob、又拍云、AWS || 移动端推送 | 极光、友盟、百度 || 即时通信 | 环信、融云 || 短信服务 | 云片、极光、Luosimao、又拍云 || 第三方登录 | 友盟、ShareSDK || 网站监控和统计 | 阿里云监控、监控宝、百度云观测、小鸟云 |