python服务器环境搭建(3)——参数配置

举报
AllEmpty 发表于 2020/03/10 19:27:49 2020/03/10
【摘要】   前面我们已安装好了python服务器运行所需要的相关软件,而最重要最繁琐的就是参数配置,写这篇就踩了好多坑,花了好多时间,遇到了各种各样的问题。好了费话少说,直接进入本篇话题。  一、优化服务器网络环境  在开始配置服务器前,我们需要先对服务器环境配置进行优化,提升服务器的访问数和处理数  输入命令:vi /etc/sysctl.conf  将里面值替换为下面参数# sysctl set...

  前面我们已安装好了python服务器运行所需要的相关软件,而最重要最繁琐的就是参数配置,写这篇就踩了好多坑,花了好多时间,遇到了各种各样的问题。好了费话少说,直接进入本篇话题。

  一、优化服务器网络环境

  在开始配置服务器前,我们需要先对服务器环境配置进行优化,提升服务器的访问数和处理数

  输入命令:vi /etc/sysctl.conf

  将里面值替换为下面参数

# sysctl settings are defined through files in
# /usr/lib/sysctl.d/, /run/sysctl.d/, and /etc/sysctl.d/.
#
# Vendors settings live in /usr/lib/sysctl.d/.
# To override a whole file, create a new file with the same in
# /etc/sysctl.d/ and put new settings there. To override
# only specific settings, add a file with a lexically later
# name in /etc/sysctl.d/ and put new settings there.
#
# For more information, see sysctl.conf(5) and sysctl.d(5).
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1

vm.swappiness = 0
net.ipv4.neigh.default.gc_stale_time=120


# see details in https://help.aliyun.com/knowledge_detail/39428.html
net.ipv4.conf.all.rp_filter=0
# net.ipv4.conf.default.rp_filter=0
net.ipv4.conf.default.arp_announce = 2
net.ipv4.conf.lo.arp_announce=2
net.ipv4.conf.all.arp_announce=2


# see details in https://help.aliyun.com/knowledge_detail/41334.html
# net.ipv4.tcp_max_tw_buckets = 5000
# net.ipv4.tcp_syncookies = 1
# net.ipv4.tcp_max_syn_backlog = 1024
net.ipv4.tcp_synack_retries = 2

net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 0
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
net.ipv4.tcp_max_tw_buckets = 6000
net.ipv4.tcp_sack = 1
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_rmem = 4096 87380 4194304
net.ipv4.tcp_wmem = 4096 16384 4194304
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.netdev_max_backlog = 262144
# net.core.somaxconn = 262144
net.core.somaxconn = 2048
net.ipv4.tcp_max_orphans = 3276800
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_mem = 94500000 915000000 927000000
net.ipv4.tcp_fin_timeout = 1
net.ipv4.tcp_keepalive_time = 10
net.ipv4.tcp_keepalive_probes=5
net.ipv4.ip_local_port_range = 1024 65535


  输入命令让配置生效:sysctl -p

 

  输入命令:echo "options sunrpc tcp_slot_table_entries=256" >> /etc/modprobe.d/sunrpc.conf

  写入配置:sysctl -w sunrpc.tcp_slot_table_entries=256

  重启服务器,再查看一下配置就可以看到配置参数值已经改变了(有的服务器可能不存在这两个文件,不运行问题也不大)

  输入命令:cat /proc/sys/sunrpc/tcp_slot_table_entries

  输入命令:cat /proc/sys/sunrpc/tcp_max_slot_table_entries

  一个是256,一个是65536

 

  二、让你的python代码跑起来

  既然我们要配置的是python服务器,那首先我们要做的第一步是,放上我们的python代码,看看能否运行并访问

  先上代码,将下面代码粘贴到记事本上并存储为main.py(这个文名可以随便起,我存储的格式为ANSI格式,即记事本默认的格式)

#!/usr/bin/evn python
# coding=utf-8

from bottle import default_app, get, run
from beaker.middleware import SessionMiddleware

@get('/index/')
def callback():
    return 'Hello World!'

if __name__ == '__main__':
    app_argv = SessionMiddleware(default_app())
    run(app=app_argv, host='0.0.0.0', port=8088, debug=True, reloader=True)
else:
    application = SessionMiddleware(default_app())


  我们为了方便以后对服务器的管理,需要创建一个指定的文件夹(如果有挂载新硬盘的,可以将这个文件夹绑定到该目录),将日志、数据库、web站、后台服务、svn等内容统一放到指定文件夹下面

  首先在根目录下创建一个data文件夹(后面的各种日志、web站点等全都放在这里统一管理,以后我们要查找时就很方便了)

  输入命令:mkdir /data

  创建python web存储目录:mkdir /data/www

  创建测试目录:mkdir /data/www/test

  然后使用SSH的上传工具1583839102100809.png,上传刚刚创建好的main.py文件到www目录下的test文件夹

1583839114475440.png

  后面的上传用这个上传工具处理(也可以直接使用vi进行编辑)不再截图

  然后我们运行:python /data/www/test/main.py  (或进入test目录运行:python main.py

  运行后会显示ImportError: No module named bottle错误,这是因为我们的程序调用了bottle包,而我们未安装这个依赖包,需要安装后程序才能正常运行,以后在使用python中碰到这种情况,直接输入pip install xxx即可

  安装bottle包:pip3 install bottle

  安装beaker包:pip3 install beaker

1583839134774756.png

  然后再次输入:python main.py

  就会发现python web服务运行起来了

1583839151862433.png

   然后关闭防火墙:systemctl stop firewalld  (如果浏览器访问不了,可以运行这个命令来关闭防火墙)

   打开浏览器输入:http://192.168.0.128:8088/index/  就可以看到Hello World!了

1583839169600689.png

  为了方便后面的测试,我们按Ctrl+C,关闭刚才python启动的main.py服务

 

  三、使用supervisord来管理python进程

  supervisord默认配置文件存放路径是/etc/目录下面,安装完成后配置文件是不存在的,需要使用命令生成或我们自己放一个进去,我们先配置一个简单的不使用uwsgi的配置文件

  文件名称:supervisord.conf (我存储的格式为ANSI格式,即记事本默认的格式)

[unix_http_server]
file=/tmp/supervisor.sock   ; (the path to the socket file)

[supervisord]
logfile=/data/logs/supervisord/supervisord.log ; (main log file;default $CWD/supervisord.log)
logfile_maxbytes=10MB        ; (max main logfile bytes b4 rotation;default 50MB)
logfile_backups=2           ; (num of main logfile rotation backups;default 10)
loglevel=info                ; (log level;default info; others: debug,warn,trace)
pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
nodaemon=false               ; (start in foreground if true;default false)
minfds=1024                  ; (min. avail startup file descriptors;default 1024)
minprocs=200                 ; (min. avail process descriptors;default 200)

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL  for a unix socket


[program:test]
command=python /data/www/test/main.py    ; supervisord将要执行的运行python服务的命令
directory=/data/www/test
stdout_logfile=/data/logs/supervisord/test_supervisord.log    ; supervisord当前这个test服务运行产生的日志存储路径,方便我们查看运行情况
socket-timeout=3
autostart=true
autorestart=true
redirect_stderr=true
stopsignal=QUIT


  使用上传工具上传到/etc/supervisord.conf

1583839206730254.png

  为了规范日志管理,我们在data文件夹下继续创建对应的日志文件夹,以后查找supervisord日志就可以在下面创建的文件夹中查看了

  输入命令:mkdir /data/logs

  输入命令:mkdir /data/logs/supervisord

  由于supervisord目前只支持python2,所以运行时需要用python2来启动

  启动supervisord服务:/usr/bin/python2.7 /usr/bin/supervisord

1583839230913886.png

  我们继续在浏览器中输入http://192.168.0.128:8088/index/ 可以发现还是可以正常访问,看到Hello World!(前面执行python /data/www/test/main.py后,按Ctrl+C就直接退出了,用浏览器是无法正常访问的,现在的访问是supervisord启动的)

  使用supervisord启动的python进程可以发现,我们用kill xxx命令来直接关闭python进程,关闭后supervisord会重新启动新的进程,也就是说不kill掉supervisord进程,是无法杀死supervisord启动的python进程的

1583839255480336.png

  PS:由于python2.7.5与python3.5.4并存,在对supervisord配置进行修改以后,使用命令:/usr/bin/supervisord -v执行时,会出现 ImportError: No module named 'supervisor' 这个错误,虽然我们前面用的是python2.7.5来启动supervisord服务的,但生成执行命令时,默认还是用python这个链接,所以我们需要对/usr/bin/supervisord/usr/bin/supervisorctl进行修改

  执行命令:vi /usr/bin/supervisord

  将第一行的#!/usr/bin/python 改为 #!/usr/bin/python2.7.5

  执行命令:vi /usr/bin/supervisorctl

  将第一行的#!/usr/bin/python 改为 #!/usr/bin/python2.7.5

  我们再执行:/usr/bin/supervisord -v时就正常了

 

  四、将nginx与supervisord关联起来(使用代理方式,非uwsgi)

  首先我们要为nginx创建对应的访问账号

  输入命令:/usr/sbin/groupadd -f www
  输入命令:/usr/sbin/useradd -g www www

 

  为nginx创建对应的日志管理文件夹

  输入命令:mkdir /data/logs/nginx

  因为nginx的配置默认全部是在nginx.conf里设置的,网站多时管理不方便,所以我们需要创建一个文件夹,将每个独立的网站配置放在里面

  创建nginx配置统一管理文件夹:mkdir /usr/local/nginx/conf/vhost

  修改/usr/local/nginx/conf/nginx.conf配置文件内容,替换成下面参数

user www www;
worker_processes  1;
worker_rlimit_nofile 10240;
error_log /data/logs/nginx/error.log error;

events {
    use epoll;
    worker_connections  10240;
}

http {
    log_format  main  '[$time_local] $remote_addr  $upstream_addr  $status  $body_bytes_sent  [$request_time] '
                      '"$request" "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    tcp_nopush     on;
    tcp_nodelay on;
    server_tokens off;
    
    include vhost/*.conf;
}


  创建test.conf文件(内容见下面代码)并上传到刚创建的/usr/local/nginx/conf/vhost/目录下,具体内容如下(使用80端口访问,将代理地址指定前面配置的8088端口):

server {
    listen      80;
    charset     utf-8;
    root        /data/www/test;
    server_name 192.168.0.128;
    
    location / {
        proxy_pass  http://127.0.0.1:8088;
    }

    access_log  /data/logs/nginx/test_access.log  main;
}


  PS:在使用之前,我们需要重新一次服务器,不然可能会出现端口被占用访问出现404的问题,重启后就正常

  启动nginx服务: /usr/local/nginx/sbin/nginx 

  启动supervisord服务:/usr/bin/python2.7 /usr/bin/supervisord

  如果修改了nginx配置内容,需要重新启动nginx才能生效,重启命令: /usr/local/nginx/sbin/nginx 

  如果启动后没有出现错误信息,就表示启动成功了,可以使用命令来查询启动情况:ps -ef | grep nginx

  我们在浏览器中输入http://192.168.0.128/index/可以发现Hello World!访问正常(PS:可以发现,我们直接访问80端口完全没有问题)

1583839305633266.png

  五、使用nginx+supervisord+uwsgi来管理python web服务

  首先,我们让uwsgi运行起来

  根据官网(https://uwsgi-docs.readthedocs.io/en/latest/)说明,我们还需要安装python-devel插件

  输入命令:yum install python-devel

 

  第一个Hello World!例子:

  输入命令:vi /tmp/foobar.py

  然后点击键盘 i  进入编辑模式,将下面的代码粘贴进vi编辑器,然后按Esc键,按Shift+:,输入wq+回车键,保存foobar.py文件

def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return [b"Hello World"]


  将这个例子运行起来:/usr/bin/uwsgi --http :9090 --wsgi-file /tmp/foobar.py

 

  我们在浏览器中输入网址:http://192.168.0.128:9090/ 就可以看到Hello World了

 

  我们按Ctrl+C,关闭刚才用uwsgi启动的main.py服务

  为了方便uwsgi配置的管理,我们需要在etc目录下创建uwsgi文件夹,用来存储配置文件

  输入命令:mkdir /etc/uwsgi

  创建uwsgi日志文件夹:mkdir /data/logs/uwsgi

  创建配置文件,并将它上传到/etc/uwsgi目录下,配置文件名:test.xml,内容如下:

<uwsgi>
    <plugins>python35</plugins>
    <socket>127.0.0.1:8088</socket>
    <chdir>/data/www/test</chdir>
    <listen>2048</listen>
    <limit-as>512</limit-as>
    <reload-on-as>128</reload-on-as>
    <reload-on-rss>96</reload-on-rss>
    <processes>8</processes>
    <max-requests>2000</max-requests>
        <socket-timeout>6</socket-timeout>
        <harakiri>6</harakiri>
        <idle>20</idle>
    <pythonpath>/data/www/test</pythonpath>
    <logto>/data/logs/uwsgi/test_uwsgi.log</logto>
    <master/>
        <reaper/>
    <no-orphans/>
    <vacuum/>
    <disable-logging/>
</uwsgi>


  修改/etc/supervisord.conf配置文件内容,将command=python /data/www/test/main.py修改为command=/usr/local/bin/uwsgi /etc/uwsgi/test.xml

[unix_http_server]
file=/tmp/supervisor.sock   ; (the path to the socket file)

[supervisord]
logfile=/data/logs/supervisord/supervisord.log ; (main log file;default $CWD/supervisord.log)
logfile_maxbytes=10MB        ; (max main logfile bytes b4 rotation;default 50MB)
logfile_backups=2           ; (num of main logfile rotation backups;default 10)
loglevel=info                ; (log level;default info; others: debug,warn,trace)
pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
nodaemon=false               ; (start in foreground if true;default false)
minfds=1024                  ; (min. avail startup file descriptors;default 1024)
minprocs=200                 ; (min. avail process descriptors;default 200)

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL  for a unix socket


[program:test]
command=/usr/bin/uwsgi /etc/uwsgi/test.xml
directory=/data/www/test
stdout_logfile=/data/logs/supervisord/test_supervisord.log
socket-timeout=3
autostart=true
autorestart=true
redirect_stderr=true
stopsignal=QUIT


  修改nginx的配置文件/usr/local/nginx/conf/vhost/test.conf

server {
    listen      80;
    charset     utf-8;
    root        /data/www/test;
    server_name 192.168.0.128;

    location / {
        proxy_set_header           Host $host;
        proxy_set_header           X-Real-IP $remote_addr; 
        proxy_set_header           X-Forwarded-For $proxy_add_x_forwarded_for; 
        proxy_connect_timeout      2;      
        proxy_send_timeout         60;     
        proxy_read_timeout         60;     
        include uwsgi_params;
        uwsgi_param UWSGI_PYHOME /data/www/test;
        uwsgi_param UWSGI_CHDIR /data/www/test;
        uwsgi_param UWSGI_SCRIPT main;
        uwsgi_pass  127.0.0.1:8088;
    }

    access_log  /data/logs/nginx/test_access.log  main;
}


  重启服务命令:/usr/local/nginx/sbin/nginx -s reload(如果nginx服务没有启动,就使用这个命令:/usr/local/nginx/sbin/nginx )

  另外,如果我们修改了supervisord的配置文件,则需要运行下面命令重启服务(如果你又重启了服务器,则需要重新启动supervisord服务:/usr/bin/python2.7 /usr/bin/supervisord,否则不用执行这个命令)

  载入刚刚修改过的配置信息:/usr/bin/supervisorctl reread (运行后才可以载入内存)

  重启全部supervisord服务:/usr/bin/supervisorctl reload (运行这个将会重启全部服务,会比较慢)

  PS:其他supervisord命令说明

  启动或重启配置修改项对应的服务:/usr/bin/supervisorctl update (有时可能会启动失败,需要需要其他方式启动)

  我们更新了python文件,如果没有重启对应的服务修改是不生效的,即访问时还是旧的代码功能,需要重启对应的服务才行,比如现在我们的supervisord服务名称叫做test,那么可以使用下面命令来重启对应的uwsgi服务

  重启test的uwsgi服务:/usr/bin/supervisorctl restart test (启动服务命令:/usr/bin/supervisorctl start test

 

  我们在浏览器中输入网址:http://192.168.0.128/index/ 就可以看到使用nginx+supervisord+uwsgi+python(bottle框架)运行的Hello World了

 

  ps:之前使用/usr/bin/supervisorctl update重启supervisord,可能浏览器访问时出现502 Bad Gateway,这时我们需要查看supervisord和uwsgi日志,看看日志里有什么错误提示。一般会有下面日志:

  日志路径可以查看前面/etc/supervisord.conf 和 /etc/uwsgi/test.xml 配置文件里设置的路径,如果是nginx的日志则查看 /usr/local/nginx/conf/vhost/ 下面各个conf配置文件里设置的路径,用cat命令就可以查看到日志内容了,如果日志内容非常多,可以使用tail -f xxx.log命令来实时查看。

*** Starting uWSGI 2.0.14 (64bit) on [Thu Mar 30 03:44:31 2017] ***
compiled with version: 4.8.5 20150623 (Red Hat 4.8.5-11) on 29 March 2017 23:46:25
os: Linux-3.10.0-514.el7.x86_64 #1 SMP Tue Nov 22 16:42:41 UTC 2016
nodename: localhost.localdomain
machine: x86_64
clock source: unix
pcre jit disabled
detected number of CPU cores: 16
current working directory: /data/www/test
detected binary path: /usr/local/bin/uwsgi
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** 
chdir() to /data/www/test/
your processes number limit is 62479
limiting address space of processes...
your process address space limit is 536870912 bytes (512 MB)
your memory page size is 4096 bytes
detected max file descriptor number: 1024
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
probably another instance of uWSGI is running on the same address (127.0.0.1:8088).
bind(): Address already in use [core/socket.c line 769]


  我们可以输入命令:ps -ef | grep uwsgi,查看一下uwsgi有没有运行,如果没有运行的话,可执行:/usr/bin/supervisorctl reload,再使用ps命令检查一下uwsgi启动了没有,启动了就表示正常了

 

 

  六、使用svn来管理python的自动化发布

  创建svn管理目录:mkdir /data/svn

  进入svn管理目录:cd /data/svn

  创建svn项:svnadmin create test

  修改/data/svn/test/conf文件夹下的配置文件

1583839437644400.png

  可以将这三个文件下载下来进行修改,也可以用vi进行编辑

  将authz文件替换成下面内容:

[test:/]

admin = rw
allempty = rw


   test是svn当前仓库项的模块名称,每个svn的这个名称都是唯一的,不然可能无法登录使用

  添加添加了两个账号,admin用于服务器端自动同步svn的代码到对应的web或服务使用,和个人账号区别出来,方便管理和保护账号安全,而allempty是我自己添加用于svn更新最新代码的账号

  将password文件替换成下面内容:

[users]
admin = 123456allempty = 123456

  这里设置账号对应的密码

  将svnserve.conf文件替换成下面内容:

[general]
anon-access = none
auth-access = writepassword-db = passwdauthz-db = authz

  在/data/svn/test/hooks/目录下创建post-commit勾子文件(post-commit文件没有扩展名),用于svn更新成功以后,自动同步到对应的代码目录

#!/bin/sh

export.UTF-8
/usr/bin/svn up /data/www/test
/usr/bin/supervisorctl restart test

  /usr/bin/svn up /data/www/test 这个命令是运行更新指令,本地代码通过svn更新到服务器以后,勾子会运行它来同步到指定的/data/www/test目录

  /usr/bin/supervisorctl restart test 因为我们用的是supervisord来管理python web服务的,代码更新完成以后并未生效,需要重新服务才行,这个命令是用来重启指定的supervisord进程的,它们帮我们将对应的uwsgi进程进行重启操作

  运行命令,将给予勾子post-commit可执行权限:chmod +x /data/svn/test/hooks/post-commit

 

  启动svn服务:/usr/bin/svnserve -d -r /data/svn

  配置test项目服务器端svn同步设置

  输入命令:svn checkout svn://localhost/test /data/www/test (在服务器端对test项进行svn检出操作)

  PS:出现Password for 'root': 直接回车就可以了,Username:输入前面authz里设置的账户名称,Password for 'admin': 输入对应的密码

1583839521965768.png

  操作到这里,svn的自动化发布就完成了,我们只需要在本地检出svn项,然后更新代码后,服务器端就会自动将代码同步到/data/www/test目录下面,并重启对应的supervisord服务了

  本地操作截图:(可以下载TortoiseSVN-1.9.4.27285-x64-svn-1.9.4.msi进行使用)

1583839555745705.png

1583839555931917.png


1583839555451850.png

1583839555754748.png


  七、设置各服务开机启动功能

  以上众多的服务,有的朋友喜欢将它们设置成service方式自动启动,也有喜欢用命令方式来启动它们,为了操作简单,我们将它们都统一设置为命令启动方式。

  输入命令: vi /etc/rc.local ,在内容后面添加下面命令项,然后保存退出

ulimit -SHn 102400
/usr/bin/python2.7 /usr/bin/supervisord
/usr/local/nginx/sbin/nginx
/usr/bin/svnserve -d -r /data/svn
su postgres -c "/usr/pgsql-9.6/bin/pg_ctl start -D /data/pg/data"
/usr/local/redis/bin/redis-server /usr/local/redis/redis.conf


  给予rc.local可执行权限:chmod +x /etc/rc.d/rc.local

  然后重启服务器,我们使用ps -ef就可以查看到各服务正在运行中了


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。