毕设的一部分是做一个微信小程序。需要公网IP,因此需要购买云服务器,并且申请域名。正赶上华为云搞活动,结结实实的薅了一把羊毛。(华为云操作教程参考我的另一篇博客:。当然希望大家货比三家,看看哪个平台性价比高买哪个。)
后端小白经过摸索,终于完成了小程序的后台搭建,并做了一个小小的微信小程序demo。下面将详细记录整个搭建流程。
一、华为云端口放通
注意:若购买的腾讯云服务,是不需要这一步骤的。腾讯云是默认放通的,无需操作。但迁移到华为云之后,发现其他主机ping不通华为云(ICMP未通),并且无法访问域名(默认的80端口未开通)。因此需要手动放通端口才行。
1. 打开“控制台”——“弹性云服务器”,界面如下。点击服务名称进入。
2. 更改安全组规则
3. 选择“入方向规则”,将协议端口一键放通。
二、后台搭建
参考链接:https://cloud.tencent.com/developer/article/1453563 (参考链接的有些步骤可以省略,具体请往下看)
1.准备域名、SSL证书、服务器
准备域名、SSL证书、服务器。在华为云的控制台添加解析记录。这一步骤不再详述。
2. 配置反向代理
(1)安装 Nginx
利用Nginx作为反向代理,搭建https服务。
在 Ubuntu 上,可直接使用 apt-get
来安装 Nginx
sudo apt-get install nginx -y
安装完成后,使用 nginx
命令启动 Nginx:
sudo /etc/init.d/nginx start
此时访问 华为云的公网IP 可以看到 Nginx 测试页面
(2)配置 HTTPS 反向代理
修改 /etc/nginx 目录的读写权限
sudo chmod a+rw /etc/nginx
将之前下载的 SSL 证书(解压后 Nginx 目录分别以 crt 和 key 作为后缀的文件)通过拖动到左侧文件浏览器 /etc/nginx 目录
的方式来上传文件到服务器上。
如何上传 SSL 证书到 /etc/nginx 目录
在 /etc/nginx/conf.d 目录创建 ssl.conf 文件
cd /etc/nginx/conf.d
sudo touch ssl.conf
sudo chmod a+rw ssl.conf
将 ssl.conf 文件修改为如下内容
示例代码:/etc/nginx/conf.d/ssl.conf
server {
listen 443; #监听443端口,这个是ssl访问端口
server_name www.sybil-chocolate.cn; # 改为绑定证书的域名
# ssl 配置
ssl on;
ssl_certificate 1_www.sybil-chocolate.cn_bundle.crt; # 改为自己申请得到的 crt 文件的名称
ssl_certificate_key 2_www.sybil-chocolate.cn.key; # 改为自己申请得到的 key 文件的名称
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://127.0.0.1:5000; #默认端口为5000.可以根据flask后台做对应修改。
}
}
server{
listen 80; # 80端口是http正常访问的接口
server_name www.sybil-chocolate.cn;
rewrite ^(.*) https://$host$1 permanent; # https全加密处理,在访问http的时候自动跳转到https
}
按 Ctrl + S
保存配置文件,让 Nginx 重新加载配置使其生效:
sudo nginx -s reload
此时,访问绑定的域名 www.example.com,应该可以看到如下结果,表示反向代理设置成功。但还没有启动后台程序,因此返回502。
3. 基于Flask搭建后台服务
由于我们的程序是python语言编写,因此选用了flask框架作为我们的后端框架。以最简单的hello world 为例。
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, World!'
if __name__ == '__main__':
# app.run('127.0.0.1', port=5000, debug=True)
app.run(debug=True) //默认为 127.0.0.1:5000, 可以进行修改
若没有上述的反向代理配置过程,在浏览器中输入 127.0.0.1:5000, 即可在页面中显示 “hello world”了。但只能在当前主机访问。
配置了反向代理之后,浏览器中输入域名 https://www.example.com,可达到同样的显示效果,可供所有人访问。
至此,最naive的后台搭建成功。
4. Gunicorn+gevent配置
作为一个轻量级的后端框架,Flask仅完成接收请求并返回执行结果的过程。但是用于生产环境无论是处理高并发还是鲁棒性都有所欠缺,一般会配合WGSI容器来进行生产环境的部署。gunicorn结合gevent,是一种比较常用的部署方式。
(1)安装gunicorn和gevent
pip install gunicorn
pip install gevent
(2)启动gunicorn
简单地,gunicorn可以通过
gunicorn -w 4 -b 127.0.0.1:5000 test:app
启动一个Flask应用。其中,
-
-w 4
是指预定义的工作进程数为4, -
-b 127.0.0.1:5000
指绑定地址和端口 - test是flask所在的python文件,app则是flask应用程序实例
(3)gunicorn配置文件
gunicorn有非常多的配置项,因此通常会写成一个配置文件来进行配置。我所用项目的配置项如下:
# 并行工作进程数
workers = 3
# 指定每个工作者的线程数
threads = 1
# 监听内网端口5000
bind = '127.0.0.1:5000'
# 设置守护进程,将进程交给supervisor管理
daemon = 'true'
# 工作模式协程
worker_class = 'gevent'
# 设置最大并发量
worker_connections = 2000
# 设置进程文件目录
pidfile = '/var/run/gunicorn.pid'
# 设置访问日志和错误信息日志路径
accesslog = 'log/gunicorn_acess.log'
errorlog = 'log/gunicorn_info.log'
# 设置日志记录水平
loglevel = 'info'
这样,可以将gunicorn的日志输出至 log/gunicorn_info.log 中,便于查看。若只想打印报错信息,只需修改loglevel = 'error'即可。
(4)合并Flask和gunicorn的日志输出
参考链接:https://zhuanlan.zhihu.com/p/36909560
我的路由入口代码如下:
@app.route('/vectorization', methods=['POST'])
def vectorization():
app.logger.info('Vectorization Start!')
img = request.files.get('file')
img_path = images_path + "cartoon/" + time.strftime('%Y%m%d_%H-%M-%S_', time.localtime(time.time())) + str(round(round(random.random(),4)*10000)) + ".png"
img.save(img_path)
seg_path=img_path.replace(".png","_s.png")
sketch_path=img_path.replace(".png","_t.png")
svg_path=img_path.replace(".png","_svg.svg")
gen_svg(img_path,seg_path,sketch_path,svg_path)
app.logger.info("img_path:"+img_path+'\n'+"svg_path:"+svg_path)
app.logger.info('Vectorization Succeed!')
return svg_path.replace(images_path,"")
该文件中添加如下语句:
if __name__ != '__main__':
gunicorn_logger = logging.getLogger('gunicorn.error')
app.logger.handlers = gunicorn_logger.handlers
app.logger.setLevel(gunicorn_logger.level)
如此即可将Flask的日志也打印至 log/gunicorn_info.log中。如下:
[2019-12-09 19:16:13 +0800] [9225] [INFO] Starting gunicorn 19.4.5
[2019-12-09 19:16:13 +0800] [9225] [INFO] Listening at: http://127.0.0.1:5000 (9225)
[2019-12-09 19:16:13 +0800] [9225] [INFO] Using worker: gevent
[2019-12-09 19:16:13 +0800] [9228] [INFO] Booting worker with pid: 9228
[2019-12-09 19:18:01 +0800] [9228] [INFO] Parent changed, shutting down: <Worker 9228>
[2019-12-09 19:18:01 +0800] [9228] [INFO] Worker exiting (pid: 9228)
[2019-12-09 19:18:04 +0800] [10011] [INFO] Starting gunicorn 19.4.5
[2019-12-09 19:18:04 +0800] [10011] [INFO] Listening at: http://127.0.0.1:5000 (10011)
[2019-12-09 19:18:04 +0800] [10011] [INFO] Using worker: gevent
[2019-12-09 19:18:04 +0800] [10014] [INFO] Booting worker with pid: 10014
[2019-12-09 19:18:09 +0800] [10014] [INFO] Vectorization Start!
[2019-12-09 19:18:11 +0800] [10014] [INFO] img_path:/root/Vec_Server/static/cartoon/20191209_19-18-09_8533.png
svg_path:/root/Vec_Server/static/cartoon/20191209_19-18-09_8533_svg.svg
[2019-12-09 19:18:11 +0800] [10014] [INFO] Vectorization Succeed!
[2019-12-09 22:06:26 +0800] [10014] [INFO] Vectorization Start!
[2019-12-09 22:06:29 +0800] [10014] [INFO] img_path:/root/Vec_Server/static/cartoon/20191209_22-06-26_792.png
svg_path:/root/Vec_Server/static/cartoon/20191209_22-06-26_792_svg.svg
[2019-12-09 22:06:29 +0800] [10014] [INFO] Vectorization Succeed!
至此,完整的微信小程序后端搭建完毕。
三、小程序部署
笔者的小程序实现的功能为:拍照或从相册中选择图像,上传至服务器,进行图像风格化,并将风格化后的图像在小程序端展示,并提供保存功能。
目前小程序仍在制作中,完成后会release小程序端和客户端的关键代码。