由于公司业务主要是2B的SAAS平台,自己也是初次进入这个领域。感觉和之前单纯javaweb还是有些差异的。
微服务
springcloud那一套解决方案。
起因,首先当时并不是为了微服务而微服务,而是系统性能的确达到瓶颈,当时使用aws云主机,mysql,cdn,mongdb等都是aws的。选择配置基本都是顶配置,2组环境A、B环境,数据库是单点的(后续也做了拆分,大数据库分成2份了)。如果不调整架构基本达到性能极限,对部分大客户最耗时操作达到30s=》1分钟级别(智能排期,里面用到了递归调用,细节忘记了,逻辑是复杂的,由于是递归,代码调试基本无从下手的)。
如果不调整架构,性能问题基本是无解的。
所以当时就采用微服务进行业务拆分,从库存到生产单等依次拆分。
tenantId租户隔离
由于saas是将软件作为服务提供给用户的,所以从单个租户的角度这就是个独立软件,所以需要对系统所有表都建立tenant字段,作为租户隔离。这个比较难以区分的是租户和用户,租户是下挂在整个Saas平台的最大的隔离单元,用户是租户的用户。
隔离粒度来说可以通过数据库隔离(不同tenantid不同数据库),但成本偏高,优点是安全性好,可以独立设置备份规则等。数据表字段隔离(大多数吧),这也是我们目前采用方案,优点是简单且成本低。
强配置性
由于真实环境中,各工厂或正产线都有一些特殊性要求(基于公共功能上的私人定制),所以需要程序具有高配置性的特征,允许租户自己定义部分业务逻辑,从而实现尽可能的接入不同类型租户。
功能可配置性
添加减少功能的开关,或者改变功能的底层逻辑,数据校验逻辑的开关等。
外观可配置性
通过配置项修改数据展示项或展示形式。
version版本(静态数据的动态支持)
这个版本不是代码的git版本,而是数据表的行数据的版本。
举例来说,MES领域的工艺-工序,其本身是静态的,但是加入生产单后就是动态的了(部分数据会根据这个结构进行流转和计算)。此时如果有人修改这个工艺-工序,那么就会导致依赖这个工艺-工序的所有生产进行中的数据都会乱掉。由于之前并未考虑到这个问题,所以只能强制性的先阻止有正在生产的工艺工序的修改。其实这个就很影响用户体验。但是最合理的方式就是对工艺工序这种可能变化的数据添加version,进行快照式保存。同时关联这个表的所有表都需要提供原id+version进行唯一行定位。这样即使有生产中的订单,在修改工艺工序时,只需要将旧记录disable(标记无效).新增新记录即可。(当然还有另一种方式,就是将工艺工序表,摘出来一份放到单独表中,这个单独表和生产单关联,等价于复制出一份冗余数据)
更简单的例子就是淘宝购物时,淘宝会保存当时你下单时的商品信息快照,防止你下单时商品信息显示的是乔布斯的“苹果”,而收货时掌柜把商品信息改成你楼下水果店的苹果。但是你不能说由于用户下单了,所以商品信息无法修改吧!就需要对商品表新增字段versionid,每次修改商品信息都新增记录的versionid++(也不会真实的删除记录),这样每个购买者都可以看到自己下单那个时刻商品的详细信息。而不用担心被套路。
此时新增=新增,修改=disable旧记录+新增,删除=disable旧记录,查询=disable标记为为“有效”的记录(当然也允许查询旧记录,只是商品默认展示最新的versionid对应记录)
标记delete
这个其实比较常见,在金融领域几乎是标配,不会真实删除数据,都是标记删除。金融领域主要是涉及反洗钱所以国家法律有明文规定。SAAS虽然没有这样的硬性规定,也采用标记删除更多是为了出问题时更容易找后悔药。而且由于系统升级,会导致数据升维(也就是需要更精确的信息,旧的数据是不全的)此时会形成很多奇形怪状的历史数据。不删除数据也是为了以后万一有需要可以有的查。保留底线(底线就是最差情况下会怎样)。
客服和工单
saas需要强有力的客服系统和工单系统,否则研发人员只能天天找bug了。
关于客服,由于saas是面对多租户的,不同租户需求不同,审美不同。同一次升级有人拍手较好,也有人拿刀骂娘(我就不要用新版,我就要回到旧版)。所以需要客服一方面沟通,一方面做新产品的变更点的培训教育。
至于工单,也是伴随着多租户的差异和各版本迭代导致的历史数据问题,这是saas天然的复杂性导致的,出问题概率很大。而且,saas大多都是“高定制性”的,允许用户灵活的功能开关,功能关了还好说,功能开了,大多需要依赖额外数据,怎么填补数据?进行中流转单怎么处理?都是需要仔细思考的问题。简单来说,saas大多都是“坑巨多”!
简单来说,一方面,软件尽可能方便用户,另一方面,也别太提升底层系统复杂度,否则会导致用户方便1分,系统复杂3分,这3分带来的bug,再给用户体验-2分,导致还不如不做(大多数时候,对开发友好的系统对用户也是友好的,系统最好让用户猜到他是如何实现的,比如你就不会再电脑上一个没有按钮的地方狂点,还指望它能有什么反应吧)。我确实遇到过这样的问题,产品逻辑非常复杂,导致开发人员要照着小本本才能捋出逻辑。至于用户就更蒙了,研发拿着表一个个对数据,然用套公式给用户解释。这样的数据,过于复杂,无法让用户形成直接理解,他当然也不会相信。
技术点
缓存和redis
最基础的session共享等就不必多说了。这里更多是指热点数据的查缓存,就目前现状,redis只放查询类数据,修改类数据都是通过mysql或者mongodb固化存储,并未做缓存(主要是从简单角度考虑的,2份数据需要考虑同步问题)。
服务内鉴权
错误回滚能力
除了常规软件研发能力,还需要较强的“批量修改数据”,简单来说就是写sql和写脚本能力了。大多数时候数据升维都需要用到脚本批量处理历史数据。
sql调优
日志收集和分析
灰度环境
一定要稳
技术并非越牛越好,越新越好,而是最符合当前公司实际需求,最稳定,最常用的最好。还好,我们这方面做的还不错,需求到了在推动技术升级,不盲目求新。虽然踩到很多坑,但都是预计内的坑,没有遇到由于技术选型或架构错误等大问题。