奶油葡萄重构(一)

重构原因

想要重构的心思很早就有了,只是因为种种原因搁置了。虽然现在站点的日活不如从前,不过负载倒比以前高不少。琢磨了下我用 Docker Swarm 自建的「云」,觉得是时候改造一波了。

重构方向

如果把重构目标划分近期、远期、终极目标的话,我认为近期目标应该是微服务化,能够「上云」,提高服务能力。远期目标的重点是前后端分离,终极目标应该是完全去中心化。

远期其实说远也不远,近期目标实现之后,就可以逐步尝试基于 Laravel 和 Vue 再次重构。当然,本文主要还是讲近期的重构计划和实现思路,先来说说具体的行动项:

代码适配 PHP 7:都已经 9102 年了,也该充分利用下 PHP 7 的优势了,再结合下 OPcache,将性能发挥到极致。

改用 Redis 作数据缓存:目前主流的数据缓存基本都用到 Redis,争取紧跟潮流

文件存储改用云存储:微服务化之后,所有长期的文件存储都应中心化存储,每个服务节点缓存部分热数据

Docker 镜像与容器:编写 Dockerfile 将所有依赖的环境打包在一个镜像中,随时 pull 即可运行

实现思路

PHP 7

从 5.4.x 升级至 7.x.x,关键在于 mysql 函数的调整和一些过时方法的重构。PHP 7 版本可以使用 mysqli 或者 PDO 进行数据库操作,但考虑到迁移成本,此处我选择 mysqli。

mysql 和 mysqli 都是 PHP 用于操作数据库的函数集,mysqli 是在 PHP 5 之后出现在,相当于 mysql 的增强版,更稳定、高效和安全,还提供了面向对象的数据库操作方式。

mysql 和 mysqli 的主要区别在于 mysql 是非持续连接函数集,每次操作都会打开一个连接进程,而 mysqli 多次运行使用同一连接进程,能够减少服务器的开销。

NexusPHP 的 functions.php 中定义了一个 dbconn 方法,在执行需要操作数据库的脚本之前,均会调用一次该方法,进行数据库连接等操作。改造之后,我在 core.php 文件中,定义了一个全局变量 DB_CONN,然后在 dbconn 方法新建数据库连接并赋值。

原生代码大量使用了 mysql_** 等方法,为了方便重构,我在 globalfunctions.php 中定义了若干 sql_** 的方法,实现相应的功能,然后 PHPStorm 批量替换一波便大功告成。剩下就是把 debug 开启,然后哪里报错改哪里。

Redis

原来的 Cache 类是继承的原生 Memcache 类,代码在 class_cache.php 这个文件中。为了改用 Redis,我引入了 predis 这个库,可以很方便地连接 Redis 进行一系列操作。

需要注意的是,Memcache 是可以直接存储读取数组内容的,而 predis 提供的普通 setex 方法不行,需要通过操作哈希表实现。为了简化代码,在调用 predis 的 setex 的方法时,先将存储内容 json_encode 为字符串之后再存储。相应地,取出来之后先使用 json_decode 转换一遍之后再返回。

云存储

之前在开发图床 ImageX 的时候,有使用到 B2 这个便宜好用的云存储服务商,我现在有大概 20 GB 的图片存放在 B2 上,每个月的费用才 0.1 刀左右,具体价格大家有兴趣可以到 官网 看看。

实现思路和 ImageX 类似,文件存储均放在 B2 上,本地仅保留近期热门数据,感兴趣的可以围观下之前的文章:开源图床 ImageX 介绍