a.代碼模塊化,不一樣功能的模塊,劃分紅不一樣的分類,下降各功能之間的耦合度
b.藍圖:用於實現單個應用的視圖、模板、靜態文件的集合。
c.藍圖就是一個存儲操做路由映射方法的容器,主要用來實現客戶端請求和URL相互關聯的功能
複製代碼
user.py文件html
from flask import Blueprint
# 建立藍圖
users = Blueprint('user',__name__)
@users.route('/user')
def user():
return "User Page"
複製代碼
login.py文件nginx
from flask import Flask,Blueprint
# 建立藍圖
logins = Blueprint('login',__name__)
@logins.route('/login')
def login():
return "Login Page"
複製代碼
主文件:web
from flask import Flask
# 導入藍圖對象
from login import logins
from user import users
app = Flask(__name__)
@app.route('/')
def hello_world():
return "Hello World!"
#註冊藍圖,第一個參數logins是藍圖對象,url_prefix參數默認值是根路由,若是指定,會在藍圖註冊的路由url中添加前綴。
app.register_blueprint(logins,url_prefix='/')
app.register_blueprint(users,url_prefix='/')
if __name__ == '__main__':
print(app.url_map)
app.run(debug=True)
複製代碼
部署方式:nginx+gunicorn+flaskredis
wsgi協議:一種通訊協議,鏈接web服務器和web應用框架數據庫
uwsgi協議json
uWSGI:實現上述兩種協議的web服務器flask
1.安裝gunicorn :pip install gunicornapi
指定進程和端口號: -w: 表示進程(worker)。 -b:表示綁定ip地址和端口號(bind)瀏覽器
命令:gunicorn -w 4 -b 127.0.0.1:5001 運行文件名稱:Flask程序實例名緩存
a.REST是設計風格而不是標準。是指客戶端和服務器的交互形式。咱們須要關注的重點是如何設計REST風格的網絡接口
b.REST特色:
具象的:通常指表現層,要表現的對象就是資源。好比,客戶端訪問服務器,獲取的數據就是資源。好比文字、圖片、音視頻等
表現:資源的表現形式。txt格式、html格式、json格式、jpg格式等。瀏覽器經過URL肯定資源的位置,可是須要在HTTP請求頭中,用Accept和Content-Type字段指定,這兩個字段是對資源表現的描述。
狀態轉換:客戶端和服務器交互的過程。在這個過程當中,必定會有數據和狀態的轉化,這種轉化叫作狀態轉換。其中,GET表示獲取資源,POST表示新建資源,PUT表示更新資源,DELETE表示刪除資源。HTTP協議中最經常使用的就是這四種操做方式。
c.RESTFul架構
每一個URL表明一種資源;
客戶端和服務器之間,傳遞這種資源的某種表現層;
客戶端經過四個http動詞,對服務器資源進行操做,實現表現層狀態轉換。
複製代碼
ps:1 每一個URL表明一種資源,2. get post delete put分別表明增刪改查 3 看URL就能知道表明那種資源
a.域名
將api部署在專用域名下:http://www.example.com/api/
b.版本
將API的版本號放在url中:http://www.example.com/app/1.0/info
c.路徑
路徑表示API的具體網址。每一個網址表明一種資源。 資源做爲網址,網址中不能有動詞只能有名詞,通常名詞要與數據庫的表名對應。並且名詞要使用複數。
錯誤實例:
http://www.example.com/getGoods
http://www.example.com/listOrders
正確示例:
#獲取單個商品
http://www.example.com/app/goods/1
#獲取全部商品
http://www.example.com/app/goods
d.使用標準的HTTP方法
GET SELECT :從服務器獲取資源。
POST CREATE :在服務器新建資源。
PUT UPDATE :在服務器更新資源。
DELETE DELETE :從服務器刪除資源。
示例:
#獲取指定商品的信息
GET http://www.example.com/goods/ID
#新建商品的信息
POST http://www.example.com/goods
#更新指定商品的信息
PUT http://www.example.com/goods/ID
#刪除指定商品的信息
DELETE http://www.example.com/goods/ID
e.過濾信息
若是資源數據較多,服務器不能將全部數據一次所有返回給客戶端。API應該提供參數,過濾返回結果。
#指定返回數據的數量
http://www.example.com/goods?limit=10
#指定返回數據的開始位置
http://www.example.com/goods?offset=10
#指定第幾頁,以及每頁數據的數量
http://www.example.com/goods?page=2&per_page=20
f.狀態碼
服務器向用戶返回的狀態碼和提示信息,經常使用的有:
200 OK :服務器成功返回用戶請求的數據
201 CREATED :用戶新建或修改數據成功。
202 Accepted:表示請求已進入後臺排隊。
400 INVALID REQUEST :用戶發出的請求有錯誤。
401 Unauthorized :用戶沒有權限。
403 Forbidden :訪問被禁止。
404 NOT FOUND :請求針對的是不存在的記錄。
406 Not Acceptable :用戶請求的的格式不正確。
500 INTERNAL SERVER ERROR :服務器發生錯誤。
g.錯誤信息
通常來講,服務器返回的錯誤信息,以鍵值對的形式返回
{
error:'Invalid API KEY'
}
h.響應結果
i.其餘
服務器返回的數據格式,應該儘可能使用JSON,避免使用XML
複製代碼
服務端性能優化:
1.使用緩存加速數據讀取(大量訪問的數據,存儲在讀寫效率比較高的介質中,好比 redis)
2.使用集羣提升數據吞吐能力
3.使用異步消息加快請求響應
4.使用代碼改善程序性能(多線程)
問題:若是訪問首頁被設置成了緩存,可是緩存都有過時時間,若是在緩存沒有過時的時候,首頁內容被更改,緩存沒有更改,致使咱們看到的內容仍是以前的,這個怎麼解決?
答:1.設置儘可能少的過時時間
2.每次修改更新了數據庫,都要同步更新緩存
複製代碼
rom flask import Flask
import logging
app = Flask(__name__)
# 日誌系統配置
handler = logging.FileHandler('app.log', encoding='UTF-8')
logging_format = logging.Formatter(
'%(asctime)s - %(levelname)s - %(filename)s - %(funcName)s - %(lineno)s - %(message)s')
handler.setFormatter(logging_format)
app.logger.addHandler(handler)
@app.route('/')
def index():
try:
no_thing = []
app.logger.info('info log')
app.logger.warning('warning log')
i = no_thing[0] # 這裏會報錯,由於列表根本是空的
return 'Hello!'
except Exception as e:
app.logger.error('%s', e)
if __name__ == '__main__':
app.run(port=8802,debug=True)
複製代碼
ERROR:這個級別的日誌意味着系統中發生了很是嚴重的問題,必須有人立刻處理,好比數據庫不可用了,系統的關鍵業務流程走不下去了等等。不少人在實際開發的時候,不會去區分問題的重要程度,只要有問題就error記錄下來,其實這樣是很是不負責任的,由於對於成熟的系統,都會有一套完整的報錯機制,那這個錯誤信息何時須要發出來,不少都是依據單位時間內error日誌的數量來肯定的。所以若是咱們不分輕重緩急,一概error對待,就會徒增報錯的頻率,長此以往,咱們的救火隊員對錯誤警報就不會那麼在乎,這個警報也就失去了原始的意義。
WARN:發生這個級別的問題時,處理過程能夠繼續,但必需要對這個問題給予額外的關注。假設咱們如今有一個系統,但願用戶每個月更換一次密碼,而到期後,若是用戶沒有更新密碼咱們還要讓用戶能夠繼續登陸,這種狀況下,咱們在記錄日誌時就須要使用WARN級別了,也就是容許這種狀況存在,但必須及時作跟蹤檢查。
INFO:這個級別的日誌咱們用的也是比較多,它通常的使用場景是重要的業務處理已經結束,咱們經過這些INFO級別的日誌信息,能夠很快的瞭解應用正在作什麼。咱們以在12306上買火車票爲例,對每一張票對應一個INFO信息描述「[who] booked ticket from [where] to [where]」。
DEBUG和TRACE:咱們把這兩個級別放在一塊兒說,是應爲這兩個級別的日誌是隻限於開發人員使用的,用來在開發過程當中進行調試,可是其實咱們有時候很難將DEBUG和TRACE區分開來,通常狀況下,咱們使用DEBUG足以。
app.logger.debug('A value for debugging')
app.logger.warning('A warning occurred (%d apples)', 42)
app.logger.error('An error occurred')
複製代碼
待總結
複製代碼
部署視頻:https://www.bilibili.com/video/av45206566?from=search&seid=695331927454347708
複製代碼
1.gunicorn配置 安裝gunincorn pip install gunicorn 啓動flask命令:gunicorn -w (開啓進程數) -b (服務器和端口) -D(表示以進程運行,後臺不會關閉) --access-logfile ./logs/log 運行的程序:app
w:表示進程數 b:表示容許訪問的ip和端口號 -D:是以進程的形式開啓 --access-logfile 表示日誌文件 運行的程序:表示主程序名 app:實例名
以配置文件開啓:
在主程序同級目錄下新建配置文件,gun.cnf,配置以下:
bind = '0.0.0.0:8802'
workers = 10
proc_name = 'app'
pidfile = '/tmp/app.pid'
其中:workers表示開啓10個進程
gunicorn -c gun.conf face_app:app --reload -D (在服務器上的部署命令,flasktest表示所有接口的 那個py文件)
複製代碼
2.nginx
多臺服務器配置在upstraem中,flask是本身命名的,nginx收到請求會轉發到兩臺服務器上,找到下邊的location,location中最後兩行配置是客戶端的原始信息,ip等原封不動的給到業務服務器