数据库连接池

flask中是没有ORM的,如果在flask里面连接数据库有两种方式

一:pymysql
二:SQLAlchemy
是python 操作数据库的一个库。能够进行 orm 映射官方文档 sqlchemy
SQLAlchemy“采用简单的Python语言,为高效和高性能的数据库访问设计,实现了完整的企业级持久模型”。SQLAlchemy的理念是,SQL数据库的量级和性能重要于对象集合;而对象集合的抽象又重要于表和行。

数据库连接池原理

- BDUtils数据库链接池
- 模式一:基于threaing.local实现为每一个线程创建一个连接,关闭是
伪关闭,当前线程可以重复
- 模式二:连接池原理
- 可以设置连接池中最大连接数 9
- 默认启动时,连接池中创建连接 5
                    -<span style="color: #000000;"> 如果有三个线程来数据库中获取连接:
</span>-<span style="color: #000000;"> 如果三个同时来的,一人给一个链接
</span>-<span style="color: #000000;"> 如果一个一个来,有时间间隔,用一个链接就可以为三个线程提供服务
</span>-<span style="color: #000000;"> 说不准
有可能:1个链接就可以为三个线程提供服务
有可能:2个链接就可以为三个线程提供服务
有可能:3个链接就可以为三个线程提供服务
PS、:maxshared在使用pymysql中均无用。链接数据库的模块:只有threadsafety</span>&gt;1的时候才有用</pre>

基于DBUtils实现连接池的两种模式

模式一:

为每一个线程创建一个链接(是基于本地线程来实现的。thread.local),每个线程独立使用自己的数据库链接,该线程关闭不是真正的关闭,本线程再次调用时,还是使用的最开始创建的链接,直到线程终止,数据库链接才关闭

注:如果线程的数量比较多,那么还是会创建比较多的线程数,所以模式二更加的常用

from flask import Flask
app = Flask(__name__)
from DBUtils.PersistentDB import PersistentDB
import pymysql
POOL = PersistentDB(
creator=pymysql, # 使用链接数据库的模块
maxusage=None, # 一个链接最多被重复使用的次数,None表示无限制
setsession=[], # 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."]
ping=0,
# ping MySQL服务端,检查是否服务可用。# 如:0 = None = never, 1 = default = whenever it is requested, 2 = when a cursor is created, 4 = when a query is executed, 7 = always
closeable=False,
# 如果为False时, conn.close() 实际上被忽略,供下次使用,再线程关闭时,才会自动关闭链接。如果为True时, conn.close()则关闭链接,那么再次调用pool.connection时就会报错,因为已经真的关闭了连接(pool.steady_connection()可以获取一个新的链接)
threadlocal=None, # 本线程独享值得对象,用于保存链接对象,如果链接对象被重置
host='127.0.0.1',
port=3306,
user='root',
password='',
database='pooldb',
charset='utf8'
) @app.route('/func')

def func():

  conn = POOL.connection()

  cursor = conn.cursor()

  cursor.execute('select * from tb1')

  result = cursor.fetchall()

  cursor.close()

  conn.close() # 不是真的关闭,而是假的关闭。 conn = pymysql.connect() conn.close()



  conn = POOL.connection()

  cursor = conn.cursor()

  cursor.execute('select * from tb1')

  result = cursor.fetchall()

  cursor.close()

  conn.close()

if name == 'main': app.run(debug=True)

模式二:

创建一个链接池,为所有线程提供连接,使用时来进行获取,使用完毕后在放回到连接池。

PS:假设最大链接数有10个,其实也就是一个列表,当你pop一个,人家会在append一个,链接池的所有的链接都是按照排队的这样的方式来链接的。

链接池里所有的链接都能重复使用,共享的, 即实现了并发,又防止了链接次数太多

import time
import pymysql
import threading
from DBUtils.PooledDB import PooledDB, SharedDBConnection
POOL = PooledDB(
creator=pymysql, # 使用链接数据库的模块
maxconnections=6, # 连接池允许的最大连接数,0和None表示不限制连接数
mincached=2, # 初始化时,链接池中至少创建的空闲的链接,0表示不创建
maxcached</span>=5,  <span style="color: #008000;">#</span><span style="color: #008000;"> 链接池中最多闲置的链接,0和None不限制</span>
maxshared=3, <span style="color: #008000;">#</span><span style="color: #008000;"> 链接池中最多共享的链接数量,0和None表示全部共享。PS: 无用,因为pymysql和MySQLdb等模块的 threadsafety都为1,所有值无论设置为多少,_maxcached永远为0,所以永远是所有链接都共享。</span>
blocking=True, <span style="color: #008000;">#</span><span style="color: #008000;"> 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错</span>
maxusage=None, <span style="color: #008000;">#</span><span style="color: #008000;"> 一个链接最多被重复使用的次数,None表示无限制</span>
setsession=[], <span style="color: #008000;">#</span><span style="color: #008000;"> 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."]</span>
ping=<span style="color: #000000;">0,
</span><span style="color: #008000;">#</span><span style="color: #008000;"> ping MySQL服务端,检查是否服务可用。# 如:0 = None = never, 1 = default = whenever it is requested, 2 = when a cursor is created, 4 = when a query is executed, 7 = always</span>
host=<span style="color: #800000;">'</span><span style="color: #800000;">127.0.0.1</span><span style="color: #800000;">'</span><span style="color: #000000;">,
port</span>=3306<span style="color: #000000;">,
user</span>=<span style="color: #800000;">'</span><span style="color: #800000;">root</span><span style="color: #800000;">'</span><span style="color: #000000;">,
password</span>=<span style="color: #800000;">'</span><span style="color: #800000;">123</span><span style="color: #800000;">'</span><span style="color: #000000;">,
database</span>=<span style="color: #800000;">'</span><span style="color: #800000;">pooldb</span><span style="color: #800000;">'</span><span style="color: #000000;">,
charset</span>=<span style="color: #800000;">'</span><span style="color: #800000;">utf8</span><span style="color: #800000;">'</span><span style="color: #000000;">

)

def func():

# 检测当前正在运行连接数的是否小于最大链接数,如果不小于则:等待或报raise TooManyConnections异常

# 否则

# 则优先去初始化时创建的链接中获取链接 SteadyDBConnection。

# 然后将SteadyDBConnection对象封装到PooledDedicatedDBConnection中并返回。

# 如果最开始创建的链接没有链接,则去创建一个SteadyDBConnection对象,再封装到PooledDedicatedDBConnection中并返回。

# 一旦关闭链接后,连接就返回到连接池让后续线程继续使用。

<span style="color: #008000;">#</span><span style="color: #008000;"> PooledDedicatedDBConnection</span>
conn =<span style="color: #000000;"> POOL.connection() </span><span style="color: #008000;">#</span><span style="color: #008000;"> print(th, '链接被拿走了', conn1._con)</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> print(th, '池子里目前有', pool._idle_cache, '\r\n')</span>

cursor = conn.cursor()
cursor.execute('select * from tb1')
result = cursor.fetchall()
conn.close()

conn </span>=<span style="color: #000000;"> POOL.connection()

</span><span style="color: #008000;">#</span><span style="color: #008000;"> print(th, '链接被拿走了', conn1._con)</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> print(th, '池子里目前有', pool._idle_cache, '\r\n')</span>

cursor = conn.cursor()
cursor.execute('select * from tb1')
result = cursor.fetchall()
conn.close()

func()

1.安装

安装ssh

新版本安装位 apt/apt-get

老版本为 apt-get

安装以后 ifconfig查看当前的ip地址

如果网络不在同一个ip段 将网络模式设置为桥接

安装pip3

sudo apt install python3-pip

  1. 在要安装项目的目录创建虚拟环境

    virtualenv venv

  2. source activate # 开启虚拟开发环境模式

  3. 退出 deactivate

  4. pip3 install uwsgi # 安装uwsgi

2.配置

uwsgi配置文件支持很多格式,我采用.ini格式,命名为uconfig.ini具体内容如下:

socket指出了一个套接字,相当于为外界留出一个uwsgi服务器的接口。

[uwsgi]

# 外部访问地址,可以指定多种协议,现在用http便于调试,之后用socket  #

socket = 0.0.0.0:8000 # uwsgi的监听端口 # 指向项目目录

chdir = /home/xlg/blog/ # flask启动程序文件

wsgi-file = manage.py # flask在manage.py文件中的app名

callable = app plugins = python# 这行一定要加上,不然请求时会出现-- unavailable modifier requested: 0 --错误提示 # 处理器数

processes = 1 # 线程数

threads = 2

socket和http的差别。从概念上来说,socket本身不是协议而是一种具体的TCP/IP实现方式,而HTTP是一种协议且基于TCP/IP。具体到这个配置这里来,如果我只配了socket = 127.0.0.1:5051的话,通过浏览器或者其他HTTP手段是无法成功访问的。而在uwsgi这边的日志里会提示请求包的长度超过了最大固定长度。另一方面,如果配置的是http = 127.0.0.1:5051的话,那么就可以直接通过一般的http手段来访问到目标。但这会引起nginx无法正常工作。正确的做法应该是,如果有nginx在uwsgi之前作为代理的话应该配socket,而如果想让请求直接甩给uwsgi的话那么就要配http

pythonpath指出了项目的目录,module指出了项目启动脚本的名字而紧接着的wsgi-file指出了真正的脚本的文件名。callable指出的是具体执行.run方法的那个实体的名字,一般而言都是app=Flask(name)的所以这里是app。processes和threads指出了启动uwsgi服务器之后,服务器会打开几个并行的进程,每个进程会开几条线程来等待处理请求,显然这个数字应该合理,太小会使得处理性能不好而太大则会给服务器本身带来太大负担。daemonize项的出现表示把uwsgi服务器作为后台进程启动,项的值指向一个文件表明后台中的所有输出都重定向到这个日志中去。

daemonize = /home/wyz/flask/server.log

3.安装nginx

sudo apt-get install nginx

Nginx是轻量级、性能强、占用资源少,能很好的处理高并发的反向代理软件。Ubuntu 上配置 Nginx 也是很简单,不要去改动默认的 nginx.conf 只需要将/etca/nginx/sites-available/default文件替换掉就可以了。 新建一个 default 文件:+

server{
listen 80; # 服务器监听端口
server_name 10.0.121.116; # 这里写你的域名或者公网IP
location / {
uwsgi_pass 127.0.0.1:8000; # 转发端口,需要和uwsgi配置当中的监听端口一致
include uwsgi_params; # 导入uwsgi配置
#uwsgi_param UWSGI_PYTHON /home/自己创建的目录/venv; # Python解释器所在的路径(这里为虚拟环境)
uwsgi_param UWSGI_PYTHON /usr/bin/python3;
uwsgi_param UWSGI_CHDIR /home/xlg/blog/;# # 自己创建的目录 项目根目录
uwsgi_param UWSGI_SCRIPT manage:app; # 指定启动程序
#比如你测试用test.py文件,文件中app = Flask(name),那么这里就填 test:app
}
}

服务启动

  1. sudo service nginx start

  2. sudo service nginx stop

  3. sudo service nginx restart

安装mysql数据库

sudo apt-get install mysql-server

指定配置文件,后台运行 uwsgi, 这时再刷新一下之前打开的页面,就可以看到应用正常运行了。

pip3 -V 查看是哪个python解释器的

pip3 list  查看安装了哪些包

pip3 freeze 安装的模块和版本号

pip3 freeze>requirements.txt

pip3 install -r requirements.txt

安装项目需要的第三方库

1. flask
2. pymysql
3. flask-wtf
4. flask-login
5. flask-mail
6. flask-script
7. flask-bootstrap
8. flask-cache
9. flask-sqlalchemy
10. pillow
11. flask-migrate
12. flask-moment
13. flask-uploads
14. redis

日志分类

Nginx(http://www.jbxue.com/server/nginx/)日志主要分为两种:访问日志和错误日志。日志开关在Nginx配置文件(/etc/nginx/nginx.conf)中设置,两种日志都可以选择性关闭,默认都是打开的。

access_log /var/log/nginx/access.log;

error_log /var/log/nginx/error.log;

基于DBUtils实现数据库连接池及flask项目部署的更多相关文章

  1. Flask【第3篇】:蓝图、基于DBUtils实现数据库连接池、上下文管理等

    基于DBUtils实现数据库连接池 小知识: 1.子类继承父类的三种方式 class Dog(Animal): #子类 派生类 def __init__(self,name,breed, life_v ...

  2. 蓝图、基于DBUtils实现数据库连接池、上下文管理等

    基于DBUtils实现数据库连接池 小知识: 1.子类继承父类的三种方式 class Dog(Animal): #子类 派生类 def __init__(self,name,breed, life_v ...

  3. 3、flask之基于DBUtils实现数据库连接池、本地线程、上下文

    本篇导航: 数据库连接池 本地线程 上下文管理 面向对象部分知识点解析 1.子类继承父类__init__的三种方式 class Dog(Animal): #子类 派生类 def __init__(se ...

  4. flask之基于DBUtils实现数据库连接池、本地线程、上下文

    本篇导航: 数据库连接池 本地线程 上下文管理 面向对象部分知识点解析 1.子类继承父类__init__的三种方式 class Dog(Animal): #子类 派生类 def __init__(se ...

  5. Flask学习【第3篇】:蓝图、基于DBUtils实现数据库连接池、上下文管理等

    小知识 子类继承父类的三种方式 class Dog(Animal): #子类 派生类 def __init__(self,name,breed, life_value,aggr): # Animal. ...

  6. Flask系列(三)蓝图、基于DButils实现数据库连接池、上下文管理

    知识点回顾 1.子类继承父类的三种方式 class Dog(Animal): #子类 派生类 def __init__(self,name,breed, life_value,aggr): # Ani ...

  7. 基于DBUtils实现数据库连接池

    小知识: 1.子类继承父类的三种方式 class Dog(Animal): #子类 派生类 def __init__(self,name,breed, life_value,aggr): # Anim ...

  8. flask项目部署到阿里云 ubuntu16.04

    title: flask项目部署到阿里云 ubuntu16.04 date: 2018.3.6 项目地址: 我的博客 部署思路参考: Flask Web开发>的个人部署版本,包含学习笔记. 开始 ...

  9. 基于JDBC的数据库连接池技术研究与应用

    引言 近年来,随着Internet/Intranet建网技术的飞速发展和在世界范围内的迅速普及,计算机 应用程序已从传统的桌面应用转到Web应用.基于B/S(Browser/Server)架构的3层开 ...

随机推荐

  1. 2.git的 分支管理

    一般我们进行提交的时候.都是在master上面提交的. git status 查看当前分支. [root@localhost jenkins_git]# git branch about * mast ...

  2. 多线程(六)多线程同步_SemaPhore信号量

    信号量依然是一种内核同步对象,它的作用在于控制共享资源的最大访问数量 例如:我们有一个服务器,为这服务器创建一个线程池,线程池有五个线程,每个线程处理1个请求.当五个线程都在处理请求时,这个线程池己到 ...

  3. thinkphp的运行

    打开cmd切换到www目录下运行think E:\wamp64\www>php think run ThinkPHP Development server is started On <h ...

  4. x1

    //程序功能: //要求客户从键盘输入一个整数,判断其是奇是偶 #include <stdio.h> int main(){ int x; printf("输入一个整数:\n&q ...

  5. Paper | Toward Convolutional Blind Denoising of Real Photographs

    目录 故事背景 建模现实噪声 CBDNet 非对称损失 数据库 实验 发表在2019 CVPR. 摘要 While deep convolutional neural networks (CNNs) ...

  6. 第01组 Beta版本演示

    目录 1.1 本组成员 1.2 工作流程.组员分工.组员工作量比例 1.3 GitHub 项目链接 1.4 本组 Beta 冲刺站立会议博客链接汇总 1.5 燃尽图 1.6 原计划.达成情况及原因分析 ...

  7. 使用k8s-prometheus-adapter实现HPA

    环境: kubernetes 1.11+/openshift3.11 自定义metric HPA原理: 首选需要注册一个apiservice(custom metrics API). 当HPA请求me ...

  8. Appium 环境配置

    前言 Appium 作为移动端自动化测试工具在业界非常流行,特别是在当前移动互联网背景下,很多公司基于此框架来开展自动化测试.但 appium 的环境配置相对 selenium 来说复杂的多,让很多同 ...

  9. matplotlib画图相关

    一. plt显示一副图像 1. import matplotlib.pyplot as plt 2. plt.figure()                    # 图像名称 3. plt.ims ...

  10. 你真的了解nginx重定向URI?-rewrite和alias指令

    未经允许不得转载!最近发现有博主转载我的文章,并没有跟我打招呼,也没有注明出处!!!! 熟悉Nginx的同学都知道Nginx可以用来做负载均衡和反向代理,非常好用.做前后端分离也是非常的方便. 今天我 ...