目录
前言
最近在捣鼓如何使用阿里云服务器搭建一个简单的基于Flask框架的后端接口,刚开始为了图方便,就直接买了一个Windows Server 2008系统服务器,这也埋下了不小的坑。
服务买下来后,会给你一个公网IP和内网IP,由于是第一次学习搭建后端接口,对于如何正确使用阿里云服务器,来处理好公网IP和内网IP之间的关系埋下了不小的坑,真是对应的一句话:技术的成长往往是一步一个坑。
下面简单说一下搭建Flask服务器端遇到的问题:
首先,Flask自带了一个服务器,直接使用很方便,不过这个服务器的性能太低,但是对于调试和学习还是绰绰有余。刚开始把代码放到阿里云服务器上,并跑通后,测试接口时公网IP无法访问,那时我以为是Flask自带服务器的问题,即因为Flask自带服务器原因导致无法使用公网IP访问。
那么,问题出现了,就要寻找解决办法吧,网上查找资料给出参照意见:使用nginx +gunicorn来部署Flask相关服务,可以避免公网IP无法访问问题。然后,我就去找资料,安装gunicorn,结果运行测试时一直报错,最后发现gunicorn不支持Windows系统,这也太坑了,早知道我当时买服务器时就不该图方便,直接买一个基于Linux的系统了。
现在,新的问题又来了,既然不能使用nginx +gunicorn来部署Flask相关服务,那就要使用其它方式来解决吧,网上资料参照结果:使用tornado。好,那么我又来查看学习tornado部署应用开发文档,按照开发文档部署完毕后,在服务器上跑通后,发现依旧不能使用公网IP进行接口访问和测试。
到了这里,就让我反思,这个难道真是Flask部署应用服务器问题吗?后来,就在网上找到了一篇关于阿里云公网IP无法访问问题的文章,发现这个需要自己去阿里云官网上去配置设置。
即以上遇到的问题,压根就不是Flask部署服务器问题,是自己没有搞清楚阿里云服务器如何使用的问题......
具体配置设置方法见:阿里云服务器 ECS 访问不了公网 ip 可能的原因及解决方法
附:
1 准备工作
导入Flask及相关扩展:
pip install flask
pip install flask-pymongo
pip install tornado(此处可选可不选。如果不选择,直接使用Flask自带的服务器部署即可;如果选择,可以使用tornado部署)
MongoDB数据库绑定服务ip地址设置(PS:如果不进行下述设置,默认ip为本机127.0.0.1地址):
打开CMD,进入MongoDB安装的bin文件夹下,例如我的安装目录为:C:\Program Files\MongoDB\Server\3.2\bin
然后在CMD中输入mongod.exe --bind_ip yourIPadress
其中参数--bind_ip意思:绑定服务IP,若绑定127.0.0.1,则只能本机访问,不指定默认本地所有IP。(注意:其中yourIPadress填写自己搭建服务器的内网ip地址)
具体如下图:
开启Flask自带的服务器,一般使用app.run(),其中一般使用如下三个参数:host(指定ip地址,如果不填写,默认为127.0.0.1)、port(指定使用的端口,如果不指定,默认为5000端口)、debug(开启调试模式,默认值为Flase,即不开启调试模式,如要开启则可以设置为True)。
如果在服务器上搭建Flask接口相关服务,设置其中host=’0.0.0.0’表示在公网ip下的同一个局域网段所有ip都可以访问这个服务,如果把host指定为其中一个内网ip地址,则这个局域网下所有用户可以通过访问这个指定的ip地址访问Flask服务。
后面介绍可以略微看看,也相当于是了解一下nginx +gunicorn以及tornado的基本概念。也可以忽略,直接查看2 具体实现
使用nginx +gunicorn来部署Flask相关服务,即不使用Flask自带的服务器。
看到上面的部署方式,作为初学者,不免会有新的疑问,什么是nginx和gunicorn呢?
我自己也是新接触的,查看了一下网上资料,大概了解了一下。
什么是nginx呢?
摘抄自百度百科(https://baike.baidu.com/item/nginx/3817705?fr=aladdin)的一段解释:Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好,*使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。
什么是gunicorn呢?
摘抄自网上一遍文章(http://www.pythontip.com/blog/post/5155/)一段解释:Gunicorn“绿色独角兽”是一个被广泛使用的高性能的Python WSGI UNIX HTTP服务器,移植自Ruby的独角兽(Unicorn )项目,使用pre-fork worker模式,具有使用非常简单,轻量级的资源消耗,以及高性能等特点。
Gunicorn 服务器作为wsgi app的容器,能够与各种Web框架兼容(flask,django等),得益于gevent等技术,使用Gunicorn能够在基本不改变wsgi app代码的前提下,大幅度提高wsgi app的性能。
看到上面的解决办法,试着搭建安装,发现gunicorn不支持Windows系统,坑啊,早知道这样就买一个Linux服务器。
使用gunicorn报错信息:
Traceback (most recent call last): File "d:\program files (x86)\python27\Lib\runpy.py", line 174, in _run_module_as_main "__main__", fname, loader, pkg_name) File "d:\program files (x86)\python27\Lib\runpy.py", line 72, in _run_code exec code in run_globals File "E:\WorkPlace\Git_python\liu_demo\venv\Scripts\gunicorn.exe\__main__.py", line 5, in <module> File "e:\workplace\git_python\liu_demo\venv\lib\site-packages\gunicorn\app\wsgiapp.py", line 10, in <module> from gunicorn.app.base import Application File "e:\workplace\git_python\liu_demo\venv\lib\site-packages\gunicorn\app\base.py", line 12, in <module> from gunicorn import util File "e:\workplace\git_python\liu_demo\venv\lib\site-packages\gunicorn\util.py", line 9, in <module> import fcntl ImportError: No module named fcntl
然而我的服务器依旧是Windows版本,Flask服务器环境还是要搭建,那么得采用什么方案呢?
此处推荐采用tornado。
那么什么是tornado呢?
摘抄至网上一篇文章(http://www.tornadoweb.cn/)介绍:Tornado 是 FriendFeed 使用的可扩展的非阻塞式 web 服务器及其相关工具的开源版本。这个 Web 框架看起来有些像 web.py 或者 Google 的 webapp,不过为了能有效利用非阻塞式服务器环境,这个 Web 框架还包含了一些相关的有用工具 和优化。
Tornado 和现在的主流 Web 服务器框架(包括大多数 Python 的框架)有着明显的区别:它是非阻塞式服务器,而且速度相当快。得利于其 非阻塞的方式和对 epoll 的运用,Tornado 每秒可以处理数以千计的连接,这意味着对于实时 Web 服务来说,Tornado 是一个理想的 Web 框架。我们开发这个 Web 服务器的主要目的就是为了处理 FriendFeed 的实时功能 ——在 FriendFeed 的应用里每一个活动用户都会保持着一个服务器连接。(关于如何扩容 服务器,以处理数以千计的客户端的连接的问题,请参阅 C10K problem。)
至于具体怎么运用,可以查看上面文章介绍,也可以参见下文的具体使用代码。
2 具体实现
看到下面具体实现代码,会让大家感叹,Python的确是一个优美的语言,Flask框架也的确是对应小而又轻量级的框架美称呀。使用MongoDB数据库,操作数据库也变得极为简单。
在看下面代码之前,需要简单说一下REST的基本思想原理,也相当于是我自己进一步加深印象吧。下面解释应用自阮一峰博客的一个评论,我感觉这样描述的很在理。
REST四个基本原则:
1.使用HTTP动词:GET POST PUT DELETE;
2.无状态连接,服务器端不应保存过多上下文状态,即每个请求都是独立的;
3.为每个资源设置URI;
4.通过XML JSON进行数据传递;
实现上述原则的架构即可称为RESTFul架构。
1.互联网环境下,任何应用的架构和API可以被快速理解;
2.分布式环境下,任何请求都可以被发送到任意服务器;
3.异构环境下,任何资源的访问和使用方式都统一;
看到上面介绍,既然说了REST方式使用HTTP动词GET POST PUT DELETE来实现相关操作。
那么下面代码就简单实现一下这四个动词的具体操作功能。
GET:实现从服务器后台获取数据功能,例如登陆接口功能实现;
POST:实现向服务器后台提交数据功能,例如注册接口功能实现;
PUT:实现修改服务器后台已有数据功能;
DELETE:实现删除服务器后台已有数据功能。
看完上面介绍,下面就请看代码:
如果不使用tornado,直接使用下面一个mongo.py文件中代码即可实现本文标题所述功能:
#coding=utf-8
#mongo.py
from flask import Flask,abort
from flask import jsonify
from flask import request
from flask_pymongo import PyMongo app = Flask(__name__) app.config['MONGO_DBNAME'] = 'rest'
app.config['MONGO_URI'] = 'mongodb://172.18.252.20:27017/rest' #如果部署在本上,其中ip地址可填127.0.0.1 mongo = PyMongo(app) @app.route('/login', methods=['GET'])
def get_all_users():
star = mongo.db.userInfo.find()
output = []
for s in star:
output.append({'name' : s['name'], 'pwd' : s['pwd']})
return jsonify({'result' : output}) @app.route('/register', methods=['POST'])
def add_user():
star = mongo.db.userInfo
name = request.json['name']
pwd = request.json['pwd']
star_id = star.insert({'name': name, 'pwd': pwd})
new_star = star.find_one({'_id': star_id })
output = {'name' : new_star['name'], 'pwd' : new_star['pwd']}
return jsonify({'result' : output}) @app.route('/modify/<string:name>', methods=['PUT'])
def update_user(name):
user = mongo.db.userInfo.find({"name":name})
output = []
for s in user:
output.append({'name': s['name'], 'pwd': s['pwd']})
if len(output) == 0:
abort(404)
mongo.db.userInfo.update({"name":name},{'$set':{"name":"LZ111"}})
return jsonify({'result': output}) @app.route('/delete/<string:name>', methods=['DELETE'])
def delete_user(name):
user = mongo.db.userInfo.find({"name": name})
output = []
for s in user:
output.append({'name': s['name'], 'pwd': s['pwd']})
if len(output) == 0:
abort(404)
mongo.db.userInfo.remove({'name': name})
return jsonify({'result': True}) if __name__ == '__main__':
# app.run(host = '0.0.0.0', port = 80, debug = True)
app.run()
如果使用tornado,新建一个tornado_server.py文件,添加以下代码,作为Flask服务启动部署,也可以实现相关功能:
#coding=utf-8
#tornado_server.py
from tornado.wsgi import WSGIContainer
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop from mongo import app http_server = HTTPServer(WSGIContainer(app))
# http_server.listen(9000) #此时,开启端口9000,默认本机127.0.0.1的IP地址
http_server.bind(80, "172.18.252.20")# 开启端口为9000,172.18.252.20为内网ip地址,也可以设置为0.0.0.0,
http_server.start(1)
IOLoop.instance().start()
看完上面代码,点击运行,即可实现相关接口功能了。既然是接口,GET方式还好说,如果是POST方式,使用浏览器就不那么好操作了,此时我们需要使用一款接口测试软件,在这里我推荐使用Postman(PS:Postman百度经验介绍,Postman官网下载链接 , 附加百度云盘WIN64位下载链接:https://pan.baidu.com/s/12t09OMcrezgNY3_JfYFx8g密码:z1vk),如果有同学使用基于Linux相关系统,推荐使用CURL来实现。
下面就正式开始使用Postman测试Get、Post、Put和Delete方式接口:
Get方式,选中下图中下拉框GET方式,直接输入URL,然后点击Send蓝色按钮即可得到请求数据。
Post方式,选中下拉框中Post方式,这里由于要发送数据,需要稍微设置一下。
首先,在下图中Headers中要选择Content-Type的数据方式,这里我选择的是json格式:
然后,点开下图中Body,选择raw,添加要存入的json格式数据,如下:
最后,点击Send按钮,在最下面出现相关提示信息后,即可查看Post请求结果。
Put方式操作和Get方式雷同,不同的是需要选中操作方式为Put,具体如下图:
Delete方式和Put请求几乎一样,不同的是一个执行修改操作,一个执行删除操作而已,具体如下图:
基本操作就这样,看完上面代码,发现使用FLask+MongoDB写后端接口是不是特别简单?
参考资料:
1.Designing a RESTful API with Python and Flask(PS:附加一个中文版,不过里面代码有bug)
3.MONGODB RESTFUL API WITH FLASK
使用Flask+MongoDB实现基于REST的接口简单操作的更多相关文章
-
C# 对MongoDB 进行增删改查的简单操作
C# 对MongoDB 进行增删改查的简单操作 下面演示下C#操作MongoDB驱动的简单的增删改查代码 运用到的MongoDB支持的C#驱动,当前版本为1.6.0 1,连接数据库 /// & ...
-
MongoDB学习-在.NET中的简单操作
1.新建MVC项目, 管理NuGet包,进入下载MongDB.net库文件 2.新增项目DAL数据访问层,引用以下库文件: 3.C# 访问MongoDB通用方法类: using MongoDB.Dri ...
-
C# 对MongoDB 进行增删改查的简单操作 (转)
运用到的MongoDB支持的C#驱动,当前版本为1.6.0 下载地址:https://github.com/mongodb/mongo-csharp-driver/downloads 1,连接数据库 ...
-
【MongoDB学习-在.NET中的简单操作】
1.新建MVC项目, 管理NuGet包,进入下载MongDB.net库文件 2.新增项目DAL数据访问层,引用以下库文件: 3.C# 访问MongoDB通用方法类: using MongoDB.Dri ...
-
【MongoDB学习-在.NET中的简单操作类】
1.新建MVC项目, 管理NuGet包,进入下载MongDB.net库文件 2.新增项目DAL数据访问层,引用以下库文件: 3.C# 访问MongoDB通用方法类: using MongoDB.Dri ...
-
Flask+mongodb 实现简易个人博客
最近学习完了<flask-web开发>,实现了一个简易的个人博客网站,由flask+mongodb+bootstrap做成, 这个软件是在阅读<Flask-Web开发>后写的一 ...
-
基于Server-Sent Event的简单聊天室 Web 2.0时代,即时通信已经成为必不可少的网站功能,那实现Web即时通信的机制有哪些呢?在这门项目课中我们将一一介绍。最后我们将会实现一个基于Server-Sent Event和Flask简单的在线聊天室。
基于Server-Sent Event的简单聊天室 Web 2.0时代,即时通信已经成为必不可少的网站功能,那实现Web即时通信的机制有哪些呢?在这门项目课中我们将一一介绍.最后我们将会实现一个基于S ...
-
Matlab与.NET基于类型安全的接口混合编程入门
原文:[原创]Matlab与.NET基于类型安全的接口混合编程入门 如果这些文章对你有用,有帮助,期待更多开源组件介绍,请不要吝啬手中的鼠标. [原创分享]Matlab.NET混编调用Figure窗体 ...
-
《Flask Web开发——基于Python的Web应用开发实践》一字一句上机实践(上)
目录 前言 第1章 安装 第2章 程序的基本结构 第3章 模板 第4章 Web表单 第5章 数据库 第6章 电子邮件 第7章 大型程序的结构 前言 学习Python也有一个半月时间了,学到现在感觉 ...
随机推荐
-
获取微软原版“Windows 10 推送器(GWX)” 卸载工具
背景: 随着Windows 10 免费更新的结束,针对之前提供推送通知的工具(以下简称GWX)来说使命已经结束,假设您还未将Windows 8.1 和Windows 7 更新到Windows 10 的 ...
-
实现textarea高度自适应内容,无滚动条
最近接触到一个很好用的js插件,可以实现textarea高度随内容增多而改变,并且不显示滚动条,推荐给大家: http://www.jacklmoore.com/autosize/
-
程序是如何执行的(一)a=a+1
本文链接:http://www.orlion.ml/35/ 一.概述 1.计算机中有两个主要的核心部件:CPU和内存,其中CPU负责运算而内存负责存储程序和相关的变量,每一条程序语句和变量都在内存中有 ...
-
AutoResetEvent和ManualResetEvent理解 z
AutoResetEvent和ManualResetEvent用于多线程之间代码执行顺序的控制,它们继承自WaitHandle,API相同,但在使用中还是有区别的. 每次使用时虽然理解了,但由于没有去 ...
-
PHP defined() 函数
定义和用法 defined() 函数检查某常量是否存在. 若常量存在,则返回 true,否则返回 false. 语法 defined(name) 参数 描述 name 必需.规定要检查的常量的名称. ...
-
springboot入门1
1引入springboot父依赖,和 spring-boot-starter-web的启动器 依赖引入后jar包展示依赖的情况 入门工程 配置数据源 package com.boot.web.con ...
-
分布式服务框架XXL-RPC
<分布式服务框架XXL-RPC> 一.简介 1.1 概述 XXL-RPC 是一个分布式服务框架,提供稳定高性能的RPC远程服务调用功能.拥有"高性能.分布式.注册中心. ...
-
python列表中的值转换为字符串,及列表里的所有值拼接成一个字符串 的方法
后记: ls3='%'.join(ls2) 会把%加入拼接成的字符里面,同理,加入其它字符也一样,''空就是什么都不加,如上图 最后输出 1%我%22
-
mysql 官方docker镜像使用教程
首先是pull image,这里我拉取的是5.x版本最新版: docker pull mysql:5 拉下来以后大可以按照官方的说明无脑启动,但是外部无法访问,所以绑定端口:docker run -- ...
-
spring中的BeanFactory和FactoryBean的区别与联系
首先,这俩都是个接口… 实现 BeanFactory 接口的类表明此类是一个工厂,作用就是配置.新建.管理 各种Bean. 而 实现 FactoryBean 的类表明此类也是一个Bean,类型为工厂B ...