├── .gitignore
├── index.html
├── docs
├── intro
│ ├── index.html
│ ├── 1.png
│ └── README.md
└── index.html
├── README.md
├── package.json
└── LICENSE.txt
/.gitignore:
--------------------------------------------------------------------------------
1 | .*
2 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 | docs/index.html
--------------------------------------------------------------------------------
/docs/intro/index.html:
--------------------------------------------------------------------------------
1 | ../index.html
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | https://elemefe.github.io/clouding/docs/intro/
2 |
--------------------------------------------------------------------------------
/docs/intro/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ElemeFE/clouding/HEAD/docs/intro/1.png
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "clouding",
3 | "version": "1.2.5",
4 | "description": "A MODULARIZATION SOLUTION OF FRONTEND ",
5 | "main": "jinkela.js",
6 | "author": "YanagiEiichi (yanagieiichi@web-tinker.com)",
7 | "license": "MIT",
8 | "scripts": {
9 | "test": "ui-tester-start tests"
10 | },
11 | "reciperConfig": {
12 | "name": "Jinkela",
13 | "darkColor": "#333",
14 | "normalColor": "#666",
15 | "primaryColor": "#000",
16 | "logoUrl": "//fuss10.elemecdn.com/9/ca/f88b429d6278cdf69e0027dfea51ejpeg.jpeg",
17 | "languages": [
18 | "xml",
19 | "markdown",
20 | "bash",
21 | "javascript"
22 | ]
23 | },
24 | "devDependencies": {
25 | "ui-tester": "~1.1.2"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) <2016>
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/docs/intro/README.md:
--------------------------------------------------------------------------------
1 | ## 解决的问题
2 |
3 | 消除前端项目部署与业务量之间的关系
4 |
5 | 无论业务量增加多少倍,前端所需的硬件资源都是额定的
6 |
7 | ## 背景
8 |
9 | 很早以前 Web 开发是不区分前后端的,HTML 由服务器动态生成,项目部署只是服务器端的代码发布而已。
10 | 后来浏览器提供了越来越多的 API 支持,前端开发逐渐复杂起来。
11 | 于是诞生了专注于浏览器端程序开发的「前端」这个分支。
12 |
13 | 虽然现在前后端分离开发已经非常普遍,但是在很多古老的程序架构下,它们只是实现了开发人员的职责分离。
14 | **这种前后端混部的模式会带来巨大的风险。**
15 |
16 | 1. 后端发布的风险
17 |
18 | 前端的变更往往是小而频繁的,也许只是修改一个文案或一个颜色。
19 | 在前后端混部的情况下,这些变更都需要所有代码重新编译重新发布,发布过程的每个环节都是风险。
20 | 比如编译过程中的某个依赖的版本错误,或者发布后重启服务导致本地缓存丢失,甚至是发布过程中网络抖动等。
21 |
22 | 2. 服务器负载的风险
23 |
24 | 有一类前端页面是属于纯展示性的,完全不涉及数据交互。
25 | 而且出于营销等目的,它们的业务量会非常巨大,而且难以预估。
26 | 这类页面带来的流量很可能是服务器无法接受的。
27 |
28 | **真正的前后端分离是后端完全 API 化,前后端分别开发和部署,互不干扰。**
29 | 一个前端项目可能调用多套后端 API,一套后端 API 也可能提供给多个前端项目使用。
30 |
31 | 前后端完全分离后我们可以观察到,数据的变更不会导致前端的变更。
32 | 这意味着**前端更趋向于「资源型产出」,而不是后端那样的「运营型产出」**。
33 | 举例来说就是一个项目的业务量增加了 100 倍,后端开发人员可能要一直调整架构变更方案,而前端开发人员可以和设计师一样完全使用同一套东西。
34 |
35 | 既然前端可以是资源型产出,那么就可以和资源类部署结合起来。
36 | **这就是 Clouding 这套方案**。
37 |
38 | ## 零机器
39 |
40 | 所谓的「零机器」并不是完全没有服务器,理论上必须要有服务器才能跑 http 服务。
41 | 这里的「零机器」是指没有任何与业务量相关的机器。
42 |
43 | 一般后端服务的机器数量与业务量是有关的,大多数程线性关系。
44 | 而资源类型的部署可以使用 CDN,对源站的压力只有 CDN 节点乘以资源量而已,这些都是常量。
45 |
46 | ## 部署原理
47 |
48 | **Clouding** 方案的核心其实就是把前端项目完全部署在 CDN 上。
49 |
50 | 由于 CDN 总是需要一个中心数据源,所以这个过程需要一个源服务器(下图中的 OSS)。
51 |
52 |
53 |
54 | OSS 可以是第三方的服务,也可以是自建的。
55 |
56 | 整个工作流畅大概有这么几个步骤:
57 |
58 | 1. 发布系统将代码推送到 OSS
59 | 2. 调用 CDN 的 API 清缓存
60 | 3. 由于缓存被清空,CDN 被请求后回到 OSS 取资源
61 |
62 | 有些云服务提供商同时提供了 OSS 和 CDN 服务,并且提供了 OSS 到 CDN 的自动同步功能。
63 | 如果使用这种方式我们要做的只是将代码发布到 OSS,其它事情全交给云提供方的程序搞定。
64 |
65 | ## 缓存设置
66 |
67 | **Clouding** 方案中最关键的参数配置就是缓存时间了。
68 | 我们不仅要关心资源在客户端缓存多久,还得关心资源在 CDN 节点缓存多久。
69 | 这可以在响应的 Cache-Control 中分别使用 max-age 和 s-maxage 来配置。
70 | 由于 **Clouding** 的数据流向是主动的,我们主动调用 CDN 的 API 来清缓存,所以 CDN 到 源站的缓存可以设非常大。
71 | 也就是 s-maxage 的取值非常大,可以设置个一年之类的时间。
72 |
73 | 至于客户端要缓存多久那就得看业务需求了。
74 | 如果前端项目构建时会自动给资源文件加版本号,那么我们可以针对 html 文件关闭缓存,对其它类型的资源文件开启一个非常大的缓存。
75 | 或者最坏的情况是完全关闭客户端缓存,让所有请求打到 CDN 节点。即便是这样也只是多出点流量而已,对源站并没有额外的压力。
76 |
77 | ## 前端项目改造
78 |
79 | **Clouding** 方案的难点并不是在部署上,而是对于前端项目的改造。
80 |
81 | 并不是任何前端项目都可以直接使用这套方案。
82 | 这套方案有许多局限性,在使用时前端项目可能是需要改造的。
83 | 下面我们逐个介绍。
84 |
85 | 1. URL 路由
86 |
87 | CDN 本身是为静态资源设计的,而静态资源 http 服务器通常被设计成 URL 与磁盘文件直接对应。
88 | 所以前端项目也只能使用此种方式来访问资源。
89 |
90 | 自从前端有了 History API 后,在前端圈有个非常普遍的做法。
91 | 让服务器将所有请求都指向同一个 html 文件,由前端自己处理路由并展示。
92 | 这种做法到 **Clouding** 上就不再适用了,或者即便有一些黑科技可以实现但也不建议使用。
93 |
94 | 前端业务如果希望自己维护 URL 与展示逻辑可以选择 QueryString 和 hash。而 QueryString 可能造成 http 无法 cache,所以这里推荐的方案是使用 hash。
95 |
96 | 2. 跨域 API 调用
97 |
98 | 即便是前后端分离,一些前端项目依然会通过服务器代理来调用后端 API 以解决跨域问题。
99 | 如果前端项目完全在 CDN 上,CDN 是无法帮你代理调用 API 的。
100 | 或者即便通过 CDN 从源站调用 API,这也会导致源站的负载变得与业务有关,违背了我们的理念。
101 | 所以 **Clouding** 方案中的前端项目需要完全跨域调用 API。
102 | 至于如何跨域,这就得根据自己的项目需求来考虑了。
103 | 现代浏览器对 CORS 的支持是不错的,大部分使用可以满足业务需求。
104 | 如果实在是要考虑低版本 IE 的话建议使用 jsonp。
105 |
--------------------------------------------------------------------------------