利用nginx、gunicorn进行负载均衡 - pjpan/DataScience GitHub Wiki

利用nginx和gunicorn进行负载均衡的设置,需要进行两个地方的设置,首先是:

  1. 设置nginx, 配置nginx.conf文件
#user  nobody;
worker_processes  12;

#pid        logs/nginx.pid;

events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  100;

    #gzip  on;

    server {
        listen       8889;
        server_name  10.14.221.88;
        root /bankapp/hushu/myprogram/Nginx/html;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
        proxy_pass http://127.0.0.1:8890;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        #error_page   500 502 503 504  /50x.html;
        #location = /50x.html {
        #    root   html;
        #}

    }

    server {
        listen       8899;
        server_name  10.14.221.88;
        #root /home/address_similarity/html;

        charset utf-8;

        #access_log  logs/host.access.log  main;

        location / {
        #proxy_http_version 1.1;
        #proxy_set_header Connection "";
        proxy_pass http://127.0.0.1:9001;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                }

    upstream AI_ADDRESS {  # 对网址进行负载均衡
        server 10.14.221.88:9001 weight=5;
        server 10.14.221.88:9002 weight=10;
    }

    server {
        listen 9090;  # 监听9090端口,外网访问的也是9090端口

       location / {
            proxy_pass http://AI_ADDRESS; # 设置一个虚拟的网址
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

    }


}
  1. 启动nginx,开始监听9090端口
nginx -c nginx.conf
  1. flask的配置:
  • 首先把主实例的文件夹复制两份,以方便进行gunicorn的多进程配置和负载均衡,这两个文件里面会出现gun_1.py和gun_2.py文件,分配配置的是端口:9001和9002对应的进程实例,所以后续对文件更新的时候,需要进行同步,否则会出问题

  • 配置gun_1.py文件,对gunicorn进行多进程设置,解决gunicorn的不稳定问题;

[root@CNSZ445979 AddressSimilarity_v1.1]# cat gun_1.py

#!/usr/bin/python
# -*- coding: utf-8 -*-

import os
import gevent.monkey
gevent.monkey.patch_all()

import multiprocessing

debug = True
loglevel = 'debug'
bind = '10.14.221.88:9001'
pidfile = 'log/gunicorn.pid'
logfile = 'log/debug.log'

#启动的进程数
workers = multiprocessing.cpu_count() * 2 + 1 
worker_class = 'gunicorn.workers.ggevent.GeventWorker'

x_forwarded_for_header = 'X-FORWARDED-FOR'
  • 设置主程序,main.py文件
# -*- coding: utf-8 -*-
"""
Created on Sun Jul  9 13:58:24 2017

@author: PANPENGJU716
"""
from __future__ import absolute_import
import sys
import os
import json
from addrner.utils.crf_model import crf_model
import jieba
from scripts import simhash
from scripts import simhash
from flask import Flask, request, abort
from scripts import lsisimilarity
from scripts.utils import strQ2B, jaccard, jaccard_word
import pandas as pd
from sklearn.externals import joblib
sys.path.append(os.path.dirname(os.path.realpath('__file__')))

app = Flask(__name__)


@app.route('/rest/nlp/v1/address_similarity', methods=['GET'])
def address_similarity():
    if not request.args:
        abort(400)
    else:
        addra = str(request.args.get('addr1'))
        # print(str(request.headers))
        addrb = str(request.args.get('addr2'))
        # print(addrb)
        os.chdir(os.path.dirname(os.path.realpath(__file__)))
        lr = joblib.load('lr.model')

        simiscore = predictScore(addra, addrb, lr)
        print(simiscore)
        return "%s" % (json.dumps({"similarity": simiscore}
                                  , ensure_ascii=False))


@app.route('/')
def say_hi():
    return 'welcome to address similarity restful-api services'


if __name__ == '__main__':
    # from werkzeug.contrib.fixers import ProxyFix # 不需要设置额外的端口也能正常启动
    # app.wsgi_app = ProxyFix(app.wsgi_app)
    app.run()
  • 设置run_multi.sh,启动gunicorn启动脚本,利用shell来启动脚本;
#!/bin/sh

nohup gunicorn -c gun_1.py main:app >/dev/null 2>&1 &
  1. 启动gunicorn的配置;
  • 启动: ./run_multi.sh即可以实现负载均衡
/home/app/anaconda3/bin/python /home/app/anaconda3/bin/gunicorn -c gun_2.py main:app
/home/app/anaconda3/bin/python /home/app/anaconda3/bin/gunicorn -c gun_1.py main:app

这里需要注意的是,需要python环境中安装gunicorn,否则会报错;

  1. 最后启动一个daemon进程,监控gunicorn是否存在,否则自动重启一下,run_daemon.sh
#!/bin/sh

PROGRAM="/home/app/anaconda3/bin/python /home/app/anaconda3/bin/gunicorn -c gun_1.py main:app"

while true; do
  sleep 10
  processes_count=`ps aux | grep "${PROGRAM}" | grep -v grep | wc -l`
  if [ ${processes_count} -lt 1 ]; then
    nohup ${PROGRAM} >/dev/nul 2>&1 &
  fi
done