前言

由于积攒太多,不得不唠叨下。

作为App开发人员,时常有种缺乏控制的感觉,特别是长时间编写交互性弱的App时,会觉得只是在单纯地展示数据,而数据并不是客户端能够控制的,因为缺少数据输入的客户端,基本不生产数据。在写CAWReader时,也有这种感受,虽然服务端折腾了很多数据,但客户端只是单纯地获取数据(这还是主动权在自己手上的时候),最近碰上要接入已有数据的时候,感觉整个人都POI了,已有的数据根本不适合移动客户端接入,但最后还是强行接入了。如果一开始的数据结构设计就有问题的话,后期的持续开发基本就不可能了。

为了能够拥有自己的API服务器,学习了很多新的东西,也下了很多功夫。然而越是不断学习,越感觉到想要写下一些通用的小技巧是不太可能的。通常只能通过教程配置并运行起来一个软件,然后才能慢慢熟悉它的其他功能。以自己为例,之前一直想把搬瓦工的服务器系统升级到64位版本,这样就可以搭建GitLab服务端了,然而每次都有原因放弃,或者在升级后,恢复原来系统中的某些软件时失败掉,最后总是回退到一个32位版本的稳定快照中,所以快照真的很重要,在保证不了性能和安全的情况下,至少先保证好功能。在经过一番折腾后,在迁移到64位后,在将全部的软件环境复原后,却发现内存不够了。毕设时翻译64位迁移指南时,就知道迁移到64位后,最大的问题,无非是内存占用增加和一些数据大小越界会引起错误,但没想到迁移后,内存占用还是十分严重的,给出两个数据。

我的搬瓦工配置为CPU  Xeon X5650 @ 2.67GHz(使用率受限),512MB内存,64MB Swap,5GB存储,500GB流量,OpenVZ虚拟化方案,内核无法升级,停留在2.6,除了流量用不完外,其他基本都很捉急。

现在主要运行的软件有Nginx,PHP-FPM,MySQL,Wordpress,StrongSwan,Shadowsocks,这些软件都使用系统和软件默认提供的。32位系统下,内存占用均值不超过100MB,也没有使用交换空间,CPU占用率也可以忽视。但是在64位系统下配合64位软件时,交换空间完全爆满,内存占用也是从256MB起步,并时常爆满,主要原因是MySQL,其他软件的资源消耗量也有所提升,系统不稳定的话,提供服务就很有问题了。

因为阿里云的免费虚拟主机就要在明年一月底到期了(此外阿里云还提供了邮件服务,不过貌似只要域名不过期,就能够一直使用邮件服务),所以必须考虑迁移博客了,国内的VPS和虚拟主机的价格都可以在国外买一个中高配置的VPS,所以综合考虑,还是搬到搬瓦工上去,由于是自己的VPS,还可以配置HTTPS来加固下网站。因此必须将搬瓦工的VPS打造成一个可靠的VPS,此外还应该能过满足下开发需求。

唠叨结束,接下是这篇文章的内容了。

1.配置HTTPS

2.Flask+FastCGI+Nginx+MySQL

服务端API的想法是用Nginx来管理HTTPS,包括博客和API,还可以自定义加密算法,提高安全性,对请求的处理使用FastCGI转发给Flask处理,将响应传递给Nginx后返回给客户端。

正文

免费的HTTPS证书使用StartSSL提供,Class 1的证书只要求国家对上号,其余的信息都可以缺省。StartSSL证书的有效期有1年时间,比Let’s Encrypt要长一些,只是2013年那段时间,部分使用了StartSSL的Class 1证书的网站被墙了,后来倒是没有什么新的消息,只是风险还是有的,特别是在国外注册,又在国内没有备案的域名。

StartSSL使用证书登陆,注册后会要求客户端安装登陆证书,有效期为1年,只是撤销证书需要付费9.9美金,感觉有点奇怪。在填写基本信息后(最好如实填写吧,或者编的好一点),就可以开始配置证书,流程如下:

1.验证域名

选择域名验证

validate1

选择验证方式

validate2

验证域名

validate3

这个步骤为的是验证你是域名的所有者,可以选择邮箱验证(这个需要你已经配置好域名邮箱),或者控制权验证(这个需要你已经做好域名解析,并将验证文件上传到域名对应文件夹的根目录)

2.证书生成

在Certificates Wizard中选择 Web Server SSL/TLS Certificate

certwizard1

接下来选择一个已经验证的域名,然后最多填入5个主机名,其中第一个会作为证书公用名,如果只为一个主机名申请一个证书,那么只填写一个,如果要为多个主机名进行配置,例如wbuntu.com以及blog.wbuntu.com等,那么应该将wbuntu.com作为证书公用名,不同主机名之间以回车或逗号分隔。

certwizard2

这一步首先需要生成一个私钥,然后用私钥生成一个CSR(Certificate Signing Request),可以使用openssl生成

openssl genrsa -out privateKey.pem 2048
openssl req -new -key privateKey.pem -out privateKey.csr

第一条命令生成私钥(私钥后缀也可以改为privateKey.key),第二条生成CSR,这两个文件最后都要上传到服务器上。使用cat命令输出csr内容,然后复制粘贴到输入框中。

certwizard3

完成后,可以在ToolBox-> Certificate List中查看到证书

certwizard4

3.Nginx配置

下载证书解压后,可以看到有针对不同网页服务器的证书,选NginxServer.zip,解压后获得一个domainName.crt文件,和privateKey.pem一起上传到服务器。

Nginx采用最新稳定版,可以按照官方指南安装:Nginx_LinuxPackages

WordPress的HTTPS配置,可以参照官方指南:WordPress

对于Nginx,需要将对API的80端口请求转到443端口,然后在443端口的配置中设置SSL相关内容,在/etc/nginx/conf.d/default.conf中配置如下。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
server {
    listen 80;
    server_name api.wbuntu.com;
    return 301 https://$server_name$request_uri;
}
server
{
    listen  443 http2;
    server_name api.wbuntu.com;
    ssl on;
    ssl_certificate /etc/ssl/certs/domainName.crt;
    ssl_certificate_key /etc/ssl/private/privateKey.pem;
    ssl_prefer_server_ciphers on;
    ssl_dhparam /etc/ssl/dhparam.pem;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4";
    keepalive_timeout 70;
    ssl_session_cache shared:SSL:10m;
    location /
    {
      fastcgi_pass  127.0.0.1:8008;
      include fastcgi_params;
    }
}

为了增强安全性,除了HTTPS外,这里额外增加一个dhparam.pem文件,采用服务端选择的加密算法,使用更强的DHE参数,生成的命令如下

1
openssl dhparam -out dhparam.pem 2048

然后上传到服务器。

4.uWSGI+Flask

将CAWProject/CAWServer/PythonServer下的两个文件复制到一个文件夹下,在该文件夹中新建一个fcgi.py文件,内容如下,确保运行地址与Nginx中proxy_pass中的参数一致。

1
2
3
4
5
6
7
8
#!/usr/bin/python
# encoding : utf-8

from flup.server.fcgi import WSGIServer
from CAWServer import app

if __name__  == '__main__':
   WSGIServer(app,bindAddress=('127.0.0.1',8008)).run()

确保已经将CAWProject/CAWServer/Data文件中的test.sql中的数据存入了数据库,然后运行fcgi.py

python fcgi.py

访问http://api.wbuntu.com/discover

会发现跳转到https://api.wbuntu.com/discover,并获得一个长长的字符串,到此为止,配置完成,同样,可以使用supervisor来管理fcgi.py的启动和重启,接下里就是继续开发新功能或者增加一些额外的性能与安全优化了。

其他:python版本为2.7,使用pip安装了flask,Flask-MySQLdb,Flask-RESTful,Flask-SQLAlchemy,flup等,如果运行出现错误,一般是由于缺失了某些包。

5.使用supervisor管理应用

在之前的shadowsocks配置中,就有使用supervisor的例子,目前服务端还十分脆弱,如果在哪搜索文本中加入emoji表情,就足以导致程序崩溃,所以可以使用supervisor来管理应用启动,让应用在崩溃时自动重启需要注意的是python路径和执行的py文件路径都应该写成绝对路径,防止在微读取到PATH前,执行命令错误错误。