公司内部运维系统的日常开发,日常修bug,新功能上线总会遇到一个问题,线上资源变更使用者无感,或者拉取对应资源时失败抛错,体验不好。
问题来源
- bug总会出现,需要紧急修复发布上线。
- 新功能上线,需要发布。
- 用户始终不刷新,享受不到新功能或者修复。
- cookie时间设置不合理能无限长使用。
解决方案的思考
问题3、4暂时不能有效解决,毕竟用户始终是对的,后台也是对的,所以本文只对1,2做出解决的思考。问题1,2出现的原因就是资源变更了,如何更合理的通知用户成为了重点。
现有解决方案
- 多版本适应,线上会有多个版本资源都存在所以不会报错,缺点是如果用户不主动刷新重新登录无法感知新的功能。
- 轮询版本文件,主动发起版本校验,确保资源是新的,缺点会发起多次请求占用资源。
- 在特定节点发起版本校验,节省资源占用,覆盖大部分场景。
动手时间
特定节点时间: 页面切换时,长时间挂起后重新使用。
生成版本文件
因为都是ci/cd自动跑完,所以版本文件的生成采取了webpack插件生成的方式,顺便温习一下webpack机制,学习plugin如何编写。
const path = require('path')
const childProcess = require('child_process')
// 保持生成版本的便捷后续方便维持sentry上传的版本相同
const content = () => {
const release = childProcess.execSync('git rev-parse HEAD').toString().trim().substr(0, 9)
return release
}
class genVerPlugin {
apply(compiler) {
compiler.hooks.compilation.tap('GenVersionPlugin', (compilation) => {
compilation.hooks.htmlWebpackPluginAlterAssetTags.tapAsync(
'GenVersionPlugin',
(data, cb) => {
data.body.push(
{
tagName: 'script',
closeTag: true,
attributes: {
src: path.join('/version.js') //引入自执行文件可以线上查版本
}
}
)
cb(null, data)
}
)
});
compiler.hooks.emit.tapAsync('GenVersionPlugin', (compilation,callback) => {
let fileContent = content()
compilation.assets['version.js'] = {
source: () => {
return fileContent;
},
size: () => {
return Buffer.byteLength(fileContent, 'utf8');
}
};
compilation.assets['version.json'] = {
source: () => {
return `{"version": content()}`;
},
size: () => {
return Buffer.byteLength(content(), 'utf8');
}
};
callback()
})
}
}
module.exports = genVerPlugin;
复制代码
结果
-
通过vue-router全局守卫进行页面跳转请求。请求version.json文件对比现有window.__version 与远端的是否一致。 这里要注意nginx 配置 location ~/verison.json {add_header Cache-Control “no-store”}; 获取最新的文件。 更好的优化: 接入service worker 定时查询,跟着接口一起发送。
-
因为version生成策略是git commit 的hash值, 我们可以在接入的sentry 上传sourcemap 时设置相同release版本,好处是我们可以快速定位环境报错时对应线上版本。
最后
如果作者有啥不对可以留言,创作不易点个赞呗?
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END