Worktile 技术架构概要

徐海峰
徐海峰 2015-04-13 21:01 38 12062

其实早就该写这篇博客了,一直说忙于工作没有时间,其实时间挤挤总会有的,可能就是因为懒吧!从2013年11月一直拖到现在,其实我是不怎么擅长写技术博客的,因为语言表达能力和文采不是很好,每次写博客都不知道自己在写啥,作为一开始就参与 Worktile 开发的技术人员,今天就简单谈谈 Worktile 的技术架构吧 。

Worktile 自上线到现在收到了很多用户的喜欢,我们倍感欣慰,自己做的产品得到了用户的认可是件幸福的事情,其中有很多来自IT的用户,经常在官方群或者知乎上问一些关于Worktile的技术问题:

Worktile 采用的是怎么样的架构?
Worktile 前后端采用了哪些技术?
...

Worktile整体架构一览

Worktile 是企业协同办公软件,所以一开始注定就应该是单页应用(SPA),因为使用SPA后,用户在浏览器端可以像操作原生客户端程序一样的体验(速度和流畅度),对于开发者来说,前后端分离,服务端只提供RESTful API服务,移动端集成也非常的方便,具体可以看下面这张草图。

Worktile 整体架构

前端

  1. Angular.js(客户端MV*)
  2. Bootstrap (CSS基础库和一些Javascript组件)
  3. UI Bootstrap (Bootstrap 的 Angular.js版本)
  4. jQuery (取代Angular.js中的jqLite,并作为其他第三方jQuery插件的基础类库)

Worktile的服务端基本上只是提供API数据服务的,不会渲染HTML,前端的代码在发布之前会使用 Grunt 工具打包合并压缩成一个js文件。

Angular.js

既然是SPA程序,前端必然要选择一个MVC(或者MVVM)框架,关于前端MVC框架有很多,当时面临选择的时候也是比较犹豫,因为在此之前我们只初略的使用过 Knockoutjs
其实我们当时就是急切的希望一个框架能做到:

  1. 数据能够双向绑定(或者只单向绑定)
  2. 前端路由功能
  3. 简单易学的模板语言

最终我们选择了 Angular.js,具体其中选择的细节就不一一描述了(之前在知乎上也回答过关于Angular.js 的问题:Angular.js 在实际应用中有哪些优缺点?),从开始使用到现在已经快2年了,事实证明当初的选择还是没有错的, Angular.js的确很适合 Worktile。

Bootstrap 和 jQuery

选择Bootstrap主要是为了使用它的基础CSS功能,在它的基础之上很容写出规范的样式代码,当然我们也需要使用其中的部分Javascrip组件功能,因为原生的 Bootstrap是基于 jQuery的,为了在Angular.js中也能很好的使用它,我们引入了 UI Bootstrap、关于jQuery大家再熟悉不过了,我们使用的很多第三方插件是jQuery的,所以也一并引入了。

上面只是列出了 Worktile 主要使用的几个Javascript框架和类库,真正使用的类库远不止上面列出的这些。比如日历库 ui-calendarunderscorejs 等等...

服务端

  1. Node.js
  2. Redis
  3. MongoDB

Node.js

服务端是构建在Node.js之上的,我们的服务端MVC框架采用的是 Expressjs,刚开始是 Express 3.x版本,现在已经升级到 4.x,Expressjs提供了 Route和模板引擎的功能,由于我们的服务端基本只提供数据服务,所以关于服务端模板引擎这块基本不使用(只有布局和一些配置项输出到界面时需要用到)。

选择 Node.js 是因为它简单,适合高并发的Web服务,而且我们的开发人员能够熟练使用它,关于Node.js的优缺点我在知乎上也曾经回答过:使用 Node.js 的优势和劣势都有哪些?

Redis

Worktile 用户的登录状态,一些临时使用的数据、部分业务数据缓存 都是放在 Redis 里面的,关于Node.js怎么和 Redis 连接采用 Node Redis 模块。

MongoDB

Worktile 并不是那种高度事物性的系统或者传统的商业智能应用,所以MongoDB非常适合,性能非常高,集群方便,而且以BSON结构存储,和Node.js完美集成。
Worktile 的数据层和MongoDB之间并不是使用 原生的驱动 ,而采用了 mongoosejs,类似Java或者C#上的ORM框架,使用 mongoose 可以很方面的定义数据 Schema,读取操作 MongoDB。

推送服务

前面也说了 Worktile 是 SPA程序,用户登录到系统之后,基本上所有的操作都不需要刷新浏览器,因为是一个协同办公软件,其他用户多数据进行操作需要实时更新,所以客户端必然要和服务端保持一种长连接,方面进行数据交互,我们的实时推送服务是采用 Erlang 语言编写的,感兴趣的可以查看:https://worktile.com/tech/basic/worktile-real-time-notice

采用 Erlang 是因为我们的开发人员有这方面的经验,并且Erlang非常适合做这个高并发实时推送服务。

如果你熟悉 Node.js 肯定知道 Socket.IO,我们最初的实时推送其实是采用 Socket.IO的,后来由于访问量的增张,原有的Sockiet.IO 是基于Worktile Web站点的,没有独立成单独的服务,重构的时候彻底采用Erlang重写了。

其实这2种技术都非常优秀,选择哪种主要取决于你擅长什么。

文件预览服务

使用过 Worktile 的人肯定都知道,在系统中上传一些文件,比如:word、excel、txt、pdf、ppt等等,都是可以在线预览的,关于 txt、pdf这些文件的预览其实好办,txt直接读取文件内容即可,pdf采用浏览器自带的预览或者使用一些Js类库都很方便的做到,但是对于 Ofiice 文件,是不可以直接读取的,所以我们自己搭建了一套 Ofiice的预览服务,这个服务主要是基于微软的 Office Web App服务

Box 文件服务

Worktile 中所有的文件存储在阿里云的OSS上,为了做一些权限的认证和安全问题,我们通过一个Box服务做中转,所有文件的上传下载都是走 Box 服务。这要感谢 5楼的Box之父 @Shaun Xu 写出了这么好的Box 服务。

以上是Worktile用的所有技术和架构简单介绍。

Worktile 自上线以来用户的增长也是非常迅速的,所以 Web服务器从原先的1台变成多台,数据库从单实例到现在的集群,等等,关于目前Worktile的服务器结构图参考如下:

Worktile的服务器结构图

Worktle 免费了

评 论

anytao anytao
04-13 23:34 #2

这个我看过的关于架构分析,最好的一篇了,给小伙伴点个赞。

Rwing Rwing
04-14 15:58 #3

nginx服务器是只有一台吗?

#2楼 @Rwing: 目前有一台备份的nginx服务器,但正式使用只有一台,当代理服务器故障的时候,切换到备份nginx服务器上去,以后会做成热备

#2楼 @Rwing: 目前web服务只有一台代理服务器(还有说的备份nginx服务器,正常情况下不工作),其他的服务都有单独的nginx服务器。

架构图里面为什么没有最为重要的Box呢!!!

推到社区~

#5楼 @Shaun Xu: 这个失误了,回头补上,把BOX之父的BOX漏掉了

#5楼 @Shaun Xu: Box 之父 ,文件服务已经加上了

非常感谢这么好的文章~ 能否再提供些文件预览服务的部署经验呢 非常感谢

哪里有Box的详细介绍

#10楼 @周崇军: 这个暂时没有,以后或许会补上

#9楼 @吴林峰: 这个回头会有相关的人发布博客,到时候通知你

作者是如何处理hash路由的?

前后端分离, 正在进行中, http://segmentfault.com/a/1190000002690813

为什么用Node?因为我们有人能够熟练使用。 为什么用Erlang?因为我们有这方面经验。 说了等于没说 sweat

非常不错的一篇技术分享,WEB产品架构的典范!

#13楼 @arccode: hash 路由使用的是Angular.js 的路由功能

#15楼 @EurekaWang: 欢迎吐槽,团队中有人熟悉了解这门技术的确是选择这种技术的一个因素,但不是只因为这个因素,当然对于某些人来说也许就是废话,哈哈。

#8楼 @徐海峰: You are always awesome!

nice~

Dom Dom
05-05 12:46 #23

很不错的分享,谢谢。

nice!

学习了, worktile用户.. ps, 楼主socket写成了sockiet。。。我不是故意挑错的 5555

#24楼 @赖永华: lice.

@徐海峰 @arccode @anytao 赞一个。大部分技术都有一定了解,技术架构和服务器架构都相当赞。 不过有几点疑惑:

  • Nginx你们应该还实现了负载均衡,不仅仅是故障转移吧?

  • Office Web App Server你们是如何实现集群的?

  • Knockoutjs感觉很轻量,但是确实不适合做SPA,我用的不深,你能点评下Knockoutjs么?

  • 在我的印象中,NodeJs+MongoDB+Redis+Express(这个我不了解)不太适合复杂业务开发,但是随着Worktile的持续发展以及反馈的不断积累,估计以后避免不了开发复杂业务,遇到这种情况,你们有考虑过么?是否考虑多语言开发(比如引入Java或者C#)以及添加关系型数据库呢?或者搭建一个可扩展的Socket服务器端框架,能够使用NodeJs、Java、C#等等来编写插件之类的?

  • 因为对NodeJs实践经验不多,我想问的是,NodeJs做单元测试方便么?

#18楼 @徐海峰: Worktile是我看到的第一个真正使用NodeJs开发的用户体验相当赞的高可用的网站。以前在NodeJs开发网站业务这块,我都是持怀疑态度的。

#24楼 @赖永华: lice,已经纠正

#26楼 @李文强:

  1. 我们采用了多个 Nginx,但没有采用 Nginx 集群;
  2. 关于 Office Web App Server 集群,参考:https://technet.microsoft.com/en-us/library/jj219455.aspx#DeploymentTypes,Deploy a multi-server, load-balanced Office Web Apps Server farm;
  3. Knockoutjs 我使用的不是很深入,模板语言不是很强大(写法很怪异,数据绑定的对象必须要自己包装一下),没有自己的路由等等原因吧;
  4. 不知道你说 复杂业务开发 是指复杂到什么程度?Worktile 暂时没有遇到靠 Node.js 解决不了的问题,就算遇到,也应该能找到合适的解决方案,最后找不到的话,也许会考虑其他语言,但是目前没有遇到,所以不会考虑这些事情;
  5. Node.js 做单元测试还算方便吧,可以采用 mochajs

多谢你对 Worktile 技术上的关心!

#8楼 @徐海峰: hi,这个box服务在哪里可以找到,网上没有找到啊,能告知下吗,谢谢

#30楼 @王子: 这个Box是我们自己写的一个服务做权限验证,上传下载文件功能

真是很棒,学习了,最近在学习react,也想实现端对端

peter peter
11-16 23:05 #33

很棒。提个问题哈,一般不是说不建议angularjs和jquery混用么?

#31楼 @徐海峰: 可以请教一下,这样的架构,一台Node的ECS配置大概多少?

#31楼 @徐海峰: BOX服务也是node写的?

路由直接用的是angular的路由吧,状态数据同步也是用的angular的双向绑定吧,然后同步到服务端,长连接?

very nice +1

staid staid
06-15 17:34 #38

推送服务负责前后台交互,不是有$http吗?为什么不用这个呢