用互联网思惟来开发客户端软件——项目开发小结

      随着智能手机、平板电脑的快速发展,台式电脑在我的用户那里已经没落了,可是台式电脑仍然是企业用户工做中的主要工具,且具备不可替代的做用。客户端软件在企业级用户那里有着不可替代的做用,结合时代发展,咱们应以互联网思惟来作好企业级应用客户端软件?研发快速迭代、快速试错,把大功能拆分红小功能,分阶段实现,追求微创新。
前端

    一般企业级应用的客户端,就是企业管理应用系统,通常分为BSCS两种架构,CS架构要求在用户的电脑上装上客户端与数据库,或者数据库安装在数据库服务器上。这种方式咱们常常会碰到一些问题,好比用户的数据库坏,要求服务商帮助进行恢复;用户说个人数据没法保存到数据库中了,大家来看一下,这样就要派出人力到现场进行问题诊断,或者简单问题使用远程维护的方式,无论哪一种方式,一旦用户的数量超过了必定的量,那么公司的运维成本就上去了。那么有没有一种方式,改变这种状况呢?云服务风起云升,云数据库的兴起,宽带速率的大幅度的提高,宽带价格的不断下降。让我看到了一种解决方式。此次公司开发的新项目中,力主采用数据库放在云端,客户端经过服务端的Rest Ful接口去云端访问数据,而后加载到本地,用户进行业务操做。  java

      提及互联网,你们一个反应便会想到网站,例网易、新浪、淘宝、京东。你们想必也知道网站与客户端软件各有优劣吧,好比:网站能够运行在任何设备的浏览器上,不须要用户安装,网站有更新了,也不须要用户去升级,只要刷新一下浏览器就能够了,能在各类终端(平板电脑,智能手机,台式电脑等)保持统一的用户体验(固然须要有很是好的前端工程师);而相比之下,安装在台式电脑上的客户端软件会运行得更快,而且可以充分利用本地资源为用户带来更多的功能、更方便的操做。BSCS各有优劣,那么如何能把二者进行一些融合呢,让客户端软件具备一些BS架构的优势呢。我试着把一些互联网的优势融合进了这次的客户端软件中。web

项目介绍算法

     这是一个很大的项目,企业级用户数在1000以上,业务多并且复杂。我作为项目的客户端负责人参与系统需求分析至测试和部署的整个过程。负责沟通需求,创建客户端开发团队,肯定系统架构风格和技术实现方案。因为项目开发资源(好比时间、人力)紧张,项目的业务逻辑复杂,项目组对业务并不熟悉,难以在一开始预估将全部需求开发完成的时间。所以,在开发模型选择上,采用螺旋式增量开发。数据库

     在开发技术的选择上,因为本公司以往开发中,客户端都是使用微软的开发技术,服务端使用的是Java。 因此这次的项目仍是采用微软技术+java技术结合。浏览器

      整个系统部署共有12台服务器:四台前置机用于运行REST服务+前台管理系统+MQ+报文生成;四台Web服务器Linux + Weblogic 11, 分别运行后台管理系统+MQ+报文处理;四台数据库服务器 Linux + Oracle 12C;通过试运行,于10月份投入正式使用。目前系统情况良好,经运行评估,实现了所有必须功能,性能、安全性等质量均达到了原定设计要求。目前系统正在根据业务需求,作二次开发中。缓存

 

快速迭代开发、快速试错安全

 

      此次咱们对客户端的开发采用了Scrum敏捷开发流程——两周一次迭代,每两周发布一个版本。咱们称之为小步快进”——用户需求拆分,分阶段实现,先让用户看到咱们的工做在不断的推动。比较一下传统的软件开发模式:先制定一份详尽冗长的详细设计文档、项目任务计划,而后是少则12个月,多则是56个月甚至更久的开发周期,再加上一个较长的稳按期来修复足够多的bug,而后再给用户布署。性能优化

      那么如何快速试错呢?这就要须要靠数听说话了!网站是能够很方便地收集到相关数据:用户在网站上停留了多久,点了什么网页,在网页上点了什么按钮,用户使用的是什么浏览器,同时有多少人在线,访问的峰值出如今什么时间段,等等。这次咱们在客户端的一些主要操做都是要调用服务端REST接口进行操做的,咱们在服务端加入了一些收集信息的代码,同时在客户端中也加入了相似的收集信息的代码,不断的收集咱们开发的客户端软件中出现的BUG让咱们对客户端软件的性能以及用户行为了如指掌。咱们就能知道用户使用客户端时哪些查询比较慢,哪些操做是不合理的须要改进等信息。每次咱们作了一些改进或是增长了新功能以后,咱们都会先在小范围内给用户更新,而后在后台观察各类统计数据,同时也会派人去用户那里收集用户的使用反馈。以此来帮助咱们决定是否应该继续完善这个功能。服务器

如何解决版本碎片化问题?

       你们若是有过客户端软件运维的经历,那么确定会知道客户端软件到了用户那里,版本控制就是一个很是麻烦的事情了,在用户那里会有不少版本,这个用户的版本多是2.1,那个用户的版本多是2.2。若是版本更新比较频繁的话,特别是项目进行运维初期,咱们每两周就对外发布一个版本,那么用户那里的版本就更加不可控了。此次咱们在客户端中加入了强制更新机制,一旦在服务器端设置了这个参数以后,就可经过软件自带的升级机制把最新版本的客户端送到用户手上。

      在功能实现方面,咱们时刻保持着一种意识:尽可能不把业务逻辑在客户端里写死。不然的话,一旦业务逻辑有变,咱们必须修改客户端的代码,而后再作强制升级,一来周期比较长,二来万一有什么BUG就会影响用户使用,就必须不得不当即再次更新一个版本,同时通知用户更新,结果就比较被动了。举一个用户提交数据的例子吧。在客户端,当用户对单证数据进行了变动,提交数据的时候,要判断一下是否有变动?具体的业务逻辑是:若是用户对当前单证的数据进行了修改,则保存数据,调用保存接口;若是用户对当前单证数据没有作变动,则不用保存到数据库,同时给出提示。若是是以往的CS架构,这样作多少也会有点问题,由于存在并发的问题,更况且是访问的是云端数据。一些经验欠缺的开发人员 会把上述逻辑直接实如今客户端软件里。遗憾的是,这样作没法解决并发的问题,并发状况下那会死的很惨的!更灵活的实现方式应该是客户端只要把用户的单证数据作为参数传给保存接口,而具体的业务逻辑实现则由服务器端来实现。

    固然,上面只是一个很小的例子。为了在客户端里得到足够的灵活性(不经过发布新版本就能知足业务需求),咱们给不少功能加上了云端配置。只要咱们发现某些功能的用户使用上有问题,好比查询超时了,咱们就能够随时均可以调整控制参数,甚至能够控制用户每分钟的请求数。咱们始终牢记,咱们在作的不是一个单纯的、孤立的客户端软件——咱们提供的是一种互联网服务,咱们提供的是云端功能。 

   

为何采用REST作为数据访问接口

     咱们采用REST服务方式来实现客户端与云端的交互,是由于考虑到项目开发的两个因素:简单和灵活。

      REST (Representation State Transfer) 描述了一个架构样式的网络系统,好比 web 应用程序。它首次出如今 2000 年 Roy Fielding 的博士论文中,他是 HTTP 规范的主要编写者之一。REST 指的是一组架构约束条件和原则。知足这些约束条件和原则的应用程序或设计就是 RESTful。

      使用REST作为业务逻辑接口是由于,从客户端到服务器的每一个请求都必须包含理解请求所必需的信息。若是服务器在请求之间的任什么时候间点重启,客户端不会获得通知。此外,无状态请求能够由任何可用服务器回答,这十分适合云计算之类的环境。客户端能够缓存数据以改进性能。

      在服务器端,应用程序状态和功能能够分为各类资源。资源是一个有趣的概念实体,它向客户端公开。资源的例子有:应用程序对象、数据库记录、算法等等。每一个资源都使用 URI (Universal Resource Identifier) 获得一个唯一的地址。客户端使用的是标准的 HTTP协议进行资源访问,同时还可使用标准的HTTP方法,好比 GET、PUT、POST 和 DELETE。

      REST的一个重要原则是系统分层,这表示组件没法了解它与之交互的中间层之外的组件。经过将系统的某些功能限制在某一层,由此能够限制整个系统的复杂性,促进了底层的独立性。

      当 REST 架构的约束条件做为一个总体应用时,将生成一个能够扩展到大量客户端的应用程序。它还下降了客户端和服务器之间的交互延迟。统一界面简化了整个系统架构,改进了子系统之间交互的可见性。REST 简化了客户端和服务器的实现。

REST架构风格能够为开发者带来三方面的利益:

  • 简单性

  采用REST架构风格,对于开发、测试、运维人员来讲,都会更简单。能够充分利用大量HTTP服务器端和客户端开发库、功能测试/性能测试工具、HTTP缓存、HTTP代理服务器、防火墙。这些开发库和基础设施早已成为了平常用品,不须要昂贵小型机、大型机等硬件,使用增长日常使用的便宜的PC服务器,就能解决大多数可伸缩性方面的问题。

  • 可伸缩性

  充分利用好通讯链各个位置的HTTP缓存组件,能够带来更好的可伸缩性。其实不少时候,在客户端作性能优化,产生的效果不亚于仅仅在服务器端作性能优化,可是HTTP协议层面的缓存经常被一些资深的架构师彻底忽略掉。

  • 松耦合

  统一接口+超文本驱动,带来了最大限度的松耦合。容许服务器端和客户端程序在很大范围内,相对独立地进行开发,并行开发。对于设计面向企业内网的API来讲, 松耦合并非一个很重要的设计关注点。可是对于设计面向互联网的API来讲,松耦合变成了一个必选项,不只在设计时应该关注,并且应该放在最优先位置。

     REST服务具备很是出色地灵活性,同时方便用浏览器和 firebug等工具进行测试。咱们在项目中,并无将REST服务单纯视为一串地址的响应,基于HTTP协议,能够最大地利用HTTP协议的语义特性。如数据的增删改查操做对应不一样Http Method(Put/Delete/Update/Get)。用户能够用相同访问URI,根据须要,经过在请求头中设置不一样的 Accept-Type,获取不一样形式的数据结果,好比JSON(用于Ajax)或XML(用于后台)。

     REST服务请求因为不须要构造SOAP消息,开销更小。 REST服务能够利用高速缓存控制头,从而减小带宽的需求,从而REST能够改善响应时间和改进用户体验。
    REST的每一个请求都是独立的。一旦被调用,服务器不保留任何会话,这样就能够更具响应性。经过减小事件后通信状态的维护工做,提升了服务器的可扩展性。 

在此系统开发过程当中,也遇到了一些问题:

1、安全性方案。特别是指Restful Api的访问控制方法。REST既能够被服务器端调用又能被客户端调用,因此一开始就要明确地区分用户访问权限和系统访问权限,区分Web页面权限和REST API接口权限。可是在开发过程当中常常会混为一谈,从此要增强设计阶段这方面的文档和评估工做。

2、服务接口规范性。REST服务基于URI地址访问,URI不只仅指明了被标识资源所在的位置,并且经过这个URI能够直接获取目标资源。REST服务接口的每一个操做都基于一个URI模板。在实际业务中,功能相似的操做被作成多个重载,随之重载的增多,URI模板如何约定,如何扩展便成为一个规范性问题。开始时,对此未予以足够重视,REST服务接口由不一样的人来进行开发,以至于一些REST服务接口定义上产生了混乱,影响了理解和正确使用。后来,又额外花费时间定义了操做URI的规范。经过这次的项目让我知道了应该从设计时就应该全面考虑URI模板的语义扩展方式。

3、因为服务端使用的是Spring与Hibernate这些JAVA的第三方组件,因此形成了一个问题,效率问题,一旦数据量稍微大一点,就会出现问题。我仔细研究了一下服务端工程师写的JAVA程序,发现原来他们的写法很成问题,我不知道这是否是JAVA使用Hibernate就是这样使用的。我举个例子:

表结构与要显示的结果以下图。

 

通常咱们,应该使用SQL语句,使用SQL的(inner join 、left join、right join)三种中的一种,把三个表关联起来,一条SQL语句,把结果查询出来。

服务端的实际写法倒是,先查询了“单证实细表”,而后循环去查询货物信息表,获得品名,查询企业信息表,获得名称。也就是说,由一条SQL语句,变成了

明细数量*2条SQL语句,最后,形成了很大的性能瓶颈。服务端的负责人最后为了达到性能上的指标,使用了内存数据库,来解决这个问题。

相关文章
相关标签/搜索