你尚未登录,仅允许查看本站部分内容。请登录使用邀请码注册
zhoucongjun

vue + node + lumen 开发重构总结 2个回复 专栏 @ 架构

zhoucongjun 发布于 1 周前

前言

4、5月份做了一个手百积分商城项目,因为前后端用了比较新的技术(后端用lumen代替了百度老ap框架,前端使用 vue + yog2 ),项目组开发者也大都是新童鞋(双新),踩了不少坑,中间又和@三水清 老师一起重构了一次,也学到了不少东西,所以在这总结下与大家分享。如有问题希望大家帮小弟指正

项目背景

需求背景

手百中引进积分,用户通过搜索、分享、完善用户信息等任务行为,每天可以赚取一定量的积分,同时用户可以在积分商城换券或实物商品来消费积分。运营人员可以通过积分做运营活动,提升运营活动的趣味性。

产品效果体验: 打开手机百度 ==》个人中心 ==》积分
首页图效果: 图片

技术选型

对于后端,总感觉百度传统的odp ap框架使用起来有些重,最近貌似laravel lumen 框架比较流行,之前百家号使用lumen框架也积累一些公共类库,可以搬来用,再加上本次项目后端只需要提供API数据,并不需要支持web页面,故选择lumen框架。

对于前端,考虑是h5想使用前端渲染和后端渲染结合方式,于是选择了最近比较火的vue。为何不选 react呢,当然vue支持mvvm数据双向绑定,支持动画更友好这种技术区别并不是主要原因,主要原因是:其一,团队其他业务已经使用 vue + yog2(公司对node的封装),有一定的技术积累,像幻灯片等组件可以直接拿来复用;其二,总体感觉vue文档资源更全,搭建上手更快(对于双新同学而言)。

架构流程设计

模块结构图

图片
vue层: 视图, 前端交互 , 前端渲染
yog2层:请求汇总与转发, 首次请求的后端渲染
lumen: 提供数据接口,存储

图片

后端逻辑流程图

图片

泛前端逻辑流程图

这里泛前端指的是,vue + yog2部分(此为前端重构后的流程图,借用三水的图,三水妹子别打我)

图片

踩过的坑

项目中其实前后端都有很多做的很优秀的地方,比如前后端都有添加middleware(中间件)做身份校验及审核用,一些类库在不同项目间都可以复用,组件化开发,后端尝试trait技术等等。这里我不再一一阐述了,下面只介绍遇到的坑,填过的坑。以下分为:前后端共有部分, 前端部分和后端部分 逐块分析

前后端共有的问题

全局意识不够,定位问题速度及联调效率低下

  1. 后端出现面向前端页面编程的倾向, 比如 商品兑换按钮的状态button_status竟然是后端控制的,显然这种状态变量应该是前端根据登录状态及用户实际积分情况判断更合理。
  2. 很多同学是面向自己编程,缺少整体把控能力,对定位问题的敏感度低,联调效率低下。解决这种问题其实很简单,1)清楚全局数据流向,2)遇到问题,在关键地方打上日志(比如请求前后的地方),查看具体数据信息即可快速定位。

复制代码现象频繁

作为一个开发者,代码抽象能力是最基础的素养。比如,实物商品兑换和实物商品抽奖,虚拟商品兑换和虚拟商品抽奖后续交互逻辑一致,但是由于不同人开发,导致出现4个大量重复代码文件。解决方法:抽象公共方法于library,供使用方调用,把有差异的逻辑提出来兼容下。

修改后: 图片

图片

缺少严格的review机制, 入库代码质量低,变量命名不规范

由于双新问题,开发项目时间也比较紧凑,很多代码没过review,导致很多不规范代码入库。可能短期内不会有什么功能问题,但基本代码修养对程序员来说还是要求的: 图片图片
当然还有一些 变量方法命名,比如后端:getInfoById $List,显然要注意其含义的精确性。

泛前端部分(vue + yog2)

前端模块开发中,换过2个架构师,历经一次大重构,下面着重介绍前端遇到的坑及解决方法。

渲染模式冗余

  • 问题详述
    每次请求都会前端渲染+后端渲染(应该是最初开发者复制别的项目代码模块导致的),虽然短期内并不影响功能,但渲染时间可定变长了,应该针对不同请求做不同渲染处理。

  • 解决方法:后端渲染 + SPA单页应用

  • 首次请求-后端渲染:此时需要后端渲染主要HTML+页面数据,利用chunked技术,先将不依赖后端数据部分返给浏览器,页面数据和后面的HTML拿到数据后再返给浏览器。 client.tpl被「一分为二」:HTML[0] + HTML[1]
    1)将页面通用的css和js lib库,放在HTML[0]中,首先返回,浏览器先解析下载
    2)业务代码初始化代码放在HTML[1], 等到获取到后台API数据一起返回
    后端client.tpl代码 图片
    处理逻辑 chunked代码 图片
  • 非首次请求-前端渲染:这是一个单页应用的流程,用户点击链接,实际走的是vue的router,然后出发vue页面渲染,URL是通过history pushState mode更改实际URL,具体是通过vue-resource发起ajax请求,拿到数据之后commit mutation改变state。(来自三水清设计)
    注:如果强刷或者复制url在浏览器打开,就会又走 首次请求-后端渲染

请求数据接口被隐藏且琐碎

  1. yog2中间层,直接把前端的请求透传(代理)给后端,导致有多少接口并不清楚,可控性低,安全性低。
    之前代码: 图片
    修改后代码,显性API:

图片
2. 页面请求次数太多,并且一个vue文件对应了一个store模块的module,导致modules严重冗余藕合,后端接口合并后,前端文件也对应大幅度优化。 修改前的store文件结构, 图片
修改后的store文件结构, 图片

后端部分

对于后端,从设计存储(mysql redis)、预估机器资源、设计具体表和接口,总体来看还是比较合理,下面会从代码接口及细节优化方面讲述。

对lumen自带的方法没有灵活运用

lumen自带很多功能强大的API,很多同学没有看官方文档,导致很多方法自己实现了一遍,而且实现的不是很优雅。
之前代码: 图片

修改后代码: 图片

处理数据的算法缺乏长远意识导致程序鲁棒性低

  • 需求逻辑:积分变更(做任务加积分,买商品减积分)记录时,入库时只存了任务和商品id,所以前端页面若要展示记分记录时,需要根据id去商品(或任务)库匹配对应的商品(或任务)name 或图片。

  • 之前的逻辑:从商品(或任务)库取出所有的 id name img放入数组,然后根据请求的记录id,去数组内映射查出数据,最后返回给前端。

  • 存在问题:短期内没有问题,当一年以后,如果商品(任务)数量到达了几百或几千,那么很可能就会卡死在大数组这。
  • 修改后逻辑:前端分页请求积分变更记录,根据id直接去商品(任务)库取对应的信息。

修改前和修改后代码: 图片

总结

有问题不可怕,关键是要正视问题,主动暴露问题,积极去解决,这样才能成长更快!

C`est La Vie.

  • kangxiaojun

    不错啊 这基本是多数稍微大点项目的通病

    #1
  • zhoucongjun

    对啊,感觉是这样的。模块大了,参与人多了,好多问题不断出现~

    #2
登录后回复,如无账号,请使用邀请码注册