​尽管没有特别的动力去构建一个全新的CMS,但是我还是愿意去撰文一篇来书写如何去做这样的事——编辑-发布-开发分离模式是如何工作的。微服务是我们对于复杂应用的一种趋势,编辑-发布-开发分离模式则是另外一种趋势。在上篇文章《Repractise架构篇一: CMS的重构与演进》中,我们说到编辑-发布-开发分离模式。

系统架构

如先前提到的,Carrot使用了下面的方案来搭建他们的静态内容的CMS。

在这个方案里内容是用Contentful来发布他们的内容。而在我司ThoughtWorks的官网里则采用了Github来管理这些内容。于是如果让我们写一个基于Github的CMS,那么架构变成了这样:

或许你也用过Hexo / Jekyll / Octopress这样的静态博客,他们的原理都是类似的。我们有一个代码库用于生成静态页面,然后这些静态页面会被PUSH到Github Pages上。

从我们设计系统的角度来说,我们会在Github上有三个代码库:

  1. Content。用于存放编辑器生成的JSON文件,这样我们就可以GET这些资源,并用Backbone / Angular / React 这些前端框架来搭建SPA。
  2. Code。开发者在这里存放他们的代码,如主题、静态文件生成器、资源文件等等。
  3. Builder。在这里它是运行于Travis CI上的一些脚本文件,用于Clone代码,并执行Code中的脚本。

以及一些额外的服务,当且仅当你有一些额外的功能需求的时候。

  1. Extend Service。当我们需要搜索服务时,我们就需要这样的一些服务。如我正考虑使用Python的whoosh来完成这个功能,这时候我计划用Flask框架,但是只是计划中——因为没有合适的中间件。
  2. Editor。相比于前面的那些知识这一步适合更重要,也就是为什么生成的格式是JSON而不是Markdown的原理。对于非程序员来说,要熟练掌握Markdown不是一件容易的事。于是,一个考虑中的方案就是使用 Electron + Node.js来生成API,最后通过GitHub API V3来实现上传。

So,这一个过程是如何进行的。

用户场景

整个过程的Pipeline如下所示:

  1. 编辑使用他们的编辑器来编辑的内容并点击发布,然后这个内容就可以通过GitHub API上传到Content这个Repo里。
  2. 这时候需要有一个WebHooks监测到了Content代码库的变化,便运行Builder这个代码库的Travis CI。
  3. 这个Builder脚本首先,会设置一些基本的git配置。然后clone Content和Code的代码,接着运行构建命令,生成新的内容。
  4. 然后Builder Commit内容,并PUSH内容。

这里还依赖于WebHook这个东西——还没想到一个合适的解决方案。下面,我们对里面的内容进行一些拆解,Content里面由于是JSON就不多解释了。

Builder: 构建工具

Github与Travis之间,可以做一个自动部署的工具。相信已经有很多人在Github上玩过这样的东西——先在Github上生成Token,然后用travis加密:

travis encrypt-file ssh_key --add

加密后的Key就会保存到.travis.yml文件里,然后就可以在Travis CI上push你的代码到Github上了。

接着,你需要创建个deploy脚本,并且在after_success执行它:

after_success:- test $TRAVIS_PULL_REQUEST == "false" && test $TRAVIS_BRANCH == "master" && bash deploy.sh

在这个脚本里,你所需要做的就是clone content和code中的代码,并执行code中的生成脚本,生成新的内容后,提交代码。

#!/bin/bash

set -o errexit -o nounsetrev=$(git rev-parse --short HEAD)cd stage/git init
git config user.name "Robot"
git config user.email "robot@phodal.com"git remote add upstream "https://$GH_TOKEN@github.com/phodal-archive/echeveria-deploy.git"
git fetch upstream
git reset upstream/gh-pagesgit clone https://github.com/phodal-archive/echeveria-deploy code
git clone https://github.com/phodal-archive/echeveria-content content
pwd
cp -a content/contents code/contentcd codenpm install
npm install grunt-cli -g
grunt
mv dest/* ../
cd ../
rm -rf code
rm -rf contenttouch .if [ ! -f CNAME ]; thenecho "deploy.baimizhou.net" > CNAME
figit add -A .
git commit -m "rebuild pages at ${rev}"
git push -q upstream HEAD:gh-pages

这就是这个builder做的事情——其中最主要的一个任务是grunt,它所做的就是:

grunt.registerTask('default', ['clean', 'assemble', 'copy']);

Code: 静态页面生成

Assemble是一个使用Node.js,Grunt.js,Gulp,Yeoman 等来实现的静态网页生成系统。这样的生成器有很多,Zurb Foundation, Zurb Ink, Less.js / lesscss.org, Topcoat, Web Experience Toolkit等组织都使用这个工具来生成。这个工具似乎上个Release在一年多以前,现在正在开始0.6。虽然,这并不重要,但是还是顺便一说。

我们所要做的就是在我们的Gruntfile.js中写相应的生成代码。

    assemble: {options: {flatten: true,partials: ['templates/includes/*.hbs'],layoutdir: 'templates/layouts',data: 'content/blogs.json',layout: 'default.hbs'},site: {files: {'dest/': ['templates/*.hbs']}},blogs: {options: {flatten: true,layoutdir: 'templates/layouts',data: 'content/*.json',partials: ['templates/includes/*.hbs'],pages: pages},files: [{ dest: './dest/blog/', src: '!*' }]}}

配置中的site用于生成页面相关的内容,blogs则可以根据json文件的文件名生成对就的html文件存储到blog目录中。

生成后的目录结果如下图所示:

 .
├── about.html
├── blog
│   ├── blog-posts.html
│   └── blogs.html
├── blog.html
├── css
│   ├── images
│   │   └── banner.jpg
│   └── style.css
├── index.html
└── js├── jquery.min.js└── script.js7 directories, 30 files

这里的静态文件内容就是最后我们要发布的内容。

还需要做的一件事情就是:

grunt.registerTask('dev', ['default', 'connect:server', 'watch:site']);

用于开发阶段这样的代码就够了,这个和你使用WebPack + React 似乎相差不了多少。

编辑-发布-开发分离

在这种情形中,编辑能否完成工作就不依赖于网站——脱稿又少了 个借口。这时候网站出错的概率太小了——你不需要一个缓存服务器、HTTP服务器,由于没有动态生成的内容,你也不需要守护进程。这些内容都是静态文件,你可以将他们放在任何可以提供静态文件托管的地方——CloudFront、S3等等。或者你再相信自己的服务器,Nginx可是全球第二好(第一还没出现)的静态文件服务器。

开发人员只在需要的时候去修改网站的一些内容。

So,你可能会担心如果这时候修改的东西有问题了怎么办。

  1. 使用这种模式就意味着你需要有测试来覆盖这些构建工具、生成工具。
  2. 相比于自己的代码,别人的CMS更可靠?

需要注意的是如果你上一次构建成功,你生成的文件都是正常的,那么你只需要回滚开发相关的代码即可。旧的代码仍然可以工作得很好。

其次,由于生成的是静态文件,查错的成本就比较低。

最后,重新放上之前的静态文件。

你不再需要动态网页——编辑-发布-开发分离相关推荐

  1. 编辑-发布-开发分离: 静态API设计

    周末在计划着Growth的最外一层,即解决方案的时候,想着自己要做一个静态的API--即基于JSON与GitHub的API. 在之前的那篇<编辑-发布-开发分离:git作为NoSQL数据库> ...

  2. Linux部署动态网页,Nginx发布支持动态配置的开源Web服务器

    NGINX最近发布了NGINX Unit 1.0版.NGINX Unit是一种开源的Web和应用服务,它支持远程配置和动态配置,使得配置上的更改不会对服务造成中断.Unit 1.0还支持在同一实例中运 ...

  3. 简单的动态网页设计及开发(关联数据库)

    留言板网页 源码: (1)db.php <?php//连接数据库$mysqli=new mysqli("localhost","root","& ...

  4. 动态网页怎样才能被搜索引擎收录

    动态网页怎样才能被搜索引擎收录动态网页怎样才能被搜索引擎收录呢?其实动态网页被搜索引擎收录和静态网页被收录的原理是一样的,只是因为两种网页表现形式的差异造成了搜索引擎索引这些文件的方式有所不同,动态网 ...

  5. Python-Flask入门,静态文件、页面跳转、错误信息、动态网页模板

    Python-Flask入门及路由基础请参看Python-Flask入门,路由route.项目启动.修改网址端口.获取URL地址和参数.Form数据_无敌路路帅气的博客-CSDN博客 本节重点讲述静态 ...

  6. JavaWeb开发---B/S和C/S模式 tomcat服务器 Tomcat项目部署和发布 静态网页和动态网页 tomcat对web项目的目录要求 使用idea开发工具创建web项目 设置默认首页

    目录 1. B/S和C/S模式 1.1 C/S模式 1.2 B/S模式 1.3 B/S和C/S区别 2.服务器 3.web 服务器 3.1.IIS 3.2.Tomcat 3.3.Zeus 3.4.Ng ...

  7. JAVA动态网页开发:框架

    目标: 本文主要教会大家如何搭建一套简单的Eclipse开发框架,为快速开发网页项目做准备. 学习前提: 安装好Eclipse开发环境,懂得简单的配置,新建和发布项目. 学习案例: 开发一个登录功能, ...

  8. python+selenium+phantomJS爬取国家地表水水质自动监测实时数据发布系统——动态网页爬虫

    一.关于phantomjs 1.介绍 PhantomJS是一个为自动化而生的利器,它本质上是一个基于webkit内核的无界面浏览器,并可使用JavaScript或CoffeeScript进行编程.由于 ...

  9. 第四本书第1章 动态网页开发基础、

    一.动态网页开发基础 1.动态网页:能跟用户进行交互的网页,能够处理用户请求的网页 2.B/S架构:浏览器:客户端零维护:与操作系统平台的关系最小化:在响应速度和安全性上需要花费更多设计成本 C/S架 ...

最新文章

  1. mysql中正则表达式的用法_Mysql中正则表达式Regexp常见用法
  2. go标准命令详解0.1 go build
  3. R-3.1.1 编译安装
  4. Sequence 带来的更多乐趣
  5. 转载 300年前的黑色“巫女”
  6. maya怎么贴膜_maya怎么渲染成白膜?
  7. 函数二的变量作用域,多函数执行,返回值,函数参数,拆包,引用
  8. fbx模型加载的材质球路径
  9. 第四章 Linux命令
  10. glide从入门到精通使用
  11. Django SimpleCMDB API
  12. JDBC 学习笔记(三)—— 数据源(数据库连接池):DBCP数据源、C3P0 数据源以及自定义数据源技术...
  13. HG255D[OpenWrt]刷机
  14. c语言程序设计商品库存管理系统,《C语言课程设计商品库存管理系统》.doc
  15. 虚拟机体验NAS私人云(第四篇):虚拟机安装群晖DSM7.01系统(附赠新版DS918+和DS3615xs启动映像)
  16. 『开发技巧』MacbookM1芯片深度学习环境配置最全教程:简明安装开发TensorFlow与PyTorch
  17. 尚学堂马士兵_Struts2下载完成
  18. 怎样正确安装Photoshop CS6破解版【图文教程】
  19. django email邮箱
  20. 狂神说Java系列视频教程之docker(记录到swarm安装)

热门文章

  1. Initialization failed for Block pool registering (Datanode Uuid unassigned)
  2. OK外呼中心配置的电话系统规则
  3. android查看wifi记录仪,行车记录仪wifi通用app安卓版
  4. 一段代码——使用rdkit函数生成分子文件的3D构象
  5. 基于CNN的花卉识别
  6. 500是什么php,HTTP 500,该怎么解决
  7. 高仿马蜂窝旅游头像泡泡动画
  8. Paper之EfficientDet: 《Scalable and Efficient Object Detection—可扩展和高效的目标检测》的翻译及其解读
  9. google浏览器如何添加收藏夹
  10. Python设计俄罗斯方块