虚拟开发环境


虚拟环境就是一个目录树,在这其中安装特定的python版本以及其它的包
对于不同的应用使用不同的虚拟环境,可以解决需求相冲突的情况。

使用Virtualenv

  1. pip install virtualenv
  2. virtualenv --version
  3. virtualenv -p python3 venv #虚拟环境命名为venv

此时文件夹下会创建一个venv全新的文件夹,使用时只需要激活即可:

  1. windows激活:venv\Script\activate
  2. linux激活:source venv/bin/activate
  3. 关闭:deactivate

    使用pip包管理工具

  4. 安装包:pip install 包名==版本号

  5. 显示全部安装的包:pip list
  6. 显示可升级的包:pip list —outdate
  7. 升级包:pip install —upgrade 包名 可以使用==,>=,<=,>,<将包升级到指定版本
  8. 卸载包:pip uninstall 包名

    包的路径

    python找第三方包的时候会出现问题,有时候会出现找不到包的情况,这个时候需要排除路径,一般python找包通过sys.path这个值来依次加载找寻

    1. import sys
    2. sys.path

    image.png
    如果出现包找不到,那么包所在的路径如果不存在就需要添加,有如下方法:
    1、sys.path.append() 临时添加,如果退出就失效
    2、在site-packages路径下添加一个路径配置文件,文件的扩展名为.pth,内容为要添加的路径即可
    在/usr/lib/python3.6/site-packages下添加一个path.pth文件,写入内容即可(推荐)
    3、添加环境变量PYTHONPATH,python会添加此路径下的模块在.bash_profile文件中添加如下类似行:
    export PYTHONPATH=$PYTHONPATH:/usr/local/lib/python2.7/site-packages(不推荐,这个方法添加的包一定会在路径最前面,有时候会导致原生的包无法正常时候)

    移植工具

    将一个已经开放完成的项目迁移到另一个全新的python环境时,可以将原项目中的包逐一安装的新环境中,可以使用如下的方式:

    1. 使用如下命令将已经安装好的包输出到requirements.txt文件中

pip freeze > requirements.txt
requirement.txt包含了包名以及版本号
b. 在全新的python环境下,一次安装requirements.txt文件中所有包:
pip install -r requirements.txt

使用镜像源加速

使用pip下载安装第三方包时,可以使用国内镜像来解决超时的问题

  1. 临时使用

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple beautifultable

  1. 默认使用

可以设置为配置文件,
Windows : C:\Users\Administrator\pip\pip.ini
Linux:~/.config/pip/pip.conf
[global]
index-url=https://pypi.tuna.tsinghua.edu.cn/simple
[install]
trusted-host=mirrors.aliyun.com

Docker


卸载

  1. sudo apt-get --purge remove docker-ce
  2. sudo rm -rf /var/lib/docker

安装

  1. sudo apt-get update
  2. sudo apt-get install apt-transport-https ca-certificates curl gnup g-agent soft ware-properties-common
  3. curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
  4. sudo apt-key fingerprint 0EBFCD88
  5. sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
  6. sudo apt-get install docker-ce docker-ce-cli containerd.io
  7. #指定版本
  8. apt-cache madison docker-ce
  9. sudo apt-get install docker-ce=<VERSION_STRING> docker-ce-cli=<VERSION_STRING> containerd.io

增加普通用户权限

  1. sudo usermod -aG docker <your-user>

制作docker容器

  1. sudo docker build --rm --network=host --no-cache --build-arg "username=$(whoami)" --build-arg "host_uid=$(id -u)" --build-arg "host_gid=$(id -g)" --tag "yocto:latest" <your-dockerfilepath>
  2. #容器制作成镜像
  3. docker save -o yocto.tar.gz yocto:latest
  4. #镜像还原
  5. docker load --input yocto.tar.gz

使用docker

—network=host 挂载主机网络
—privileged -v /dev:/dev 挂载主机驱动
—device=/dev/ttyUSB1 只挂载一个

  1. sudo docker run -ti --network=host -v /home/q/docker/gerrit:/home/q/workspace yocto:latest /bin/bash
  2. docker run -dit --network=host --privileged -v /dev:/dev -v /home/q/gregory.peng/gerrit/ql_auto_check:/home/quectel/version_check autocheck:v1.0 /bin/bash
  3. docker ps -a
  4. docker attach [CONTAINER_NAME or CONTAINER_ID]
  5. #使用[ctrl + D],这样会结束docker当前线程,容器结束,可以使用[ctrl + P][ctrl + Q]退出而不终止容器运行

image.png

这样可以进入上一次的docker容器里面,在这个容器里面装的东西不会被删除

  1. docker start e3979acedd61
  2. docker attach e3979acedd61

删除

  1. #删除进程
  2. docker ps -a
  3. docker rm -f e7bf15dfb241
  4. #删除容器
  5. docker images
  6. docker image rm docker d313d836f552 -f

dockerfile

  1. # Copyright 2019, Burkhard Stubert (DBA Embedded Use)
  2. # In any directory on the docker host, perform the following actions:
  3. # * Copy this Dockerfile in the directory.
  4. # * Create input and output directories: mkdir -p yocto/output yocto/input
  5. # * Build the Docker image with the following command:
  6. # docker build --no-cache --build-arg "host_uid=$(id -u)" --build-arg "host_gid=$(id -g)" \
  7. # --tag "cuteradio-image:latest" .
  8. # * Run the Docker image, which in turn runs the Yocto and which produces the Linux rootfs,
  9. # with the following command:
  10. # docker run -it --rm -v $PWD/yocto/output:/home/cuteradio/yocto/output cuteradio-image:latest
  11. # Use Ubuntu 16.04 LTS as the basis for the Docker image.
  12. FROM ubuntu:18.04
  13. COPY keyboard /etc/default/keyboard
  14. RUN echo "console-setup console-setup/codeset47 select Guess optimal character set" | debconf-set-selections && \
  15. echo "console-setup console-setup/fontface47 select Fixed" | debconf-set-selections && \
  16. echo "console-setup console-setup/fontsize-text47 select 16" | debconf-set-selections && \
  17. echo "console-setup console-setup/charmap47 select UTF-8" | debconf-set-selections && \
  18. echo "console-setup console-setup/store_defaults_in_debconf_db boolean true" | debconf-set-selections && \
  19. echo "console-setup console-setup/fontsize-fb47 select 16" | debconf-set-selections && \
  20. echo "console-setup console-setup/fontsize string 16" | debconf-set-selections
  21. # Install all the Linux packages required for Yocto builds. Note that the packages python3,
  22. # tar, locales and cpio are not listed in the official Yocto documentation. The build, however,
  23. # without them.
  24. RUN sed -i s/archive.ubuntu.com/mirrors.ustc.edu.cn/g /etc/apt/sources.list \
  25. && sed -i s/security.ubuntu.com/mirrors.ustc.edu.cn/g /etc/apt/sources.list \
  26. && apt-get update && apt-get -y install autoconf cryptsetup-bin checkpolicy squashfs-tools dos2unix \
  27. python python3 python3-pip python3-pexpect libncurses5-dev unzip locales sudo iputils-ping tar vim git \
  28. make git-core wget ssh dpkg tree bc m4 libc6-dev-i386 libswitch-perl automake cmake cpio curl minicom zip
  29. # gawk wget git-core diffstat texinfo gcc-multilib \
  30. # build-essential chrpath socat cpio \
  31. # xz-utils debianutils iputils-ping tar locales sudo gcc-4.9 gettext vim cryptsetup mtd-utils squashfs-tools \
  32. # libncurses5-dev bc m4 bear openjdk-8-jre rpm2cpio libc6-dev-i386 libxml-simple-perl libswitch-perl \
  33. # autoconf automake bsdiff chrpath cmake cpio \
  34. # diffstat flex gcovr git gperf rpm2cpio curl \
  35. # iputils-ping libbz2-dev libcurl4-gnutls-dev libncurses5-dev \
  36. # libncursesw5-dev libsdl-dev libssl-dev libtool libxml2-utils \
  37. # ninja-build python python-git python-jinja2 python-pkg-resources \
  38. # zlib1g-dev doxygen graphviz python3-crypto libfile-copy-recursive-perl device-tree-compiler \
  39. # bison subversion quilt intltool ruby fastjar zip unzip \
  40. # coreutils cvs desktop-file-utils docbook-utils fakeroot libgmp3-dev help2man libmpfr-dev libreadline6-dev \
  41. # libxml2-dev python-pysqlite2 make texi2html aptitude
  42. # vim configure
  43. # RUN pip3 install scons -i https://pypi.tuna.tsinghua.edu.cn/simple
  44. # RUN aptitude install libc6-i386 libstdc++6:i386
  45. # RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 50 && \
  46. # update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.9 40
  47. # RUN curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | bash \
  48. # && apt-get install git-lfs
  49. # By default, Ubuntu uses dash as an alias for sh. Dash does not support the source command
  50. # needed for setting up the build environment in CMD. Use bash as an alias for sh.
  51. RUN rm /bin/sh && ln -s /bin/bash /bin/sh
  52. # Set the locale to en_US.UTF-8, because the Yocto build fails without any locale set.
  53. RUN locale-gen en_US.UTF-8 && update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
  54. ENV LANG en_US.UTF-8
  55. ENV LC_ALL en_US.UTF-8
  56. # Perform the Yocto build as user yoctouser (not as root).
  57. # NOTE: The USER command does not set the environment variable HOME.
  58. ARG username=yoctouser
  59. ARG host_uid=1000
  60. ARG host_gid=1000
  61. RUN groupadd -g $host_gid $username && \
  62. useradd -G sudo -m -s /bin/bash -u $host_uid -g $host_gid $username && \
  63. echo "$username:123" | chpasswd && \
  64. echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
  65. COPY vimrc /home/$username/.vimrc
  66. #autocheck env
  67. # COPY google-chrome-stable_current_amd64.deb /home/$username/
  68. COPY allure-commandline-2.13.8.tgz /usr/local/
  69. COPY ql_crosstools.tar.gz /opt/
  70. COPY pip.conf /home/$username/.config/pip/
  71. COPY requirement.txt /home/$username/
  72. COPY QFirehose /usr/bin/
  73. COPY jdk-8u201-linux-x64.tar.gz /usr/local/
  74. RUN cd /home/$username/ && pip3 install -r requirement.txt -i https://pypi.tuna.tsinghua.edu.cn/simple \
  75. && cd /usr/local && tar -xf jdk-8u201-linux-x64.tar.gz && ln -s /usr/local/jdk1.8.0_201/bin/java /usr/bin/java \
  76. && tar -xf allure-commandline-2.13.8.tgz && ln -s /usr/local/allure-2.13.8/bin/allure /usr/bin/allure \
  77. && cd /opt && tar -xf ql_crosstools.tar.gz && chown -R $username:$username ql_crosstools /usr/bin/allure /usr/bin/QFirehose /usr/bin/java
  78. # By default, docker runs as root. However, Yocto builds should not be run as root, but as a
  79. # normal user. Hence, we switch to the newly created user cuteradio.
  80. USER $username
  81. WORKDIR /home/$username
  82. CMD /bin/bash

框架部署


框架部署的一般链路如下:
开发环境 - 图4

Gunicorn


  1. 安装,直接在虚拟环境venv下安装Gunicorn

    1. pip install gunicorn
  2. 添加参数启动服务

    1. gunicorn -w 3 -b 0.0.0.0:9100 run:app

    run:执行python文件run.py
    app:Flask app应用名称
    常用启动参数及说明

参数 说明
-c/—config=CONFIG 指定配置文件
-b/—bind=BIND 绑定运行的主机加端口
-w/—workers INT 用于处理工作进程的数量,整数默认为1
-k/—worker-class STRTING 要使用的工作模式,默认为sync异步,类型可以为:sync,eventlet,gevent,tornado,gthread,gaiohttp
—threads INT 处理请求的工作线程数,使用指定数量的线程去运行每个worker,默认为1
—worker-connections INT 最大客户端并发数量,默认为1000
—backlog INT 等待连接的最大数,默认为2048
-p/—pid FILE 设置pid文件的文件名,不设置不会创建pid文件
—access-logfile FILE 日志文件路径
—access-log_format STRING 日志格式,—access-log_format’%(h)s%(l)s%(u)s%(t)s’
—error-logfile FILE,—log-file FILE 错误日志文件路径
—log-level LEVEL 日志输出等级
—limit-request-line INT 限制HTTP请求行的允许大小,默认为4096,取值范围0-8190,可以防止任何DDOS攻击
—limit-request-fields INT 限制HTTP请求头字段的数量,默认100,最大值为32768
—limit-request-field-size INT 限制HTTP请求中头的大小,默认为8190,该值为0时表示不对请求头大小做限制
-t/—timeout INT 设置超时,超过后工作将被杀掉并重新启动,默认为30s,Nginx为60s
—reload 在代码改变时自动重启,默认为False
—daemon 是否以守护进程启动,默认为False
—chdir 在加载应用程序之前切换目录
—graceful-timeout INT 默认30,超时(从接收到重启信号开始)之后仍活在的工作将被强行杀死,一般采用默认值
—keep-alive INT 在keep-alive连接上等待请求的描述,默认为2s,一般设定为1~5s
—spew 打印服务器执行过的每一条语句,默认为False
—check-config 显示当前配置,默认为False,即不显示
-e/—env ENV 设置环境变量
  1. 加载配置文件启动服务

如果Gunicorn时加载的参数很多,那么第一种方式就不适用了,此时使用配置文件的方式来启动Gunicorn

  1. mkdir /var/www/html/flask_test/gunicorn
  2. vi /var/www/html/flask_test/gunicorn/gunicorn_conf.py
  1. import logging
  2. import os
  3. import multiprocessing
  4. BASE_DIR = os.path.abspath(os.path.dirname(__file__))
  5. port = [自行设定端口]
  6. bind = f'0.0.0.0:{port}'
  7. backlog = 512
  8. chdir = BASE_DIR
  9. timeout = 30
  10. daemon = 'false'
  11. worker_connections = 2000
  12. loglevel = 'warning'
  13. threads = 2
  14. workers = multiprocessing.cpu_count()
  15. access_log_format = '%(t)s %(p)s %(h)s "%(r)s" %(s)s %(L)s %(b)s %(f)s" "%(a)s"'
  16. accesslog = os.path.join(BASE_DIR, "log/gunicorn_access.log")
  17. errorlog = os.path.join(BASE_DIR, "log/gunicorn_error.log")
  1. gunicorn -c gunicorn/gunicorn_conf.py run:app

Nginx


nginx是轻量级的web服务器和反向代理服务器,占用内存小,启动极快,高并发能力强
Nginx在做反向代理时,提供性能稳定,并且能够提供配置灵活的转发功能。Nginx可以根据不同的正则匹配,采取不同的转发策略,比如图片文件结尾的走文件服务器,动态页面走web服务器,只要你正则写的没问题,又有相对应的服务器解决方案,你就可以随心所欲的玩。并且Nginx对返回结果进行错误页跳转,异常判断等。如果被分发的服务器存在异常,他可以将请求重新转发给另外一台服务器,然后自动去除异常服务器

  1. nginx -V

nginx version: nginx/1.10.3 (Ubuntu)
built with OpenSSL 1.0.2g 1 Mar 2016
TLS SNI support enabled
configure arguments: —with-cc-opt=’-g -O2 -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2’ —with-ld-opt=’-Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now’ —prefix=/usr/share/nginx —conf-path=/etc/nginx/nginx.conf —http-log-path=/var/log/nginx/access.log —error-log-path=/var/log/nginx/error.log —lock-path=/var/lock/nginx.lock —pid-path=/run/nginx.pid —http-client-body-temp-path=/var/lib/nginx/body —http-fastcgi-temp-path=/var/lib/nginx/fastcgi —http-proxy-temp-path=/var/lib/nginx/proxy —http-scgi-temp-path=/var/lib/nginx/scgi —http-uwsgi-temp-path=/var/lib/nginx/uwsgi —with-debug —with-pcre-jit —with-ipv6 —with-http_ssl_module —with-http_stub_status_module —with-http_realip_module —with-http_auth_request_module —with-http_addition_module —with-http_dav_module —with-http_geoip_module —with-http_gunzip_module —with-http_gzip_static_module —with-http_image_filter_module —with-http_v2_module —with-http_sub_module —with-http_xslt_module —with-stream —with-stream_ssl_module —with-mail —with-mail_ssl_module —with-threads
其中可以看到 —prefix=/etc/nginx,nginx 安装时会把相关数据文件写入到该目录,如我们的配置文件 —conf-path。
每次更改 nginx 的配置文件,你需要执行一下操作:

  1. #验证配置文件的正确性
  2. nginx -T
  3. #重新加载配置文件
  4. nginx -s reload

安装完 nginx ,我们先来看一看 nginx 的默认配置 /etc/nginx/nginx.conf,当然可能与你的默认配置不同,不过大同小异:

  1. # worker以什么身份运行
  2. user nginx; // default nobody
  3. # worker进程个数,一般为 CPU 个数,也可选 auto
  4. worker_processes 1; # default 1
  5. # 每个worker可打开的描述符限制
  6. worker_rlimit_nofile 8192;
  7. # 错误日志保存路径和级别
  8. error_log /var/log/nginx/error.log warn;
  9. # 进程pid保存路径
  10. pid /var/run/nginx.pid;
  11. # 指定dns服务器
  12. resolver 10.0.0.1;
  13. events {
  14. # 每个worker最大连接数
  15. worker_connections 1024; # default 1024
  16. }
  17. # http 服务定义
  18. http {
  19. # 加载 mime 类型
  20. include /etc/nginx/mime.types;
  21. # 定义默认数据类型
  22. default_type application/octet-stream;
  23. # 日志格式
  24. log_format main '$remote_addr - $remote_user [$time_local] "$request" '
  25. '$status $body_bytes_sent "$http_referer"'
  26. '"$http_user_agent" "$http_x_forwarded_for"';
  27. # 访问日志
  28. access_log /var/log/nginx/access.log main;
  29. # 是否调用sendfile函数(zero copy 方式)来输出文件,如果磁盘IO重负载应用,可设置为off
  30. sendfile on;
  31. # 此选项允许或禁止使用socke的TCP_CORK的选项,此选项仅在使用sendfile的时候使用
  32. #tcp_nopush on;
  33. keepalive_timeout 65;
  34. # 代理相关设置
  35. # proxy_connect_timeout 90;
  36. # proxy_read_timeout 180;
  37. # proxy_send_timeout 180;
  38. # proxy_buffer_size 256k;
  39. # proxy_buffers 4 256k;
  40. # proxy_busy_buffers_size 256k;
  41. # proxy_temp_file_write_size 256k;
  42. # tcp_nodelay on;
  43. # gzip 压缩
  44. #gzip on;
  45. # 加载其它配置,这样我们在 conf.d 下写的文件才会生效
  46. include /etc/nginx/conf.d/*.conf;
  47. include /etc/nginx/sites-enabled/*;
  48. }

内置变量

内置变量,nginx 各个模块都将请求的一些参数进行变量化,通过 $ + 变量名 即可使用。每个模块或多或少都有自己的变量。着重介绍下核心模块的 内置变量

  1. # 通过arg_<name>的方式可取出相关参数,若请求 /foo?name=Tony&age=2,则 arg_name=tony arg_age=2
  2. $arg_name
  3. $args
  4. # 客户端IP地址二进制
  5. $binary_remote_addr
  6. # 发送到客户端的字节数,不包括响应头
  7. $body_bytes_sent
  8. # 发送给客户端字节数
  9. $bytes_sent
  10. # 连接序列号
  11. $connection
  12. # 当前已经连接的请求书
  13. $connection_requests
  14. # Content-Length 请求头
  15. $content_length
  16. # Content-Type 请求头
  17. $content_type
  18. # cookie 名称
  19. $cookie_name
  20. # 当前请求的 root 或 alias 的值
  21. $document_root
  22. # 与 $uri 相同
  23. $document_uri
  24. # 优先级:请求行中的 host name,请求头中的 Host,请求匹配的 server name
  25. $host
  26. # host name
  27. $hostname
  28. # 任意请求头字段。变量名的最后一部分是转换为小写的字段名,用下划线替换破折号
  29. $http_name
  30. # 如果连接在 SSL 模式下运行,则为 on,否则为空字符串
  31. $https
  32. # ? 后如果请求行有参数,或者空字符串
  33. $is_args
  34. # 设置此变量可以限制响应速度
  35. $limit_rate
  36. # 当前时间(秒),分辨率为毫秒
  37. $msec
  38. # nginx 版本号
  39. $nginx_version
  40. # 当前 worker 进程号
  41. $pid
  42. # 如果是 pipelined 则为 p,否则为 .
  43. $pipe
  44. # 代理协议头中的客户端地址,否则为空字符串,代理协议之前必须通过在listen指令中设置 proxy_protocol 参数来启用
  45. $proxy_protocol_addr
  46. # 来自代理协议头的客户端端口,否则为空字符串,代理协议之前必须通过在listen指令中设置 proxy_protocol 参数来启用
  47. $proxy_protocol_port
  48. # 与 $args 相同
  49. $query_string
  50. # 与当前请求的 root 或 alias 指令值对应的绝对路径名,所有符号链接都解析为实际路径
  51. $realpath_root
  52. # 客户端地址
  53. $remote_addr
  54. # 客户端端口
  55. $remote_port
  56. # 使用 Basic auth 的用户名
  57. $remote_user
  58. # 完整的请求行
  59. $request
  60. # 请求体,当将请求体读入内存缓冲区时,proxy_pass、fastcgi_pass、uwsgi_pass和scgi_pass指令处理的位置可以使用变量的值
  61. $request_body
  62. # 具有请求主体的临时文件的名称
  63. $request_body_file
  64. # 如果请求完成则为 OK,否则为空
  65. $request_completion
  66. # 当前请求的文件路径,基于 root 或 alias 和请求 URI
  67. $request_filename
  68. # 由16个随机字节生成的惟一请求标识符,以十六进制表示
  69. $request_id
  70. # 请求长度(包括请求行、头和请求体)
  71. $request_length
  72. # 请求方法,如 GET 或 POST
  73. $request_method
  74. # 请求处理时间,从客户端读取第一个字节以来的时间
  75. $request_time
  76. # 若请求 /foo?a=1&b=2,则 request_uri=/foo?a=1&b=2
  77. $request_uri
  78. # 如 http 或 https
  79. $scheme
  80. # 任意响应报头字段,变量名的最后一部分是转换为小写的字段名,用下划线替换破折号
  81. $sent_http_name
  82. # 响应结束时发送的任意字段,变量名的最后一部分是转换为小写的字段名,用下划线替换破折号
  83. $sent_trailer_name
  84. # 接受请求的服务器的地址
  85. $server_addr
  86. # 接受请求的 server 名称
  87. $server_name
  88. # 接受请求的 server 端口
  89. $server_port
  90. # 请求协议,如 HTTP/1.0 或 HTTP/1.1 或 HTTP/2.0
  91. $server_protocol
  92. # 响应状态
  93. $status
  94. $tcpinfo_rtt,$tcpinfo_rttvar,$tcpinfo_snd_cwnd,$tcpinfo_rcv_space
  95. # 本地时间ISO 8601标准格式
  96. $time_iso8601
  97. # 通用日志格式的本地时间
  98. $time_local
  99. # 若请求 /foo?a=1&b=2,则 uri=/foo
  100. $uri
  101. # 用户代理
  102. $http_user_agent
  103. # cookie
  104. $http_cookie

server定义

server 即虚拟服务,它用来描述我们站点一些访问规则。需要填写在 http 标签中,可定义多个,如:

  1. http{
  2. resolver 127.0.0.1;
  3. # 负载均衡
  4. upstream dynamic {
  5. zone upstream_dynamic 64k;
  6. server backend1.example.com weight=5;
  7. server backend2.example.com:8080 fail_timeout=5s slow_start=30s;
  8. server 127.0.0.1:8080 max_fails=3;
  9. server backend3.example.com resolve;
  10. server backend4.example.com service=http resolve;
  11. server backup1.example.com:8080 backup;
  12. server backup2.example.com:8080 backup;
  13. }
  14. server{
  15. listen 80;
  16. server_name example.com www.example.com;
  17. location / {
  18. rewrite https://$host; # 重定向到https
  19. }
  20. }
  21. server {
  22. listen 443 ssl; # 监听端口
  23. server_name example.com www.example.com; # 匹配域名
  24. # ssl证书
  25. ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  26. ssl_ciphers AES128-SHA:AES256-SHA:RC4-SHA:DES-CBC3-SHA:RC4-MD5;
  27. ssl_certificate /usr/local/nginx/conf/cert.pem;
  28. ssl_certificate_key /usr/local/nginx/conf/cert.key;
  29. ssl_session_cache shared:SSL:10m;
  30. ssl_session_timeout 10m;
  31. # 静态服务
  32. location / {
  33. root /usr/share/nginx/html;
  34. index index.html index.htm;
  35. }
  36. # 反向代理
  37. location /api {
  38. proxy_pass http://dynamic;
  39. health_check;
  40. }
  41. }
  42. }
  1. http_upstream_module

说白了就是做负载均衡,它可以帮助我们定义一组相同服务的别名,如backend,当请求到来的时候可以通过相关策略帮我们选一组服务提供响应。
目前只能被 proxy_pass,fastcgi_pass,uwsgi_pass,scgi_pass,memcached_pass,grpc_pass 使用。
形式如下:

  1. upstream <name> { # 命名
  2. server <address> [parameters]; # 服务
  3. server <address> [parameters];
  4. ...
  5. }

[parameters]可选以下值:

  • weight=number,default 1,设置 server 的权重
  • max_conns=number,default 0,限制 server 的活跃连接数,0 代表不限制
  • max_fails=number,default 1,设置在 fail_timeout 时间内失败的最大次数,可由 proxy_next_upstream,fastcgi_next_upstream,uwsgi_next_upstream,scgi_next_upstream,memcached_next_upstream,grpc_next_upstream 指定下组 upstream,0 值代表不启用
  • fail_timeout=time,default 10s,设置多长时间判定无连接服务器失败
  • backup,标记 server 为备用 server,当 primary server 不可用时启用
  • down,标记 server 下线不可用
  • resolve,用来监视与服务器域名对应IP地址的更改,它会自动更改上游配置,upstream 必须驻留在共享内存中,必须写在 http 标签中。
  • route=string,设置 server 路由名称
  • server=name,
  • slow_start=time,慢启动,server 非正常状态恢复到正常需要的时间
  • drain,设置为 drain 模式

其它负载均衡设置

  • zone name [size],设置共享内存的名称和大小
  • state file,
  • hash key [consistent],负载均衡方式,key 可以为文本,变量,或其组合
  • ip_hash,负载均衡方式,根据IP地址范围分布 server,用 IPv4 前三个8位或整个IPv6
  • keepalive connections,设置到上游 server 保持最大空闲连接
  • keepalive_requests number,设置最大请求连接数
  • keepalive_timeout timeout,连接超时时间
  • ntlm,允许使用NTLM身份验证代理请求

    Listen

    listen 监听设置,来看一看可选参数:
    默认:listen :80 | :8000;
    IPv6:listen [::]:8000; listen [::1];
    参数说明:

  • default_server,如果指定,server 将会成为默认 server

  • ssl,开启 ssl 模式,即 https
  • http2,正常情况开启 http2 都应该开始 ssl,但 nginx 也支持不开启 ssl 下的 http2 协议
  • spdy,和 http2 一样,建议开启 ssl
  • setfib=number,监听套接字设置关联的路由表FIB (SO_SETFIB选项)。这目前只适用于FreeBSD
  • fastopen=number,为监听套接字启用“TCP Fast Open”(1.5.8),并限制尚未完成三方握手的连接队列的最大长度
  • backlog=number
  • rcvbuf=size,接受 buffer 的大小(SO_CRCVBUF)
  • sndbuf=size,发送 buffer 的大小(SO_SNDBUF)
  • accept_filter=filter,可选 dataready 和 httpready,在 accept() 前过滤
  • deferred,指示在Linux上使用deferred accept() (TCP_DEFER_ACCEPT套接字选项)
  • bind,标记指定 address:port 单独的绑定
  • ipv6only on|off,只接受 IPv6 连接
  • reuseport
  • so_keepaliv on|off|[keepidle]:[keepintv1]:[keepcnt],”TCP keepalive” 开关

    server_name

    server_name,设置虚拟主机的名称。
  1. 穷举域名

    1. server {
    2. server_name example.com www.example.com;
    3. }
  2. 通配符写法

    1. server {
    2. server_name example.com *.example.com www.example.*;
    3. }
  3. 正则表达式,以~开头

    1. server {
    2. server_name ~^www\d+\.example\.com$;
    3. }
  4. 正则表达式捕获

    1. server {
    2. server_name ~^(www\.)?(.+)$;
    3. }
  5. 正则表达式变量

    1. server {
    2. server_name ~^(www\.)?(?<domain>.+)$;
    3. }
  6. 与空名称使用

    1. server {
    2. server_name www.example.com "";
    3. }

    如果当一个名称匹配多个 server 的是时候,匹配优先级如下:

  7. 确切的名称

  8. 以 * 开头的最长的通配符名称
  9. 以 * 结尾的最长通配符名称
  10. 第一个匹配的正则表达式

    location

    location 是用来干嘛的,它是用来根据 URI 进行配置设置的,如:

    1. server{
    2. location / { # 普通请求网页
    3. root /usr/share/nginx/html;
    4. index index.html index.htm;
    5. }
    6. location /api { # API请求代理
    7. proxy_pass http://dynamic;
    8. health_check;
    9. }
    10. }

    形式如下

    1. location [ = | ~ | ~* | ^~ ] url{ ... }
  • none,如果没有修饰符,则将该位置解释为前缀匹配。这意味着给定的位置将根据请求URI的开头进行匹配,以确定匹配
  • =,代表精确匹配,完全相等即匹配
  • ~,区分大小写的正则表达式匹配
  • ~*,不区分大小写的正则表达式匹配
  • ^~,普通字符匹配,如果该选项匹配,只匹配该选项

nginx 的匹配过程如下:

  1. 精确匹配 =,如果匹配成功,搜索停止
  2. 前缀匹配,最长位置匹配,如果该匹配具有 ^~,搜索停止
  3. 正则匹配,按配置文件中定义的顺序进行匹配。
  4. 如果第3条规则产生匹配的话,结果被使用。否则,使用第2条规则的结果。
    1. #精准匹配,只匹配/
    2. location = / {
    3. [ configuration A ]
    4. }
    5. #请求/index.html会匹配到B
    6. location / {
    7. [ configuration B ]
    8. }
    9. #请求/documentes/document.html 将匹配到C
    10. location /documents/ {
    11. [ configuration C ]
    12. }
    13. #请求/images/1.gif将会匹配到D
    14. location ^~ /images/ {
    15. [ configuration D ]
    16. }
    17. #请求 /documents/1.jpg 将会匹配 E
    18. location ~* \.(gif|jpg|jpeg)$ {
    19. [ configuration E ]
    20. }

    ssl modem

    ssl 模式可以让我们站点启用 HTTPS,具体详细请参考 http_ssl_module
    想要开启 ssl 模式,需要在 listen 关键字处添加上 ssl,如:
    1. server {
    2. listen 443 ssl;
    3. server_name example.com;
    4. ssl_certificate example.com.rsa.crt;
    5. ssl_certificate_key example.com.rsa.key;
    6. ssl_certificate example.com.ecdsa.crt;
    7. ssl_certificate_key example.com.ecdsa.key;
    8. }
    上面的例子是部署双证书,当某一证书因某种原因失效不至于导致站点不能访问。下面来看看参数解释:
  • ssl_buffer_size size,default 16k,发送数据的缓冲区的大小
  • ssl_certificate file,PEM 格式证书文件
  • ssl_certificate_key file,PEM 格式私钥文件
  • ssl_ciphers ciphers,default HIGH:!aNULL:!MD5,ssl套件 openssl ciphers
  • ssl_client_certificate file,用于验证客户端证书的 CA 文件
  • ssl_crl file,用于验证客户端证书的吊销文件
  • ssl_dhparam file,为DHE密码指定具有DH参数的文件
  • ssl_early_data on|off,default on
  • ssl_ecdh_curve curve,default auto,为ECDHE密码指定一条曲线
  • ssl_password_file file,私钥密码文件
  • ssl_prefer_server_ciphers on|off,是否启用服务器套件偏好
  • ssl_protocols [SSLv2] [SSLv3] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2] [TLSv1.3],default TLSv1 TLSv1.1 TLSv1.2,可选的ssl协议
  • ssl_session_cache off|none|[builtin[:size]] [shared:name:size],default none,设置 session cache 的类型和大小

    1. ssl_session_cache builtin:1000 shared:SSL:10m;
  • ssl_session_ticket_key file,设置一个文件,其中包含用于加密和解密TLS会话票据的密钥

    1. ssl_session_ticket_key current.key;
    2. ssl_session_ticket_key previous.key;
  • ssl_session_tickets on|off,default on,是否启用 session ticket

  • ssl_session_timeout time,default 5m,超时时间
  • ssl_stapling on|off,default off,ocsp 装订 ssl_stapling on; resolver 192.0.2.1;
  • ssl_stapling_file file
  • ssl_stapling_responder url
  • ssl_stapling_verify on|off,default off
  • ssl_trusted_certificate file,指定验证客户端证书的 CA 文件
  • ssl_verify_client on|off|optional|optional_no_ca,default off,是否验证客户端证书
  • ssl_verify_depth number,default 1,设置客户端证书链的验证深度

相关变量:
$ssl_cipher,已建立连接使用的 ciphers
$ssl_ciphers,客户端支持的 ciphers
$ssl_client_escaped_cert,urlencoded 客户端证书
$ssl_client_fingerprint,SHA1指纹
$ssl_client_i_dn,issuer DN
$ssl_client_i_dn_legacy,同上,1.11.6之后使用
$ssl_client_raw_cert,PEM格式客户端证书
$ssl_client_s_dn,subject DN
$ssl_client_s_dn_legacy,同上,1.11.6之后使用
$ssl_client_serial,客户端证书序列号
$ssl_client_v_end,客户端证书结束时间
$ssl_client_v_remain,剩余多少天
$ssl_client_v_start,证书开始时间
$ssl_client_verify,客户端证书是否验证成功,”SUCCESS” 或 “FAILED:reason” 或 “NONE”
$ssl_curves,客户端支持的曲线
$ssl_early_data$ssl_protocol,连接使用的协议
$ssl_server_name,从 SNI 获取的 server name
$ssl_session_id,连接的 session id
$ssl_session_reused,session是否重用,”r” 重用,”.” 没有

Supervisor


但是nohup运行的后台程序并不能够可靠的在后台运行,我们最好让我们的后台程序能够监控进程状态,还能在意外结束时自动重启,这就可以使用一个使用Python开发的进程管理程序

安装

  1. virtualenv -p python3 venv
  2. source venv/bin/activate
  3. pip install supervisor
  4. 或者使用:
  5. sudo apt-get install supervisor

安装完成后,我们在/etc/supervisor/conf.d/目录下创建我们控制进程的配置文件,并以.conf结尾,这样将会自动应用到主配置文件当中,创建后添加如下的配置内容:

  1. [program:demo]
  2. command=/q/home/gregory.peng/venv/bin/gunicorn -c ../gunicorn/gconfig.py run:app
  3. directory=/q/home/gregory.peng/venv //项目目录
  4. user=root
  5. autorestart=true //设置自动重启
  6. startretires=3 //重启失败3次

在上面的配置文件中,[program:demo]设置了进程名,这与之后操作进程的状态名称有关,为demo;command为进程运行的命令,必须使用绝对路径,并且使用虚拟环境下的gunicorn命令;user指定了运行进程的用户,这里设置为root
接下来,使用如下命令启动supervisor:

  1. sudo supervisord -c /etc/supervisor/supervisor.conf

查看进程状态

  1. sudo supervisorctl status
  2. >>foo RUNNING pid 17704, uptime 0:21:21

常用命令:

参数 说明
status
status
start
stop
restart
stop all
reload
reread
add
remove
update
tail
shutdown