程序员的自我修养
上QQ阅读APP看书,第一时间看更新

二、全栈工程师如何快速构建一个Web应用

前不久,我为我的微信订阅用户编写了一个分享学习编程和设计资源的小站——技匠社(jijiangshe.com)。有朋友问我是如何在短时间内写出这个网站的,我又用到了哪些技术和框架呢?这其实是一个挺有意思的话题,我们都知道全栈工程师能够快速地开发出一个网站或者APP,那么他们到底是怎么做到的呢?我花了一些时间将我在这个实验性的小项目中的一些实践写成文章,与大家进行分享。

如果你问10个全栈工程师,如何快速构建一个Web应用,我相信你会得到10个不同的答案,因为每一名全栈工程师的技术栈都不尽相同。以设计见长的全栈设计师可能会告诉你,做一个很好的设计,然后套用一个博客系统或基于CMS的内容管理平台(如Drupal、Jommla、Wordpress)就可以快速建站;而前端全栈工程师可能会建议用HTML5+JavaScript(AngularJS或React)来写网站的前端,用Node.js来写后端服务。我最早是一名Java程序员,后来当了架构师,又自学设计,成为了一名全栈工程师。因此,我会更偏向于使用Java来构建稳定且易于扩展的后端服务,而用HTML5+CSS3+JavaScript,再结合一些流行的前端框架来快速写出一个Web应用来。当然,这绝对不是唯一或最优秀的技术组合,你需要根据不同的应用场景和你自身的专长来进行合理的选择。

在这篇文章里,就让我们结合网站开发的各个重要阶段(网站定位、功能设定、设计、架构、开发、部署、性能调优、数据统计、开发工具),来谈谈我在构建这个真实Web应用过程中的一些思考与实践。

1.网站定位与功能设定

网站无论大小都应该有清晰的定位,也就是你希望你的网站做什么?这一点非常重要,我见过很多网站虽然功能很多,但由于缺少明晰的定位而少有人问津。而我写的这个小站只有一个核心功能,那就是要帮助我的微信订阅用户们(大多是学习计算机或设计的在校大学生和那些工作不久希望提升技能的设计师或程序员们)分享那些优秀的开发或设计(学习)资源。

围绕这个核心功能,我便得到了构成这个网站所需要的3个主体功能:

•资源发布与展示(核心功能,用户可以分享他们的资源,也可以看到其他人的分享)。

•用户的第三方登录(为了快速开发,我省略了不必要的用户注册功能,全部采用第三方社交平台登录)。

•用户反馈功能(用户反馈几乎是我自建的每个网站中都包含的功能,这使我能通过不断收集用户的反馈来改进这个平台)。

至此,已经完成了网站的功能设定,我尽可能省略了一切不必要的网站功能,也没有写任何文档,这使我能够以最快的速度将这个Web应用实现出来。这种方式也是目前增长黑客们所普遍采用的一种做法:快速搭建出一个具备核心功能的应用原型——MVP(Most Viable Product,最小化可行产品),来验证自己的业务模型,然后再根据用户的需求和反馈来不断进行改进。当然,随着项目规模的不断扩大,以及更多团队成员的加入,我们可以回过头来再去补齐那些在前期遗漏的文档。记住,仅当确认文档能够产生价值时,才去编写它们。

2.信息架构

这个阶段在不同的团队或项目中会有很多不同的名字,比如,概要设计、业务建模,等等。而我最喜欢信息架构这个名字,因为在这个阶段,我们所要做的就是对不同纬度和粒度的信息进行抽象、规划、设计,从而支撑整个网站的信息体系。我曾经历过很多不同的信息架构方法论,从最初基于模块的设计,到后来的领域驱动设计(DDD)、面向服务的设计(SOA),Oracle的基于数据建模驱动的设计,再到最新的微服务架构设计,等等。我想说,这些方法论大多是针对那些大规模应用而言的,你需要了解它们,并有意识地在你的系统设计中去匹配这些优秀的架构和设计思想,这有利于你做出扩展性良好的系统,从而避免因整个系统复杂度的提升而导致的大规模重构风险。

对于我们这个小站来说,我们只需要先定义出合适的业务领域和实体模型。这里,我们定义出以下3个业务实体,并为这些实体添加所需要的字段:

•User(用户)。

•Resource(资源)。

•Feedback(用户反馈)。

围绕着这3个领域模型,我们再定义出3个服务,并为它们增加相应的方法:

•UserService(用户服务)。

•ResourceService(资源服务)。

•FeedbackService(用户反馈服务)。

信息架构阶段完成后,我们已经对整个网站创建了一个全面的视图,下一步,我们就可以进入UI设计阶段了。

3.UI设计

我经常在CSDN、V2EX等一些开发社区看到一些程序员分享的由他们独立开发的网站或工具。当我访问这些网站时却往往发现,这些网站大多只是简单套用了一个模板或干脆根本没有任何设计。这样的网站虽然功能不错,但很难吸引用户前来使用。我也不是一名设计师,只是利用业余时间自学了设计,但当我需要独立完成一个网站时,我仍然会尽我所能地做一些设计,而为了能够快速实现一个网站,我的做法往往是借助现代网站设计工具(比如Blocs)或利用现成的网页模板去实现它。在这个项目中,我就用到了一套相对简洁的HTML5+CSS3网页模板。

使用模板有很多优点,比如,你可以直接获得优秀的设计,利用网页模板自带的HTML、CSS、JavaScript代码可以节省大量开发时间,等等。但使用模板同样会带来一些问题,比如,网页模板可能会包含大量你不需要使用的页面或代码,你需要小心地剔除它们,一些设计师写的脚本很可能存在缺陷,你需要去修复它。同时我想说,你必须首先理解设计才能正确地使用模板,因为模板往往不能解决你所有的设计需求,你总会需要在你的设计中添加一些额外的页面,这时你就必须基于现有的设计,去进行添加或改造。这往往比从头开始进行一个完整的设计还要难,因为你必须保持和网页模板的设计者相一致的设计思路,否则你的网站将变得非常不和谐。而在整个过程中,你必须理解设计的各个方面:色彩、字体、动效、排版,等等。

在做技匠社网站时,用Sketch所做的一个资源详情页面的设计。

为了得到更好的用户体验,我也会在弹出资源详情页面时,利用CSS3的@Keyframe给它赋予诸如打开报纸般的简单功效,这能让应用显得更加生动、有趣。

4.应用架构

接下来,我要做的便是为网站选择合适的应用架构。我曾为一些银行或保险公司写过底层核心框架,来支持它们复杂或对并发要求极高的业务场景。但对于一个刚刚起步的网站,你完全不需要去做如此复杂的架构设计,只需要尽可能地去使用那些标准和开源的框架和技术就能够保证你做出一个具有良好扩展性的网站。请记住:没有最好的架构,只有最合适的架构。

为了便于系统日后的扩展,我采用了前后端分离的架构设计:

前端:目前最流行的两个前端框架是AngularJS和React。在这个项目中我选择的是AngularJS(https://angularjs.org/),主要出于以下两个方面的原因:

•我需要的是一个更完整的JavaScript框架,AngularJS能满足我在全面性方面的要求,我可以使用它的Controller、Service、Directive等特性来构建出一个完整的Web应用。

•我希望在将来用Ionic来写出一个APP应用,由于Ionic也是基于AngularJS的,这意味着,我将可以复用很多前端代码。

后端:对于后端,我选择的是基于Spring Boot(http://projects.spring.io/ spring-boot/)的框架,Spring Boot并不是Spring的一个升级版本,而是一个为构建微服务提供更好支持的全新框架。Spring Boot能够为我提供一个具有良好扩展性的框架,在初期我可以将所有的功能作为一个整体对外服务。随着用户数量的上升,和系统规模的不断扩大,我将可以借助Spring Boot,并基于Domain Driven Design的设计思想将系统的服务进行拆分,构建出一系列微服务。

目前,在后端我主要使用到了以下这些技术或框架组合。

•Spring Boot:开发基于REST的服务,使用JSON作为数据交换格式。

•MyBatis:提供基于SQL的持久层支持。

•Redis:由于采用了前后端分离的做法,我用Redis来持久化用户Session信息。

•Spring Security:提供安全方面的支持,能与SpringBoot无缝整合。

•MySQL:在这个项目中我仍然使用了传统的关系型数据库。

•Maven:项目的包依赖管理,以及项目打包。

5.开发

开发相对来说倒是一件按部就班的事情。首先,基于Spring Boot及其他第三方库所提供的API来开发出基于REST的服务;然后,在前端利用AngularJS将应用分为几个模块(UserManager, ResourceManger, FeedbackManager)分别开发;最后,通过$http调用后端服务来进行业务处理和数据交互。

在整个开发过程中,你仍需要去解决一些问题:

•前后端分离之后,如何进行Session的管理。

•如何实现安全的跨域请求。

•在Spring Boot中如何整合MyBatis框架。

•如何利用Spring Security来构建安全的REST服务。

•如何利用云服务实现图片的上传与处理。

6.部署

(1)选择云服务器

虽然我们采用了前后端分离的架构,但在上线初期,我们可以将系统的前端、后端和数据库都部署在一台云服务器上。我们需要选择一个云服务提供商,将应用部署上去。如果你是一个学生,那么我建议你选择亚马逊云,因为它能提供首年免费使用的服务。我由于有多台服务器使用了阿里云,所以为了管理的方便,我还是选择了阿里云服务器来部署我的应用。在操作系统方面,我选择的是Ubuntu Linux。在其他硬件方面,除了带宽,我选择了3M之外,其他我都使用的是最低的配置,因为根据上线初期的用量评估,这样的配置已经足够使用了。当用户和规模增加时,可以通过升级配置的方式来获得更多硬件资源,这一点还是非常方便和经济的。

(2)应用部署

后端:由于采用了Spring Boot,所以后端的服务可以用Maven Plugin直接打包成一个可运行的jar包,它集成了Jetty服务器可以直接向外提供REST服务。当然,如果你不喜欢Jetty,那么也可以通过在pom.xml中简单地修改配置来集成tomcat作为你的应用服务器。最后,在你的服务器启动脚本中,简单地使用Java-jar命令,就可以启动你的后端服务了。

前端:前端是一个静态网站,包含HTML、CSS,以及图片文件。我将它部署在了一台Apache服务器上,当然你也可以选择Nginx这样的高性能服务器。

(3)安全

你需要定义出网站的安全策略,比如,用户组,用户权限的分配,出于对安全的考虑,尽可能将不需要开放的端口用防火墙隔离,只保留80等几个对外提供服务的端口,等等。另外,如果你的网站交互中包含一些敏感的信息,那么你还应该使用TLS对数据的传输进行加密处理。

7.性能调优

在正式上线之前,你还应该对网站做一些性能调优,以保证网站能够有比较好的响应速度。使用YSlow等工具是一个不错的选择,它能告诉你网站加载缓慢的原因,并给出优化的建议。

下面是一些常见的优化方法。

•合并压缩静态文件:将JavaScript、CSS文件进行压缩(去掉不必要的空格、换行和注释)与合并(将多个CSS或JavaScript文件合并成一个文件),并使用GZIP进行压缩,可以提高网站的加载速度。

•使用前端镜像库:对于网站中用到的第三方字体和前端代码库,我通过360和百度的前端镜像站点来获取,这样可以降低网站本身的流量开销,也可以提高网站的整体加载速度。

•利用云存储和CDN进行加速:技匠社的资源分享具备图片上传功能,而图片是最占带宽的,3M的带宽根本支持不了几个用户的同时访问。因此,我选择使用了七牛云,我将用户上传的图片通过七牛云的API传到七云存储空间内,并直接利用它的CDN对这些静态资源进行加速,这样一来网站的图片及那些静态文件(我们将那些不会频繁修改的JavaScript、CSS等都放到了CDN上)就不会占用阿里云的带宽了。另外,不得不说七牛云的价格对于个人用户或初创企业来说还是比较优惠的,比如,10GB空间以内的存储都是免费的。

下图为网站的CDN流量统计。

8.网站数据统计

网站上线后,你仍然需要对网站的访问量、用户情况进行持续的统计和分析。大家可能发现在网站的功能里我们并没有加入相应的用户访问跟踪模块,是的,我们可以借助第三方的统计平台来帮我们做这件事。由于国内无法使用Google Analytics,因此我选择了百度统计。你只需要在百度统计中注册一个账号并加入你的站点,然后在你的网站头部加入一小段JavaScript代码就能实现最基础的网站统计功能了。当你需要更多用户个性化分析时,可以在应用的内部增加相应的模块来进行数据的抓取和分析。

9.开发与设计工具

最后来分享一下我在整个开发过程中所使用到的4个主要的开发和设计工具,我用到的其他一些工具,也可以在我写的另一篇文章“一名全栈设计师的Mac工具箱(设计、开发、效率)”中找到。

(1)Eclipse(https://eclipse.org/)

Eclipse是我一直在使用的后端Java开发IDE,另外,我也使用它来开发基于Spring Boot的后端服务应用。其实,比起商用的IntelliJ它仍然逊色不少,之所以推荐它,一方面因为我一直在使用它,另一方面因为它是免费的。

(2)Sublime Text 3(http://www.sublimetext.com/)

我使用Sublime Text来开发前端基于AngularJS的静态网站。它是我开发前端代码时最喜欢使用的IDE。我非常喜欢它的那些使代码异常清晰的主题,以及功能丰富的插件。有了它,开发HTML、CSS、JavaScript变成了一件非常愉悦的事情。

(3)CodeKit(https://codekitapp.com/)

CodeKit可自动编译Less、Sass、Stylus、CoffeeScript、Jade & Haml等文件,为JavaScript提供合并、压缩及错误检查,还可以优化JPEG和PNG图片,并为用户提供一个本地的测试环境。当然,你也可以不使用任何工具,直接通过Grunt或Gulp的插件去实现所有这些功能。

(4)Sketch 3(http://www.sketchapp.com/)

Sketch是我目前最常使用的设计工具。它只有几十兆,相较于Photoshop,它小巧得多。此外,更重要的是它专为UI设计而生,我可以不必关注那些与我做UI设计毫无关系的图片处理功能,从而降低了工作环境中的噪声。另外,通过强大的插件功能,我能根据需要进行安装使用,这大大提高了我的工作效率。所以,现在大到做一个完整的UI设计,小到设计一个图标或修一张图片我都会首先选择Sketch这个工具。

能够快速构建出一个Web应用或APP是全栈工程师的核心竞争力,这也是为什么那么多初创公司都在寻找全栈工程师的原因。如果你也希望成为全栈工程师,那么请跟着我一起进行全栈修炼吧!