python服务器环境搭建(3)——参数配置
前面我们已安装好了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的上传工具,上传刚刚创建好的main.py文件到www目录下的test文件夹
后面的上传用这个上传工具处理(也可以直接使用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
然后再次输入:python main.py
就会发现python web服务运行起来了
然后关闭防火墙:systemctl stop firewalld (如果浏览器访问不了,可以运行这个命令来关闭防火墙)
打开浏览器输入:http://192.168.0.128:8088/index/ 就可以看到Hello World!了
为了方便后面的测试,我们按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
为了规范日志管理,我们在data文件夹下继续创建对应的日志文件夹,以后查找supervisord日志就可以在下面创建的文件夹中查看了
输入命令:mkdir /data/logs
输入命令:mkdir /data/logs/supervisord
由于supervisord目前只支持python2,所以运行时需要用python2来启动
启动supervisord服务:/usr/bin/python2.7 /usr/bin/supervisord
我们继续在浏览器中输入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进程的
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端口完全没有问题)
五、使用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文件夹下的配置文件
可以将这三个文件下载下来进行修改,也可以用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': 输入对应的密码
操作到这里,svn的自动化发布就完成了,我们只需要在本地检出svn项,然后更新代码后,服务器端就会自动将代码同步到/data/www/test目录下面,并重启对应的supervisord服务了
本地操作截图:(可以下载TortoiseSVN-1.9.4.27285-x64-svn-1.9.4.msi进行使用)
七、设置各服务开机启动功能
以上众多的服务,有的朋友喜欢将它们设置成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就可以查看到各服务正在运行中了
- 点赞
- 收藏
- 关注作者
评论(0)