乐码范的网站架构设计

2020-04-04大约27分钟

乐码范是一个小型的网站,目前主要是一个个人业余项目。目标主要是利用最新的前端技术,实现一个对用户友好、高质量的在线编程学习网站。虽然是一个小型网站,但麻雀虽小,五脏俱全,自己在做的过程中,也让自己可以接触到大项目里接触不到的方方面面,让自己的知识和思考更加全面。由于这是一个免费的网站,个人目前主要是依靠兴趣来开发和维护,因此,如何从节省运营成本,也是个重点。

网站设计一路,经过了几次大的架构变化。经历过几年时间,虽然中间也有少部分朋友一起进来开发一些功能,但大家更多都是出于兴趣在摸索,对商业化想得并不成熟,所以到后面就主要靠我自己坚持做下去了。一路走来,磕磕绊绊,走了不少弯路,现在可能也还是在弯路上,不过回过头去看,受益也是良多。在这篇文章里,把乐码范的技术演变过程回顾总结一下。

第一阶段:巨石架构

网站最开始是采用Python的技术栈。很简单,一句话:Flask + MySQL。

为什么是Python?

Python是一种很简洁的语言,很对个人胃口,不喜欢PHP、Ruby的语法,所以既然是自己的项目,自己喜欢才是最重要的;其次同等功能的情况下,代码量比Java语言要少很多,业余开发这个,节省时间也很重要。

为什么是Flask?

是Flask,不是django呢?几年前,像Flask这样的微框架已经比较流行了,好学、易用,可以节省学习时间!其次,很多事情可以自己掌握摸索,主要的组件比如SQLAlchemy也可以自己控制。

为什么是MySQL?

数据库采用的一直是MySQL,为什么不用PostgreSQL、SQL Server之类的?主要是相比之下,我自己对MySQL更熟悉,更流行,在公有云上MySQL实例的价格更便宜。考虑到由于内容需要积累,几年这个网站都不会有多少用户的情况下,MySQL更容易找到低配置、便宜的实例了。

最后,实现的是这个简单的架构:

图片

第二阶段:Web前后端同构+API服务

为什么要做前后端同构呢?这不是为了追求热点,而是有现实的考量。

现在做网站,不管后端什么技术,前端网页上是肯定要添加JavaScript做一些更丰富的功能,不能每个操作都要刷新页面。那么问题就来了,后端的Flask采用的是Jinja的模版,后端渲染出一个帖子列表之后,前端JS也还要能不依赖后端渲染帖子列表里的新的条目,怎么办,一般的办法只能是把Jinja模版里的内容,用JS再重新实现一遍了。重复的实现,不光是开发工作量的问题,还有后续维护的代价,一旦模版改了,需要确保所有的地方都要改。这个真的是很烦人。

这时候,前后端同构的好处就显现出来了。Node.js已经证明了JavaScript不光可以在浏览器端运行,也可以在服务器端运行,那么理论上我们只要用JavaScript,就能保证解决上面的问题,只需要一份代码!是不是很美好?确实,React.js的出现,使用了虚拟DOM,让SSR变得更容易,我们的确可以用一份代码,既可以在服务器端生成页面内容,也可以在浏览器端生成内容。

于是,乐码范就把Web页面的前后端完全用JavaScript重写,只用一种语言,包括服务器端和客户端。

为什么要做API服务呢?既有跟风的因素,也有现实的考量。之所以跟风,是因为把数据有关的业务逻辑封装成独立的API是比较吸引人的一种解决方案;现实的考量,则是因为当时Node.js还是6.x,没有async/await,虽然有promise,但是也不敢想跟数据库有关的操作都用JS来写是多么难看,加上ORM相关的库感觉也不怎么成熟,所以就仍旧用Python做API。

虽然仍旧使用Python,但是框架也变成了更快速、轻量、RESTful友好的Falcon + falcon-autocrud。由于不少的API都可以通过falcon-autocrud写少量代码进行直接生成,API的工作也简化了很多,后端的编码工作变得很少,主要的精力是花到了对业务需求本身的理解上。

于是,这个阶段就变成了Web前后端用Node.js,API端用Python的架构:

图片

第三阶段:Node.js统一前后端

按理说,到了第二个阶段,架构对于一个小网站应用已经足够了。但是按耐不住使劲作、瞎折腾的心,还是想了一些理由把API也切换到Node.js上。主要是这些理由:

  1. 做web和API需要在Node.js和Python之间切换,频繁这样子的话,脑子有点累;
  2. Python的性能一般,要提高性能,还要考虑Pypy等技术,不如JS天生的异步、有v8加持性能还不错;
  3. 在Windows上开发,本地用Python只能启一个单线程的开发服务器,连个普通的压力测试都做不了;
  4. Python用的是2.x的版本,但Python 2.x已经是过时的版本了,总有一天还要考虑升到Python 3.x;
  5. 发现Node.js有feathers这样设计优秀的框架,可以更好地替代Falcon + falcon-autocrud
  6. 自从Node.js v8开始,就支持async/await了,异步代码不再那么难看了。

基于上面的一些理由,花了一两周熟悉feathers,然后花了一两周用JS重写了大部分的Python写的API,大概重写了几十个API,整体开发速度感觉还是挺快的;因为feathers本身开放性的设计,及丰富的数据库适配器支持,用起来比Python的感觉更顺畅一些。当然,从一个浅度使用者来说,两个框架的入手难度是差不多的,除了语言上的差别,从一个框架转到另一个框架比较容易。

最终,就是全站都统一用JavaScript来实现了:

图片

除了上面提到的技术架构,还有部分细节可以说一下:

  • 网站使用memcached来缓存部分页面上的内容。为什么没用Redis? 对这样一个小站点用什么都一样,并且在阿里云上,我有个小容量、免费的memcached实例,免费!
  • 使用Less来实现页面样式。为什么不是Sass? Less简单、直观,我也不需要用到Sass那么多复杂的功能,足够用了。

结束语

这个业余的项目,前后做了几年,如果当做一个创业项目的话,估计要打个0分,不管从市场还有时间角度来说,都应对的不好,拖得时间太长了;如果从一个自我学习的角度来说,通过这个项目自己能够学到很多工作里用不到的东西,也算是个不错的成果。

大家如果有什么问题和建议,欢迎提出来!