若是你接到了一个开发需求:开发一个抽奖活动的后台系统。第一反应若是是打开IDEA,新建一个项目,输入项目名:lottery。而后开始根据需求着手开始进行设计数据库,api,而后进行开发,这是太日常不过的开发流程。前端
过了一段时间,你又接到一个相似的需求:开发另外一个抽奖活动的后台系统,可是里面的一些业务逻辑、流程处理不太同样,而后就把前一个完成的后台系统复制过来,准备开始修改。git
是时候中止这种看起来很高效但实际上很愚蠢的开发方式了!本文将告诉你如何将你的思想转变过来,给你一个将业务、将系统、甚至将本身升华的机会。我会用偏后端的思惟、尽可能易懂的图文、尽可能精简的代码、尽可能多的例子来将你的等级从熟练的业务驯服者
提高为初阶架构猎人
。github
使用复制、粘贴、修改的方法去开发一个相似的新的业务系统,从开发单个系统上来看开发效率上确实挺高的,但仍然存在如下问题:web
简而言之,老鼠的视力不好,它没有办法看到远处的事物,可是咱们为了往后业务系统的重复利用,就须要尽可能避免鼠目寸光的重复开发。算法
因此,须要将业务系统抽象为业务平台,支持通用的业务流程,让业务平台为往后的相似的业务系统提供灵活多变的基础业务实现方案,至于特殊的业务流程就单独开发一个特殊的业务系统,二者共同结合提供完整的服务。数据库
另外,平台的使用者应该相似SAAS,具有为全部人服务的能力,提供给能让每一个用户甚至每一个组织都能建立属于本身的独有环境,能够经过在平台上的简单配置构建出属于个体的服务。后端
如图所示,业务系统与业务平台共同为用户服务。业务平台包含某个业务的通用流程,可能恰好能知足业务的全部需求,那么此时就不须要另外开发一个业务系统。但若是有一些比较特殊的业务流程或者必须单首创建一个业务方便管理控制的流程的话,那么能够将该业务系统与业务平台结合到一块儿使用,业务系统提供定制接口,业务平台提供通用接口,业务系统也能经过受权的调用接口来调用业务平台获取、修改数据。api
首先咱们须要想清楚,如何从平台的角度考虑,将设计业务逻辑才能比较通用?如何区分是否为通用的业务逻辑,从而进行业务拆分?缓存
目的:解决业务实现的N种可能。在业务平台上尽可能支持多的、通用的业务逻辑。安全
如何解决:把眼光放长远一些,咱们这个业务系统如今须要支持哪些业务逻辑?往后须要支持哪些?而后进行有选择的取舍,不须要考虑太多,不然系统将被设计的特别复杂且用到的部分太少。一个简单有效的方法就是参照之前作过的系统和当前须要实现的系统,将通用的逻辑抽取出来。
举几个例子:
这里的边界指的是业务拆分时的边界,好比,哪些属于平台通用逻辑?就能把这些通用逻辑放到平台里。哪些属于业务特有逻辑?这些逻辑就不须要加到平台里。
好比,对于抽奖活动,配置奖品、分发奖品是抽奖平台
通用逻辑,但用户排行榜则不够通用,除了游戏相关的场景,不多须要用到排行榜的功能,那么排行榜功能就应该属于业务特有逻辑。
在整个抽奖的业务流程中,还有一个业务流程是当抽奖次数用光,就能够经过分享的方式增长抽奖次数。因此抽奖业务通用逻辑依然能够继续拆分,对于分享功能,是不属于抽奖平台通用逻辑的,那么能够将分享功能也单独抽出来成为分享平台
,使之也能服务于其余的平台或业务系统。
看似当前已经拆得比较清晰了,但尚未结束,由于这是仅仅针对于【分享成功->增长一次抽奖机会】这样的流程,若是须要分享屡次才能增长一次机会呢?若是分享以后每次增长不一样的抽奖机会呢?谁负责维护【分享-增长机会】这个奖励机制呢?这就须要一个引擎、流程控制中心来处理,不如就叫任务调度平台
任务调度平台的核心业务流程是【完成任务-触发奖励】,至因而谁完成的任务,触发谁的奖励对它来讲并不重要。只要它可以将任务的触发者与被触发者的对应关系、触发条件、被触发者的奖励接口调用方式维护在内部,当检测到触发者达到了触发条件,可以调用到对应的奖励便可
既然是平台,会由于使用者使用时长、数据量方面就会比通常的特有业务系统多,在设计时须要考虑到提早为书数据量较大的某些表进行水平分表设计,贴一个简单的分表的例子:
在建立数据库时按上图进行建立,在代码中进行增删改查时用下面的方法根据分表字段(shard key)来获取表名:
func GetTableNameByActivityId(activityId int64) string {
if activityId > 0 {
return "activity_prize_redeem_" + strconv.FormatInt(activityId % 16, 10)
}
return "activity_prize_redeem"
}
复制代码
分表时,根据哪一个字段(shard key)进行分表也是须要考虑的,须要使数据可以均衡的分布在多张表中,而且不影响正常的查询,这样才能经过分表的方式将数据均匀分布到不一样的表中,根据shard key进行查询时效率与不分表时同样,但若是使用另外的一个字段查询数据可能须要遍历全部的表才能将数据查询到,因此shard key的选择是与业务查询需求、数据均匀分布相关。
分表以后,最直接的影响是开发的时候须要对SQL语句进行动态调整,某些ORM框架不支持致使的开发效率下降,可是改动的代码很少,一劳永逸。
对于平台来讲,并发访问量也可能较大,那么缓存、队列、ES必不可少。
对于缓存,如今基本上说的都是使用Redis,可使用的集群模式有主从、哨兵、集群。使用的策略也有延迟加载、直写,还须要考虑到一些击穿、失效的缓存问题,具体能够看这里
对于消息队列,在业务解耦、流量削峰方面是一个很是重要的中间件,具体能够看这里
对于Elastic Search,若是业务上有全文检索的需求就是要结合EFK一块儿上的一个模块,具体使用方式、场景请自行查阅。
数据过重要了!分析用户行为,预测市场走向,仍是之后设计系统的参考指标,咱们做为技术开发人员,也须要为运营人员着想,须要统计出运营人员感兴趣的一些数据,最好是直接找他们提早询问清楚,哪些数据他们须要,以便咱们在设计数据库的时候将一些关键数据用一些字段保存下来。
好比在抽奖活动中,运营人员须要知道web平台、安卓平台、IOS平台分别参与抽奖的人分别有多少,可是设计出来的数据库字段、代码中打印出的日志可能都不存在或者难以经过现有设计进行统计,那么就须要对这个统计需求进行单独的设计。
在代码中输出日志是必须的,好比一般须要在访问API、某个API里的关键逻辑、结合关键数据打印成功或失败信息。
另外,对于某些业务场景须要严格统计数据操做以前的状况、操做以后的状况、操做类型、操做人员、操做时间。虽然也能够经过输出日志的方式,但不够规范,查询统计难度大,容易丢失。因此须要单独设计出一张操做流水表,将重要信息持久化起来。
在每一个须要统计的重要操做执行以后,使用消息队列或者另外的线程去插入一条操做记录到这张表中,以下
go service.Record(&models.SysOperateRecord{
BizType: dao.BizType_Customer,
OperType: dao.OperType_INSERT,
OperContent: fmt.Sprintf("batch insert one new customer: %s", customer),
Operator: userinfo.Id,
CreateTime: currentTime,
UpdateTime: currentTime,
})
复制代码
如何让用户有本身的独立环境?让他们能够在平台上简单配置以后建立本身的应用?
其实很是简单,在只考虑用户而不是租户的命名空间下,在系统层面和数据库设计层面多进行一层考虑便可,好比在数据库的主表/主实体上增长两个字段:namespace_id、app_id。
在多个平台(抽奖、分享、任务平台)创建起以后,须要一个后台管理平台将这几个平台统一管理起来,方便为用户提供统一的配置。
以建立一个业务系统为例,若是使用管理平台进行配置,那么用户只须要在管理平台上填写不一样平台的对应业务配置便可,在管理平台中将自动处理:
对配置好平台配置进行修改、删除,对业务数据进行统计的操做可经过管理平台的调整配置、统计数据接口进行
为何说适合用微服务架构来开发平台?
业务如何决定架构?
这里给出另外一个比较能体现业务决定架构思想的一篇实例文章参考
若是只考虑性能,那么不能选择微服务架构,由于单体应用在性能上是彻底碾压微服务架构的。若是为了全局考虑以后仍是得选择微服务,那么如何在使用微服务的状况下尽可能提高访问的性能呢?
首先须要经过压测的方式测试出性能的瓶颈在哪里,这篇文章可能有所帮助。
至少须要保证能在性能问题发生以后可以当即解决,因此至少要作到服务可以在任意时刻可以版本回滚、可以动态扩展到更多机器上。而后经过对应的方式如优化代码、使用缓存、队列、添加服务器、改进中间件架构的方式去解决性能问题。
对一个架构师来说,代码从提交到上线也须要考虑到,甚至须要考虑为团队构建DevOps体系。简单来讲,使用自动化流水线将代码提交、测试、构建、部署自动化起来,并在项目上线的过程当中协助开发测试运维进行代码版本的切换、部署方式的实践。
为了往后服务的蓝绿部署、回滚、动态伸缩,必须使用容器技术如Docker与容器编排平台如K8S来实现。至于具体的搭建方式、维护细节不用彻底掌握,但必定要知道各类部署方式、服务维护方式和其利弊。
对于抽奖系统,由于奖品有实际价值,因此直接跟钱挂钩。为了防止恶意用户撸羊毛,必须对可能存在的抽奖后门进行封杀。
对于抽奖系统,最大的后门是:中奖接口。如何判断用户是真正的玩了这个游戏并一路闯关达到终点夺得奖励的呢?对于web平台来讲真的是一个比较困难的问题,由于没办法跟游戏同样实时得到用户的数据进行详细的断定,因此只能在最大程度上增长中奖接口的校验规则。以下:
这是一些比较通用的web安全问题,通常在框架内部已经解决,但也须要确认是否开启相关安全机制。
等等等等,网站安全问题是在太多,没办法都写出来,不过以上问题比较常见,须要在开发时外加注意,这些虽然不会在架构设计图上展现出来,可是会是一个存在的架构隐患
咱们从业务、数据、技术、安全方面综合考虑如何将简单的业务设计成为一个平台,看重的是长远的收益,提高的是本身的能力。做为开发人员的你也许已经烦透写业务代码,不妨换一种开发思想挑战一下本身吧。
来源:91Code
关注公众号获取更多内容!