业务系统与数据库管理心得 – 记项目部署上遇到的坑

最近一直在忙一个快速上线的项目,项目策划到业务落地用了1个半月,项目稳定下来也用了近1个月,而且在这个项目也遇到许多大坑(PS:因为bug导致了项目的不少损失,还差点被炒了)。

在项目中,我们遇到了:1、代码版本管理与生产环境部署;2、业务测试版本和更新;3、数据库管理;4、缓存优化等的问题。在此我在这会讲解下我具体遇到的坑和相对应的解决方案。

一、代码版本管理与生产环境部署

代码版本管理在多人开发里是非常有必要的,项目初始只有我一个程序,所以项目全是在我本地完成的,也没有使用代码版本管理来管理代码,但是到后面项目分配了另外一位大佬一起弄的时候,代码版本管理就开始变得非常有必要了。

因为我们的是业务代码,所以代码是不能开源的,鉴于GitHub和Gitlab在国内的访问速度和私有代码库的价格,我们选择了自己部署Gitlab服务器,Gitlab服务器在网上也有挺多教程,在此就不一一叙述,我们使用的是最简易的方式,就是通过宝塔面板一键部署上去。

在此,我们就可以使用git来实现多人开发。

我在这里最想说的是生产环境部署,我一开始贪方便,没有使用git来啊进行线上环境的部署,而是直接使用压缩包扔到web环境里,这其实是一种极其傻逼的操作,希望大家千万不要模仿,而且千万不要直接在生产环境上贪方便直接更改文件,你会被项目里的其他人打死的,而且他们一旦更新服务的一些代码,意味着你的临时更改就也会消失。

我现在推崇的方式仍然是使用git部署,并且把配置文件放入.gitignore列表里,以免开发环境的配置和线上服务的配置混淆,类似的,PHP composer的vendor目录等也可以一同扔入.gitignore目录内。

这里写上最常用的几条git命令

二、业务测试版本和更新

说到生产环境的部署问题,又涉及到我那些令人窒息的傻逼操作。

业务生产部署之前需要多次测试,请不要信任自己的代码,因为它们随时会因为自己的粗心导致一些很细小的地方有一些很细小的bug,但是这些bug都有可能导致严重的损失。

我在策划的要求下,更换了支付接口,因为没想清楚订单状态值,在支付服务商回调时,理所当然地用了一个错误的订单状态值,导致回调成功但没有成功添加用户余额。这一bug直接导致了微信支付被多次举报,被冻结了。

这次教训之后,我们就开始着手完善业务系统测试制度,每次代码更新后,先更新到测试服,让测试人员进行完全流程的测试,然后确认没问题后再更新到正式生产环境。

测试在业务部署中是一个非常容易被遗忘的但非常重要的一个环节,请各位同学千万不能怠慢这个环节。测试做好了,代码健壮了,业务才能得以正常发展。

三、数据库管理

很多小项目的业务环境应该是lnmp都部署在同一台服务器上,但这种环境配置的可用性是非常低的。特别是在服务器挂掉后,你有可能连数据库的数据都无法取出。因此,我觉得业务环境最基本要做的就是把数据库与web服务端分离出去,让数据库在一台独立的服务器上运行,以便在一台web服务器挂掉后能保住数据并快速切换到备用站点。

由于项目组里没有专业的DBA,我们直接将数据库上云,部署到阿里云的RDS数据库上。因为阿里云的高可用性和有专业的运维、专业的备份系统。数据库部署到阿里云后,开发和运维人员不需要过度注意数据库,只需要在阿里云的管理台上简单地操作即可实现备份、数据库安全策略管理、数据库扩容。

举个例子,我们项目在开始阶段时,服务器不稳定,经常挂掉,幸好在另外一位开发的建议下,数据库上云,才得以在一次服务器宕机后及时切换到备用源站。

其实这里真的不是说吹阿里云,而是在小项目里,把数据库托管到云计算平台是一种最节省资源、最安心的做法。

 

关于数据库网络瓶颈

在我们把数据库托管到阿里云后,我们的web服务器仍然是托管在其他私有机房的。这种情况下,web服务端与数据库的连接会通过公网进行,这就直接导致了一个非常严重的瓶颈。

在加载非常大量的数据的情况下,页面渲染会长达1-3秒,这就大大影响了用户体验。在这种瓶颈下,我们讨论后认为使用Redis对一些不长更改的数据进行缓存。

在Laravel下,把Cache驱动改为Redis后,能很方便地使用tags方法分类和remember方法进行缓存数据。

Remember方法的三个参数分别为[key]、[缓存时间(分钟)]、[闭包函数]。Remember方法会自动检测key对应的value是否存在,,若存在会直接返回缓存数据;若不存在,会执行闭包函数,并缓存闭包函数return的值。

值得一提的是,Laravel的cache在缓存一个数组或者是对象的时候,会反序列化并缓存反序列化后的字符串内容,并在取出缓存的时候自动序列化为一个数组或者对象,所以在很多场景下,你可以直接缓存整个Eloquent Model,例如

这样就可以很方便的就把一个activity对象缓存了下来,不需要繁杂的判断和其他处理。

其次就是你可以为这个对象的缓存使用tags打下标签(分类),在有需要的情境下,直接把这个分类下的所有对象的缓存销毁。

分享到:

2 条评论

昵称
  1. 大学生暑假兼职

    做项目就是不断积累经验的过程

    1. Y2Nk4

      是滴,所以记录下来让大家也少遇些坑