2018年末,我做了一个计划:成为小程序服务商,开发微商城saas平台解决方案,为线下商家提供微商城服务。截止到2019年中旬,提供的系统和小程序,线上可正常使用。现在已经到2021年末了,回想半年间独立作战,我觉得有必要留下一些痕迹。
saas,软件即服务,向客户提供基于互联 的软件服务。
了解什么是saas,我认为需回答如下几个问题:
- 为谁提供服务li>
客户,即服务购买者,如企业、机构、个人等。
- 提供什么服务li>
基于互联 ,对某种业务的赋能;2c与2b的完整系统;
- 面临的重点li>
上云,基于互联 的软件服务;
数据隔离,客户拥有数据私域;
效期、计费、增值服务等;
业务流程个性化;
- 对比传统软件服务,saas突出的优势是什么li>
无需客户侧部署,投入成本低。无需前期投入,客户不用准备软件系统部署所需的软硬件设备,客户不需部署软件系统;无需维护投入;
目录
1. 微商城生态
2. 抽象软件架构
3. 详细软件架构
4. 代码
1. 微商城生态
微商城即微信小程序商城。对于商家而言,付出很低的成本,就可以拥有数字化的云线上商城。通过各种运营方式,商家可以拥有并维护属于自己的私域用户。借住微商城提供的数据统计与分析能力,商家可以有理有据的采取运营决策。为了满足这种场景,我认为微商城生态需要具有的能力包括但不限于2c商城基础能力(展示重点内容的首页能力、多类目能力、商品能力、预售能力、限购能力、优惠券/优惠活动能力、购物车能力、订单能力、支付能力、交付能力等)、商城管理能力(PC端综合管理后台、商城管理小程序)、线下支持能力(如线下支付、线下核销)、 交获客能力、导购推广能力、微信群维护能力、其他能力(如类佣金能力、类返现能力、类抽奖能力)。
接下来,结合我提供的微商城解决方案,说说我在设计方面做的事情。
2. 抽象软件架构
2.1. 抽象业务模型
列举业务中涉及的事物,进行分类与抽象,彼此间只存在单向依赖。
- 商品:类目、商品、SKU、预售、限购等
- 优惠活动:各种各样的店铺优惠活动
- 优惠券:店铺优惠券、会员优惠券
- 会员:店铺会员
- 购物车
- 订单:商品订单、支付单、交付单
- 分享: 交获客、导购推广
- 佣金:导购佣金、会员积分
- 微信:微信小程序相关接口、微信支付相关接口
- 活码:微信群二维码维护
2.2. 系统模型
抽象业务模型可以作为单独模块或者单独系统,接下来,我使用连线以表示模型彼此之间存在的业务关系。
3. 详细软件架构
3.1. 逻辑架构
3.2. 部署拓扑
考虑前期数据量、访问量、成本之后,我认为两台2核4G的云服务器能满足要求。下图为系统部署拓扑图,如图可见,均使用docker容器,使用Nginx作为路由,使用zimg作为图片服务器,2C系统承担所有小程序的请求,配置端口访问白名单。
3.3. 选型
存储方面
- 数据库:mysql
- nosql存储:redis
- 图片存储:zimg
工程方面:
- rpc:考虑多个web项目均需要使用service,需service单独部署,选用dubbo。
- spring:spring boot、spring mvc、spring redis等
- 消息:不存在冗长且同步的业务流程,暂不需要使用消息进行解耦。
- 数据库连接池:druid
- 持久层框架:mybatis
- Mybatis相关工具:tkmybatis、pagehelper
- 数据验证:validation
- Json:fastjson
- 工具包:commons
- Redis客户端:lettuce
后台前端:
- Vue、jquery、bootstrap、datatables、datetimepicker、amazeui、jquery.fileupload等
微信小程序:
- 一期采用webview加载html
- 前端框架涉及Vue(学习成本较低,高效简洁的完成js与html间交互)、jquery(处理与数据模型无关的事件,ajax,其他)、sui(学习成本低,UI组件可满足移动端H5页面)
- 二期使用小程序组件
运维部署:
- 路由:nginx
- 容器:docker
- 域名:云平台购买
- 云服务器:云平台购买
- CA证书:自己生成证书无法满足微信场景,所以需在云平台购买。
3.4. 数据模型设计
由于商城支持多商户、多店铺,所以店铺维度的数据表必须有店铺ID字段,这样可以达到数据隔离的目的。
数据表包括但不限于:
- 店铺与上传图片关系表
- 店铺已上传图片汇总信息表
- 商户用户表
- 店铺表
- 商户用户-店铺关系表
- 店铺-增值能力表
- 店铺与授权app关联表
- 店铺类目表
- 店铺商品信息表
- 店铺商品SKU信息表
- 店铺销售策略表
- 店铺主订单表
- 店铺商品子订单表
- 店铺支付单表
- 店铺退款单表
- 店铺会员表
- 店铺会员收货信息表
- 订单交付信息表
- 店铺活动信息表
- 店铺优惠信息表
- 用户获取的优惠券信息表
- 店铺限流配置表
- 佣金规则表
- 订单维度佣金表
……
3.5. 包结构
无论service、web工程、前端,均按照抽象业务模型构建package。
3.6. 详细设计
3.6.1. 管理后台前端/小程序前端
- 前后端分离;
- 规范前端页面主体结构;
- 交互规范,依据交互规范封装工具包以简化代码和提高开发效率;
- 提供统一样式文件;
- 自定义组件;
3.6.2. 主要功能设计
购物车
如何实现span>
不单独提供数据表,使用redis作为持久化存储。采用hash数据结构,使用shopId和userId组装成key,使用itemId和skuId组成成field,val存储对应的数量。
为什么这么做span>
考虑快速实现数量的增减,redis可以作为持久存储,购物车条目的顺序不重要。
订单
用户购买商品后产生的订单由主订单和子订单构成,主订单是商铺和用户维度,子订单是商铺+用户+商品+sku维度。
店铺活动
如何判断商品是否参加活动span>
使用redis set存储活动与参与商品的关系,即店铺ID和活动ID构成key,参加活动的商品ID作为集合成员。所以可快速判断商品是否参加活动。优惠券采用同样的实现方式。
下单时,如何选择出优惠最优的活动span>
可以简述为3个步骤:
- 当前有效的店铺活动集合
- 订单中参与某个活动的所有商品对应的子订单总金额,根据活动规则计算优惠金额,当前活动是否最优
- 若还有未处理活动,则重复2
优惠券采用同样的实现方式。
增值服务
作为提供微商城解决方案的服务商,必然要求商户可占用的资源和购买套餐的关系。例如图片空间限制、每日访问量的限制、每日/每月/总订单量的限制等。
那么我是实现这种限制的呢span>
首先使用一个限流配置表存储店铺各种限制的信息,如限制类型、最大值、循环周期、记录有效期。再者基于redis实现计数和比较并提供服务接口。限流服务可以在拦截器中使用,也可以在需要的地方调用。
使用cache提升性能
常规实现方式为:从数据库中读出的数据放到redis中,下次直接从redis读取,这样即可提升读性能。这种方式存在一些问题,如如何选择合适的cache有效期、cache超时后并发读数据等。
针对场景,我选择另一种cache实现方式:数据变更后放入cache,读数据直接从cache取。
3.6.4. 主要时序图
微信与微商城交互时序图
商户绑定小程序的时序图
3.6.5. 其他图示
3.7. 运维部署
3.7.1. nginx部署
需要满足如下要求:
- 据域名将请求路由到不同应用(IP:端口)
- 支持https、CA证书
3.7.2. 镜像与容器
- 安装docker
- 运行docker镜像vsftpd
- 运行docker镜像mysql
- 运行docker镜像redis
- 运行docker镜像zookeeper
- 运行docker镜像zimg
- 运行docker镜像nginx
- 构建与运行应用docker镜像
以上内容涉及了从架构设计到简单运维部署的过程,希望读者能有收获。
4. 代码
4.1. 小程序的代码
4.2. 服务端代码
由于我的数据库、redis之类还在使用中,暂时不开源了。
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!