手记

如何设计一款中间件客户端,体验一把架构师的瘾

今天主要是讲解如何设计一款中间件的客户端,主要目的是传递架构的思想,让之前一直只做业务开发的同学了解一下中间件的思想以及如何设计一款中间件。因为我本身在工作的头几年都是在做业务开发,后面转成了架构方面,因此在这里说一下我个人的一些看法。

业务开发和架构开发的区别是什么呢?

技术方向不同,做业务(补充:一般来说业务系统的难点在做基础架构的时候基本上都会考虑了)基本上根据需求文档、原型图、流程设计图等,一般来说都是操作数据库来实现业务逻辑,不会有太多的技术难点(指的是大部分业务,当然也有难点很大业务开发的)。但是如果做架构,包括中间件架构、业务系统的基础架构,那么你考虑更多的是解决方案,比如:一共有哪些方案、每种方案的优缺点是什么、最后如何选择,需要积攒足够的技术栈、养成良好的思考方式,我的专栏<架构思想之微服务>里我使用的就是这种思想去引导大家思考每一种方案。

侧重点不同,很多时候我们在做业务的时候都是调用数据库、调用某个中间件,然后如何做架构的话更多的是考虑性能、并发、安全、后期扩展,还有就是考虑开发出来的东西让开发人员容易上手等等

以上,只是我个人的感受,可能会有人觉得说的不对!!!!

关于中间件的思想,我前面的两篇文章也提到过(分布式定时器、RPC框架),如果没有看到的可以回过头去了解一下,其实做架构或者中间件其实都是相同的,不要太过于注重某个点,需要从整体去把控,了解架构思想,在分步去实现。
今天主要是以网盘系统为例,讲解如何设计一款客户端给业务系统调用,如果对网盘系统不熟悉的同学,可以去了解我的开源的项目及相关专栏。地址如下:
项目地址:https://gitee.com/zwyyf/netdisk.git
专栏地址:https://www.imooc.com/read/73

需求: 我们部署一套网盘系统,然后统一管理各个业务系统的文件,业务系统无需再关系文件如何存储、如何管理的。
思考: 业务系统和网盘系统如何进行调用呢?通过什么方向进行通讯呢?

以下带大家一起分析几种方案的思路:

方案一:业务系统和网盘系统之间直接通过Http通讯

描述: ①网盘系统提供标准的Http接口,或者Restfull风格接口;②业务系统手工实现调用的细节,比如:基于HttpClient、UrlConnection、RestTemplate等等。
优点: 简单,很容易就能想到
缺点: ①增加了业务系统的调用复杂度;②服务治理(比如:负载、容错、动态感知、幂等、重试等等)的实现,需要业务系统自己去实现。

方案二:网盘系统提供接口工程,基于Dubbo、SpringCloud去实现
描述:通过提供接口工程给业务系统集成,提供好相应的接口

优点: 简化了业务系统的开发难度,并且集成了第三方的服务治理框架
缺点: ①限制性太严重了,如果业务系统不用Dubbo、不用SpringCloud开发那么怎么办?总不能要求别人重新改造吧?②如果业务系统不是Java语言开发的那么怎么办呢?

Dubbo、SpringCloud一般适合内部业务系统之间的接口调用,不适合跟外部项目的接口调用。

Dubbo的API工程示例

netdisk-api
|-- src/main/java
    |-- com.micro.file
    |  |-- FileService
|-- src/main/resources
|-- pom.xml

public interface FileService{
  public void upload(byte[] bytes,String fileName);
}

SpringCloud的工程示例

netdisk-api
|-- src/main/java
    |-- com.micro.file
    |  |-- FileService
|-- src/main/resources
|-- pom.xml

@FeignClient(value = "NETDISK")
public interface FileService {  
  @RequestMapping(value = "/file/upload",method=RequestMethod.POST)
  public PushResult upload(byte[] bytes,String fileName);
}

方案三:提供标准的SDK包给业务系统集成,其实我们参考一下Nacos的思想(我的专栏里面有讲解其思路),就会发现其实跟我们的需求很相似。我们学习开源项目,就是为了学习别人的思想、有用的代码、套用别人的套路到自己的项目,因此,我发现很多同学天天说看源码,但是根本没有懂得自己看源码的目的是什么,说白了大家都说看源码我也去看,自己没有掌握自己的学习方法。

描述: 我们提供一个jar给业务系统集成,我们的jar高度封装,以减化业务系统的集成
优点: 非常的灵活,①不同的通讯模式不同jar;②不同的语言提供不同的jar
缺点: ①难点比较大,涉及细节比较多;②考虑多种通讯模式;③考虑多种语言

总结:通过以上的分析,我们能明显的感觉那种模式比较好,其实这就是思路的设计,当你遇到一个难题时,把思路列出来,然后做对比,慢慢养成一种良好的思考习惯,这样才能让工作效率大幅度的提高。跟我观察,我发现很多的程序员会有一个通病,就是只顾实现功能,不考虑系统性。什么意思呢?比如:遇到一个问题,百度一下答案,然后copy代码运行ok之后,就不管了,我的习惯是我会去多对比,把跟其相关的知识点大概了解一遍,然后有必要再深入学习。

以上我们把业务系统和网盘系统的通讯架构及模式定下来之后,那么我们接下来考虑一下sdk的具体思路。

一、通讯问题
①通讯模式是什么?采用Http还是TCP呢?
②需要考虑集群连接问题,网盘系统可能会集群部署

其实,最好提供两种模式的通讯,Http短连接和TCP长连接。因为考虑到高并发和大文件的传输问题,高并发情况下业务系统每次都发起Http请求,那么网盘系统直接奔溃掉;如果业务系统上传的文件非常的大,那么Http将会传输失败。因此可以分别提供两种jar,让业务系统根据自身的业务、并发情况进行选择。

二、文件上传接口问题

如果对切块上传没有概念的同学,最好看一下我的专栏里面的讲解!!!
业务系统如果需要传递大文件那么应该怎么办呢?如何解决性能问题呢?

  • ①业务系统切块上传
    sdk客户端提供两个核心接口,切块上传和切块合并

优点:①思路简单,实现也简单;②文件上传不会出现超时
缺点:①很难控制切块标准,不同的业务系统定义的切块标准不一样;②对业务系统的前端技术部分限制过死,一定是切块上传、切块合并;③业务缺陷,比如:业务系统定时器扫描大文件上传网盘,此时没有前端实现切块、计算md5等等,这一切都得靠业务系统实现。

  • ②业务系统生成临时文件

业务系统把大文件上传到服务器本地,sdk客户端读取文件上传服务端

优点:①统一切块标准;②简化了业务系统的调用难度
缺点:①技术难度比较大,比如:如何计算超级大文件的MD5不导致内存溢出;如果控制大文件上传而不引起客户端请求超时;计算切块数、计算每个切块的下标起始值,然后获取对应的byte[]等等;②会占用服务器的内存和cpu资源,直接影响业务系统的性能

我真实测试的案例,计算14G的文件的MD5耗时263s,并且不会引起内存飙升。

由于篇幅有限,后面会更新跟其相关的文章

慕课网专栏(架构思想之微服务+仿百度网盘源码):
https://www.imooc.com/read/73
感谢您的阅读,希望您多多支持,这样我在原创的道路上才能更加的有信心。

0人推荐
随时随地看视频
慕课网APP