前面我們已安裝好了python服務器運行所需要的相關軟件,而最重要最繁瑣的就是參數配置,寫這篇就踩了好多坑,花了好多時間,遇到了各種各樣的問題。好了費話少說,直接進入本篇話題。
一、讓你的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包:pip install bottle
安裝beaker包:pip 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.2並存,在對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-dev插件
輸入命令:yum install python-dev
第一個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"]
將這個例子運行起來: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.ini,內容如下:
[uwsgi] socket = 127.0.0.1:8088 chdir = /data/www/test/ wsgi-file = /data/www/test/main.py limit-as = 512 reload-on-as = 256 reload-on-rss = 192 processes = 2 max-requests = 1000 pythonpath = /data/www/test/ daemonize = /data/logs/uwsgi/test_uwsgi.log log-maxsize = 10000000 disable-logging = true master = true vacuum = true no-orphans = true
修改/etc/supervisord.conf配置文件內容,將command=python /data/www/test/main.py修改為command=/usr/local/bin/uwsgi /etc/uwsgi/test.ini
[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/local/bin/uwsgi /etc/uwsgi/test.ini 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 / { include uwsgi_params; 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了
----------------------------------------2017-3-30 16:06修改更新---------------------------------------------------
ps:之前使用/usr/bin/supervisorctl update重啟supervisord,可能瀏覽器訪問時出現502 Bad Gateway,這時我們需要查看supervisord和uwsgi日志,看看日志里有什么錯誤提示。一般會有下面日志:
*** 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 = 123456 allempty = 123456
這里設置賬號對應的密碼
將svnserve.conf文件替換成下面內容:
[general] anon-access = none auth-access = write password-db = passwd authz-db = authz
在/data/svn/test/hooks/目錄下創建post-commit勾子文件(post-commit文件沒有擴展名),用於svn更新成功以后,自動同步到對應的代碼目錄
#!/bin/sh export LANG=en_US.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進行使用)
六、postgresql配置
在data下創建pg文件夾,用於放置pg相關的所有東西
輸入命令:mkdir /data/pg
在pg文件夾下我們再創建存放數據庫的文件夾
輸入命令:mkdir /data/pg/data
為新創建的pg文件夾分配數據庫服務的操作權限
輸入命令:chown postgres:postgres /data/pg
為存放數據庫的文件夾分配權限
輸入命令:chown postgres:postgres /data/pg/data
設置postgresql相關環境變量
修改profile文件
輸入命令:vi /etc/profile
在尾部添加下面代碼:
PGDATA=/data/pg/data PGHOST=127.0.0.1 PGDATABASE=postgres PGUSER=postgres PGPORT=5432 PATH=/usr/pgsql-9.6/bin:$PATH export PATH export PGDATA PGHOST PGDATABASE PGUSER PGPORT export TMOUT=1000
重啟一下虛擬機(reboot)或者輸入命令: source /etc/profile重新載入配置,然后輸入命令:export 就可以看到剛才添加的變量了
初始化postgresql數據庫:
使用postgres登錄:su postgres
然后執行初始化數據庫命令,並指定數據庫存儲路徑:initdb -D /data/pg/data
退出postgres用戶,使用原root賬號登錄,可輸入命令:su root,然后輸入密碼就可以切換回去
我們再次進入/data/pg/data路徑,就可以看到多了很多數據庫文件夾和配置文件了
打開/data/pg/data/pg_hba.conf配置文件,找到# IPv4 local connections: 在它的下面添加一行host all all 0.0.0.0/0 md5
添加以后,我們鏈接數據庫都必須要用輸入密碼
打開/data/pg/data/postgresql.conf配置文件
找到#listen_addresses = 'localhost',將前面的#刪掉,參數localhost表示只允許當前服務器能鏈接數據庫,如果想指定地址可以訪問,可以輸入ip地址,多個地址時用逗號分隔,如果開放所有地址可以訪問,由使用*
找到#port = 5432,將前面的#刪掉,這里可以指定訪問數據庫的端口
啟動postgresql數據庫:su postgres -c "/usr/pgsql-9.6/bin/pg_ctl start -D /data/pg/data"
使用postgres用戶登錄:su postgres
連接數據庫:psql -U postgres
修改postgres用戶密碼:Alter user postgres with password '123456';
退出數據庫連接:\q
我們可以在本地的windows系統里安裝postgresql9.6(官方下載地址:https://www.postgresql.org/download/windows/),然后使用pgAdmin4連接上服務器的數據庫,用圖形界面來管理數據庫了
七、pgbouncer配置
pgbouncer是pg數據庫的鏈接池管理工具,一般用於高並發高可用時使用,並發量不高的系統可以不使用它,可采用直接鏈接數據庫的方式
創建pgbouncer配置文件與日志存儲文件夾:mkdir /data/pg/pgbouncer
設置文件夾訪問用戶權限:chown -R postgres:postgres /data/pg/pgbouncer
設置文件夾讀寫權限:chmod 600 /data/pg/pgbouncer
添加/data/pg/pgbouncer/pgbouncer.ini配置文件,內容如下:
[databases] write_db = host=127.0.0.1 port=5432 dbname=postgres user=postgres password=123456 read_db = host=127.0.0.1 port=5432 dbname=postgres user=postgres password=123456 [pgbouncer] listen_port = 5433 listen_addr = * auth_type = md5 auth_file = /data/pg/pgbouncer/userlist.txt logfile = /data/pg/pgbouncer/pgbouncer.log pidfile = /data/pg/pgbouncer/pgbouncer.pid admin_users = pg_admin pool_mode = session max_client_conn = 1000 default_pool_size = 128
配置中的pg_admin是pgbouncer的登錄賬號,auth_file是配置各種賬號密碼的文件路徑,在這里可以直接配置讀與寫用不同的數據庫(write_db與read_db)
添加/data/pg/pgbouncer/userlist.txt配置文件,內容如下:
"pg_admin" "123456"
設置文件夾訪問用戶權限:chown -R postgres:postgres /data/pg/pgbouncer/*
添加pgbouncer相關環境變量
輸入命令:vi /etc/profile
在尾部添加下面代碼:
PATH=/usr/local/pgbouncer/bin:$PATH
輸入命令重啟服務器:reboot,讓配置生效
啟動postgresql數據庫:su postgres -c "/usr/pgsql-9.6/bin/pg_ctl start -D /data/pg/data"
啟動pgbouncer服務: su postgres -c "/usr/local/bin/pgbouncer -d /data/pg/pgbouncer/pgbouncer.ini"
查看pgbouncer服務啟動情況:ps -ef | grep pgbouncer
PS:pgbouncer服務的啟動,不能直接用root用戶去執行啟動命令,這樣會出現 FATAL @src/main.c:875 in function main(): PgBouncer should not run as root 這樣的錯誤提示,為了這個問題,我用這個錯誤提示做為關鍵字找了N久,都沒有找到解決辦法,還好認識postgresql中文社區大牛:阿弟,他就一句話幫我這個外行人解決了,非常感謝阿弟的幫助
pgbouncer具體的測試與使用,以后相關文章再寫
八、Redis配置
redis之前安裝沒有指定安裝路徑,重新做了修改,大家可以查看http://www.cnblogs.com/EmptyFS/p/6558800.html 檢查安裝
修改redis配置信息(可以下載/usr/local/redis/redis.conf或直接用vi /usr/local/redis/redis.conf進行編輯)
主要修改內容有:
bind 127.0.0.1 redis服務訪問限制設置。使用127.0.0.1表示只能本機訪問;如果用的是服務器在局域網里的ip:192.168.1.128,即表示局域網內的ip都可以訪問;如果使用0.0.0.0由表示所有地址都可以訪問。需要綁定多個時,可以添加多個bind xxx.xxx.xxx.xxx
daemonize no 這個修改為daemonize yes 開啟守護進程
dir ./ 這里需要修改為dir /usr/local/redis/data 不然redis數據會存儲到root文件夾下面
隨便找個位置增加requirepass xxxxx,可以增加訪問redis訪問密碼,如果你的redis對外網開放,這個密碼一樣要足夠長足夠復制,不然以redis的訪問速度,比較容易被人破解
可以增加maxmemory 1024M來限制redis占用內容大小,也可以不限制
修改完成后,創建redis數據存儲文件夾:mkdir /usr/local/redis/data
修改完成,運行redis啟動命令:/usr/local/redis/bin/redis-server /usr/local/redis/redis.conf
redis服務就啟動了,可以使用RedisDesktopManager這種第三方可視化工具來訪問redis,查看里面的存儲數據
九、設置各服務開機啟動功能
以上眾多的服務,有的朋友喜歡將它們設置成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" su postgres -c "/usr/local/bin/pgbouncer -d /data/pg/pgbouncer/pgbouncer.ini" /usr/local/redis/bin/redis-server /usr/local/redis/redis.conf
給予rc.local可執行權限:chmod +x /etc/rc.d/rc.local
然后重啟服務器,我們使用ps -ef就可以查看到各服務正在運行中了
版權聲明:
本文由AllEmpty原創並發布於博客園,版權與博客園共同所有
轉自:http://www.cnblogs.com/EmptyFS/p/6595968.html