其他
基于模块联邦与大仓模式的商家巨石应用拆分实践|得物技术
一
背景
代码构建体量大,随着时间推移,构建速度的优化空间较少。 巨石应用下各个业务模块没有做物理拆分,管理与维护难度提升。 应用粒度较粗,在发布节点上需要对应用做进一步拆分以优化发布粒度。 巨石应用下,组件与业务的关系需要梳理,避免出现重复开发的情况。
二
目标
提升构建与维护效率
虽是单个子应用开发,但可全量访问巨石应用模块
由于商家内部各应用间在业务上存在上下游的关系,我们在开发D子应用时,需要在其上游的C、B子应用中进行相关配置,它们之间是强绑定的关系,结论就是:需要在本地开发时,能够同时使用其他子应用的页面模块的功能。
三
技术方案
微应用代理
用户首次进入线上测试环境,会加载远程应用入口文件,代理插件会将入口文件根据用户配置转发至对应的本地地址。 进入路由访问,由于上一步对远程应用入口做了代理,加载的模块被代理至本地,这样用户就可以在线上访问到本地页面,实现本地开发。 在线上基座应用与本地应用间建立websocket链接,本地应用代码更改后通知线上基座应用刷新页面。
generateRedirectUrl = (details: UrlDetailsType) => {
if (details.url.includes(MICRO_ONLINE_LOAD_PATH)) {
const redirectUrl = this.generateDefaultProxyUrl({ originUrl: details.url })
if (redirectUrl) {
console.log('触发代理', `${details.url}代理至${redirectUrl}`)
this.checkMicroAppStatus({ originUrl: details.url, redirectUrl })
return {
redirectUrl,
}
}
}
if (details.url.includes('t1-dev.dewu.net:98')) {
console.log("details.url.includes('t1-dev.dewu.net:98')", details.url);
const redirectUrl = this.generateOnlineUrlByLocal({ originUrl: details.url })
if (redirectUrl) {
console.log('触发代理', `${details.url}代理至${redirectUrl}`)
this.checkMicroAppStatus({ originUrl: details.url, redirectUrl })
return {
redirectUrl,
}
}
}
}
文件内容代理为本地文件后,此时对应的模块加载path还是会加载线上路由,这里同样需要做内容代理。 由于是基于线上测试环境开发,本地开发的页面不仅需要在线上展示,并且本地代码更新后需要触发线上页面更新,这是必不可少的步骤,我们基于websocket将本地与线上进行连接。 不同子应用动态设置socketUrl与PingUrl。
function getHost() {
if (process.env.SOCKET_SERVER) {
return new URL(process.env.SOCKET_SERVER);
}
return location;
}
function getSocketUrl() {
let h = getHost();
let host = h.host;
host = `localhost:${PORT}`;
const isHttps = h.protocol === 'https:';
return `ws://${host}`;
}
function getPingUrl() {
const h = getHost();
return `${h.protocol}//${h.host}/__umi_ping`;
}
let pingTimer = null;
let isFirstCompilation = true;
let mostRecentCompilationHash = null;
let hasCompileErrors = false;
let hadRuntimeError = false;
const pingUrl = getPingUrl();
if (!window[`${APP_NAME}UmiEntry`]) {
const socket = new WebSocket(getSocketUrl(), 'webpack-hmr');
socket.addEventListener('message', ({ data }) =>
__awaiter(void 0, void 0, void 0, function* () {
data = JSON.parse(data);
if (data.type === 'connected') {
console.log(`[webpack] connected.`);
// proxy(nginx, docker) hmr ws maybe caused timeout,
// so send ping package let ws keep alive.
pingTimer = setInterval(() => socket.send('ping'), 30000);
} else {
handleMessage(data).catch(console.error);
}
}),
);
}
本地需求开发共享部署态代码的store与路由跳转。 需求开发完成后进行单个应用部署,由于是本地代理,不影响测试访问。
基于模块联邦
本地与部署态基座应用通过MF方案加载子应用,同时部署态新增动态加载保证远程组件的实时性,在加载入口文件处进行监控告警。
效果
四
应用拆分
大仓模式
大仓模块化共享
组件构建发布使用标准的cli规范。 在提交MR节点与发布节点新增自动化卡口。 通过依赖分析自动化检测单测运行范围。 组件发布时发布通知,提醒组件使用者,并运行业务单测。
五
总结与思考
单应用构建->单页面构建?
*文/天意
关注得物技术,每周一、三、五更新技术干货
要是觉得文章对你有帮助的话,欢迎评论转发点赞~
未经得物技术许可严禁转载,否则依法追究法律责任。
“
扫码添加小助手微信
如有任何疑问,或想要了解更多技术资讯,请添加小助手微信:
线下活动推荐
主题:得物技术沙龙-中间件专场
时间:2023年8月27日(周日)14:00-18:00
地点:上海·杨浦区黄兴路221号互联宝地C2栋5楼培训教室(宁国路地铁站1号口)
活动亮点:本次中间件专场沙龙由得物技术出品,聚焦于行业最新的技术趋势和实践,将在上海(线上同步直播)为你带来四个令人期待的演讲话题:
1. 《得物蓝绿发布演进和落地》
2. 《基于istio的Service Mesh落地实践》
3. 《Apache Pulsar -- 金融级云原生消息平台》
4. 《得物DLB演进之路》
相信这些话题将对你的工作和学习有所帮助,我们期待着与你共同探讨这些令人兴奋的思考和实践。欢迎线下参与,如果没办法到现场,也可以锁定我们的“得物Tech”视频号哦~
快快点击下面图片报名吧~