python的flask微服务-一次flask+redis的微服务实战

编辑推荐:

本文来自于jianshu,主要简单介绍了一个flask的app部署的环境搭建,以及各种配置的坑等相关知识。

0x00 背景

先说一下需求的场景,策划部门想做一个垂直领域的社区产品,类似与知乎那种,但受益人群是金融行业的从业人员。产品中有一个搜索问题的需求,搜索的问题去题库中进行模糊匹配,终端支持H5/APP/小程序,甚至是微信的自动回复,用过ItChat的人都知道这个强大的工具包,不过最近好像有封号的动作了。做搜索,肯定就会用到分词,当前开源的分词库jieba是做的比较好的了,分析了一下技术栈,就决定用flask来实现一个微服务,供其他的服务模块使用。

本人会着重讲一下环境的搭建,各种配置的坑。

0x01 升级操作系统

操作系统:CentOS 6.x

CentOS 7的玩家手动跳过该环节。首先6.x的版本,默认装的python的版本是2.6的版本,这个版本后面用到的一些软件支持的不是很好,所以我们首先要把python升级到2.7的版本。先创建一个update.sh脚本,然后把下面内容复制进去。

#!/usr/bin/env

bash

#安装依赖

yum install openssl openssl-devel zlib-devel gcc

-y

# apt-get install libssl-dev

# apt-get install openssl openssl-devel

# 下载源码

wget http://www.python.org/ftp/python/2.7.12/Python-2.7.12.tgz

tar -zxvf Python-2.7.12.tgz

cd Python-2.7.12

mkdir /usr/local/python2.7.12

# 开启zlib编译选项

# sed -i "467c zlib zlibmodule.c -I$(prefix)/include

-L$(exec_prefix)/lib -lz" Module/Setup

sed "467s/^#//g" Module/Setup

./configure --prefix=/usr/local/python2.7.12

make

make install

if [ $? -eq 0 ];then

echo "Python2.7.12升级完成"

else

echo "Python2.7.12升级失败,查看报错信息手动安装"

fi

cd

mv /usr/bin/python /usr/bin/python2.6.6

ln -s /usr/local/python2.7.12/bin/python2.7 /usr/bin/python

sed -i "1s/python/python2.6/g" /usr/bin/yum

wget --no-check-certificate https://bootstrap.pypa.io/get-pip.py

python get-pip.py

if [ $? -eq 0 ];then

echo "pip升级完成"

else

echo "pip安装失败,查看报错信息手动安装"

fi

rm -rf /usr/bin/pip

ln -s /usr/local/python2.7.12/bin/pip2.7 /usr/bin/pip

然后把这个脚本加上可执行的权限,并且运行。

chmod u+x update.sh

./update.sh

0x02 创建python虚拟空间

这一步完成之后,我们就开始隔离一个虚拟的空间来运行这个微服务,以后我们所有的程序都在隔离的虚拟空间中来运行,有点docker的概念,这样不管是用python2.x还是3.x都可以同时兼容了。

pip install

virtualenv

cd /home/test/web

virtualenv ENV

cd bin

source active

至此就启动了这个docker,接下来就是在这个docker中安装我们requirement.txt中所需要的包了。

我们用的包有如下:

pip install

flask

pip install jieba

pip install pymysql

pip install redis

pip install virtualenv

pip install uwsgi

pip install xlrd

到此为止就可以在ENV的环境中,测试app的功能了,现在python myapp.py试一下各接口功能。

0x03 安装nginx

尽管测试成功了,但是线上是不能这么运行的,因为flask只是一个web框架,并不是一个web server的容器,flask自带的werkzeug只能用于开发环境,不能用于生产环境,对于web服务器,我们选择更专业的uWSGI,并且配合nginx作为反向代理。

首先,我们安装nginx

yum -y install

nginx

默认的nginx的监听端口是80,如果部署在云服务器上,80端口极大的可能被占用了,我们要去修改这个配置文件。

cd /etc/nginx

vim conf.d

查看一下配置端口的配置文件在哪里,我们看到是default.conf这个文件中有端口号的配置,我们把所有端口号都改成我们想要的端口比如8100。

在 /etc/nginx/ngixn.conf 文件的 http

部分添加一条 include 内容,即最后一行

http {

include mime.types;

default_type application/octet-stream;

sendfile on;

keepalive_timeout 65;

include /etc/nginx/sites-enabled/*;

}

创建配置文件 vim /etc/nginx/sites-enabled/hello.conf

server {

# Running port

listen 8100;

# 服务器ip 或者域名

server_name 0.0.0.0;

# Proxying connections to application servers

location / {

include uwsgi_params;

uwsgi_pass 127.0.0.1:5000;//和 uWSGI 配置文件中的 ip端口一致

}

}

然后看系统中是否有nginx的service脚本

vim /etc/init.d/nginx

如果没有该脚本,在该脚本中写如下内容:

#!/bin/bash

# chkconfig: - 85 15

nginx=/usr/sbin/nginx

conf=/etc/nginx/nginx.conf

case $1 in

start)

echo -n "Starting Nginx"

$nginx -c $conf

echo " done"

;;

stop)

echo -n "Stopping Nginx"

$nginx -s stop

echo " done"

;;

test)

$nginx -t -c $conf

;;

reload)

echo -n "Reloading Nginx"

$nginx -s reload

echo " done"

;;

restart)

$0 stop

$0 start

;;

show)

ps -aux|grep nginx

;;

*)

echo -n "Usage: $0 {start|restart|reload|stop|test|show}"

;;

esac

给该文件加上可执行权限

chmod u+x nginx

service nginx start

Nginx 在 /var/log/nginx 目录下有 access.log 和 error.log

两个日志文件,如果有问题可以查看这2个日志文件。

0x04 配置uWSGI

接下来配置uWSGI的启动文件,创建 uwsgi 配置文件

vim /etc/uwsgi/apps-enabled/hello.ini

[uwsgi]

// 开启主线程

master = true

// 项目目录

base = /home/test/web

// 移动到项目目录 cd

chdir = %(base)

// 本地的ip和端口

socket = 127.0.0.1:5000

// Python 虚拟环境目录

home = %(base)/ENV

// 程序启动文件

wsgi-file = hello.py

// 项目中引用 flask 实例的变量名

callable = app

// 处理器数

processes = 2

// 线程数

threads = 4

// 获取uwsgi统计信息的服务地址

stats = 127.0.0.1:9191

保存配置文件,通过 uwsgi -i /etc/uwsgi/apps-enabled/hello.ini,来启动

uwsgi。

注意在env的环境下,uwsgi安装的目录不会在/usr/bin中,而是在ENV的bin中,所以

在后面的/etc/init.d/uwsgi中的路径要注意。

创建uWSGI的日志文件

vim /var/log/uwsgi/hello.log

创建uWSGI的service文件

vim /etc/init.d/uwsgi

#!/bin/bash

# chkconfig: - 85 15

uwsgi=/home/test/web/ENV/bin/uwsgi

hello_conf=/etc/uwsgi/apps-enabled/hello.ini

case $1 in

start)

echo -n "Starting uWsgi"

nohup $uwsgi -i $hello_conf >/var/log/uwsgi/hello.log

2>&1 &

echo " done"

;;

stop)

echo -n "Stopping uWsgi"

killall -9 uwsgi

echo " done"

;;

restart)

$0 stop

$0 start

;;

show)

ps -ef|grep uwsgi

;;

*)

echo -n "Usage: $0 {start|restart|stop|show}"

;;

esac

添加可执行属性

sudo chmod +x

/etc/init.d/uwsgi

service uwsgi start

uWSGI 在 /var/log/uwsgi 目录下有项目对应日志,有问题可以查看。

0x05 redis的安装

首先安装redis的编译工具gcc和gcc-c++

yum install

gcc gcc-c++

然后从redis的官网上下载redis并且安装

wget http://download.redis.io/releases/redis-3.2.5.tar.gz

tar -zxvf /soft/redis-3.2.5.tar.gz

cd redis-3.2.5

make & make install

然后配置redis.conf

bind 0.0.0.0

# 3.x版本,将此属性关闭

protected-mode no

添加redis的service服务

vim /etc/init.d/redis

#!/bin/sh

#

# Simple Redis init.d script conceived to work

on Linux systems

# as it does use of the /proc filesystem.

REDISPORT=6379

EXEC=/usr/local/bin/redis-server

CLIEXEC=/usr/local/bin/redis-cli

PIDFILE=/var/run/redis_${REDISPORT}.pid

CONF="/etc/redis/${REDISPORT}.conf"

case "$1" in

start)

if [ -f $PIDFILE ]

then

echo "$PIDFILE exists, process is already

running or crashed"

else

echo "Starting Redis server..."

$EXEC $CONF

fi

;;

stop)

if [ ! -f $PIDFILE ]

then

echo "$PIDFILE does not exist, process is

not running"

else

PID=$(cat $PIDFILE)

echo "Stopping ..."

$CLIEXEC -p $REDISPORT shutdown

while [ -x /proc/${PID} ]

do

echo "Waiting for Redis to shutdown ..."

sleep 1

done

echo "Redis stopped"

fi

;;

*)

echo "Please use start or stop as first argument"

;;

esac

然后启动服务

chmod u+x redis

service redis start

0x06 python中引入redis作为缓存

我们知道redis是k-v的数据缓存机制,当缓存数据为string, 或是hash类型的时候,都有原生的函数支持,具体可以参考redis的API文档。

但是当我们缓存我们自定义的实体类的时候,有点力不从心,这时候可以用pickle库来做序列化,先把实体类转换成string类型存储在redis中,取出的时候,再做反序列化的操作,具体代码如下:

#coding=utf-8

import redis

import pickle

class Redis:

@staticmethod

def connect(host="localhost", port=6379, db=0):

r = redis.StrictRedis(host, port, db)

return r

# 将内存数据二进制通过序列号转为文本流,再存入redis

@staticmethod

def set_data(r, key, data, ex=None):

r.set(pickle.dumps(key), pickle.dumps(data),

ex)

# 将文本流从redis中读取并反序列化,返回

@staticmethod

def get_data(r, key):

data = r.get(pickle.dumps(key))

if data is None:

return None

return pickle.loads(data)

0x07 总结

到此为止,一个flask的app的部署就基本完成了,中间的环节比较琐碎,但互联网上的资料也很多,基本都可以解决,祝大家玩的开心!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值