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等原封不动的给到业务服务器