前段时间分配到一个支付相关的需求,一个需要和前端对接的项目,需要涉及到前后端对接的问题。为了可扩展性,决定将支付项目独立为一个新的服务。新创建的项目,不熟悉的童鞋可能会遇到一堆的坑,这边博主简单分享一下,自己的开发经验和准则。
确定需求:
在开发之前,我们首先要明确需求,需求中到底涉及到哪些业务,哪些流程。一定要先搞清楚才能进行实际代码的开发,否则代码可能有推到重来的风险(那个时候就等着使劲加班吧~)。
理解需求最好的方式就是将需求转化为流程图,这样可以一目了然的知道需要要开发哪些内容。这边我推荐大家使用viso来画流程图,效果图如下所示:
接口细分:
一般来说公司为了保证项目的进度,需要指定每一个需求的开发时间。那问题来了,你领导肯定会问你,这个需求大概多久可以开发完成。这个时候你会一脸懵逼,说多了会挨批,说少了又延期。这个时候我们就需要对需求进行细分,最好可以细分到接口级别,然后你根据细分的接口,预估开发时间就可以了。这边介绍一个面板工具:leangoo
这样做的好处是:
- 可以清晰明了的知道自己具体要做哪些事情
- 可以精确的把控自己的开发进度
- 可以明确整个需求的开发时间
数据库设计:
需求明确之后,第一步不是进行代码开发,而是根据需求,进行数据库的设计。我们可以采用PowerDesigner这种专业的工具,也可以直接在本地的mysql上面进行修改。博主采用的xmind思维导图来设计自己的表结构(当然设计完毕之后,还是需要在mysql中创建),这样做的好处是,我可以清晰的知道我要添加哪些表,修改哪些表。如下所示:
前后端对接:
因为要和前端对接,所以肯定需要一份接口文档,这边我采用的是swagger来生成在线文档。这样做的好处是:所有接口都是最新的,不需要人工去进行维护。
当然这只是开始,前端对接还需要对每个接口进行详细的说明,例如:
- 接口功能表述
- 接口的请求模式:get、post、delete、put等
- 参数说明:字段类型、是否必填、字段含义等
- 返回值说明
包名定义:
项目创建完毕之后,我们的包名要如何规划呢?为了规范,我将包名分为:
- config:配置类包
- dao/mapper:数据库操作dao类包
- service:服务类包
- util:工具类包
- constant:常量类包
- controller:控制类包
- exception:异常类包
- mq:mq监听器类包
- model:数据库映射类、dto、vo等对象包
- api:对外api请求类包
当然还有很多包名规范,这个要根据业务而定,博主的业务就比较特殊会涉及到mq、api。将包名规范好,写代码的时候就不会懵逼,至少代码的位置我们都是清晰明了的。
创建配置文件:
因为博主的项目是sprinboot项目,所以在包名确定下来之后,后面一件事情就是将项目运行起来,保证搭建的项目是正常的。单纯的项目运行当然很简单了,但是因为项目本身涉及很多第三方软件(redis、rabbitmq、mysql等),所以需要将这些软件配置搞定。为了方便后期的开发、测试、生产,我将项目的配置文件分为:dev、test、pro。
这样就能保证开发、测试、线上可以互不影响。
数据库相关代码生成:
项目可以正常启动之后,就要正式开始业务代码的编写了,业务代码的本质其实就是对数据库的增删改查。所以我们第一步要创建数据库对应的entity、dao、xml。因为数据库框架我这边采用的是mybatis,所以直接可用mybatis插件自动生成这些代码。
博主因为业务基本都是单表操作,所以采用了tk.mybatis插件,通过java代码快速完成sql业务的操作(有兴趣的童鞋可以去学习学习)。
业务代码编写:
数据库相关类、工具类、配置类都搞定之后,就到具体业务的开发了,这个时候有些同学可能会比较懵逼,我代码应该怎么写,控制类里面写什么、service层又应该写什么、dao里面写什么,怎么写才能避免重复代码的出现呢?其实这边博主也没办法给出一个具体的规范,只能根据自己多年的开发经验来分享。如果有谁想自己研究这方面的内容,推荐大家看一下《java编程思想》这本书,写的非常好。
代码分层:
- 控制类中只负责http请求的处理,具体的业务都不在这一层中实现,最多只是负责一些参数的校验。
- 在写业务之前,我们需求对业务进行细分,像我的原则按照业务类型创建业务服务类,例如支付服务类、交易记录服务类,这样的好处就是可以进行复用,尽可能的减少重复代码的出现。
- dao层中只有数据库的操作,不会对数据进行处理。
案例分析:
可能这样讲会比较抽象,我举一个例子吧,假如要开发一个套餐的支付(微信支付、支付宝支付)的功能。代码要分别怎么写?最傻的就是创建一个余额支付服务类、支付宝支付服务类。
我们首先要细分需求,比如两个支付都会涉及到创建交易订单和支付成功修改交易订单部分的功能,所以我们可以分为:创建交易记录、支付、修改交易记录状态、创建购买的套餐。这样就可以分为交易记录服务类、支付服务类、套餐服务类。这样我们就可以复用交易记录服务类和套餐服务类了。
服务类我们要本着功能可复用的原则,但是控制类我的原则是严格保持单一,尽量不要用type进行区分,这样做程序的扩展性和维护性会好很多。这里我给大家分享一个我写代码的技巧,我在写代码之前,我会先把业务步骤用注释的形式写出来,然后再去写具体的业务代码。
开发自测:
代码开发完毕就到测试环节了,这边测试有两种方案,一个是通过swagger页面直接发起http请求,但是博主不太推荐这种方式,前端可以用这种方式,后端我还是建议使用postman。通过postman工具,我们可以保存每一个接口的请求参数,还可以同步到云端,下次测试可以直接测试,不需要重新再添加参数。
发布线上:
数据库准备:
本地测试完毕之后,我们就可以发布到测试环境或者线上了,发布版本之前,我们要保证本地的数据和线上的数据库一致。因为本地开发可能不会设置索引,但是线上我们一定要设置每一个表的索引,不然后期添加或者修改的时候,将会对数据库造成很大的影响。
配置环境准备:
本地的配置我们可以虽然乱写,但是线上的环境一定要根据具体软件需求来配置(连接数、超时时间、并发数等)。数据库、redis、mq这些统统使用内网(如果是同一个网络),这样就不会占用外网资源了。
jvm参数设置:
线上的服务绝对不能默认jvm,因为这样只会使用到服务的1/4资源,严重情况下可能会导致jvm内存溢出等严重问题,所以上线的时候一定要设置好服务jvm参数。
优化升级:
每一个项目刚孵化的时候,肯定都是脆弱的,需要我们不断的进行完善。那我们要如何进行架构优化呢?一方面收集线上运行数据,另一方面就是对未来流量和数据的预估。像我们这个项目因为有对外的接口,那就应该进行接口限流操作,防止错误的调用导致服务奔溃呢。优化的方面当然有很多,博主这边也只能范范的给出几点优化建议:
- 如何应对高并发(大问题,根据具体方案具体实施)
- 如何保证高可用性(也是大问题,不过无非就是部署多台实例,负载均衡的进行请求)
- 对外接口如何保证数据安全性和可靠性(一方面可以对接口进行加密(对称加密、非对称加密、签名校验等),对接口进行限流)
- 数据库表数量过大(也是大问题,一般性方案是采用分库分表技术,例如mycat和sharding-jdbc)
总结:
项目开发细则就分享到这边,虽然开发过程中肯定不仅仅只有这些问题,但是采用正确的方式去开发项目,绝对可以事倍功半。希望本章的分享,可以对大家的开发有所启发。
想要更多干货、技术猛料的孩子,快点拿起手机扫码关注我,我在这里等你哦~
林老师带你学编程:https://wolzq.com