1. 动静分离原理
我们在访问网站资源的时候,通常会将资源分成两种,一种是静态资源(前端的固定界面,比如图片,html页面等),这些资源无需后台程序处理;另一种是动态资源,这种资源通常需要后台服务器进行计算处理,再将计算结果返回给用户。由于静态资源是固定的,假设和动态资源放在同一台服务器上,那么用户每次访问静态资源的时候,都会将请求转发到应用服务器,大量占用应用服务器的资源。为了减少应用服务器的负载,采用了动静分离的方式来降低应用服务器的负载,如下图所示
所谓动静分离即将静态资源和动态资源放在不同的服务器上,静态资源放在nginx服务器上,动态资源放在应用服务器上。因为静态资源都是一些图片,固定的前端界面,因此可以由nginx服务器直接返回给用户,无需转发给后台的应用服务器,这样一来极大地降低了应用服务器的负载
2. 动静分离基本配置
这个配置很简单,就是增加一个location指向静态资源。举个例子,在html目录下新增一个static目录,将应用服务器的静态资源放static目录下即可
nginx的location匹配规则是从长到短,所以,nginx会优先匹配/static,匹配不到再匹配/,走代理转发。(如果静态资源存在多个目录,可以将location路径配置成正则匹配的形式,达到简化配置的效果)
总之,动静分离的逻辑很简单,就是将静态资源放在nginx服务器上,nginx配置好location后由nginx直接将静态资源返回给用户,非静态资源转发给应用服务器处理。
3. 一个简单例子
首先,写一串简单代码,搭建一个简单的服务,能够返回静态资源和动态资源,这段代码运行在我们的应用服务器上(实际场景静态资源和动态资源是有交互的,但是这里只是举个例子,所以没搞那么复杂)
const http = require('http');
const fs = require('fs');// 创建一个HTTP服务器
const server = http.createServer((req, res) => {// 处理静态资源请求console.log(req.url);if (req.url === '/static/static.html') {fs.readFile('static.html', (err, data) => {if (err) {res.writeHead(404, {'Content-Type': 'text/plain'});res.end('Not Found');} else {res.writeHead(200, {'Content-Type': 'text/html'});res.end(data);}});} else if (req.url === '/dynamic') {// 处理动态资源请求res.writeHead(200, {'Content-Type': 'text/plain'});res.end('This is a dynamic resource');} else {res.writeHead(404, {'Content-Type': 'text/plain'});res.end('Not Found');}
});// 监听端口
server.listen(8080, () => {console.log('Server running at http://localhost:8080/');
});
这里的静态资源就是一个static.html界面(内容自定义即可)
<!DOCTYPE html> <html> <head> <title>Simple HTML Page</title> </head> <body> <h1>Hello, World!</h1> <p>This is a simple HTML page.</p> </body> </html>
初始配置如下:
然后我们访问http://192.168.66.129/static/static.html就可以看到这个界面了
访问http://192.168.66.129/dynamic就可以看到动态资源了
然后,我们删除应用服务器上这个html界面,再取访问,会提示Not Found
此时,我们将这个资源放到nginx服务上,并修改配置如下:
增加了一个指向static目录下的location,static目录位于html目录下,里面有static.html文件,此时我们访问静态资源就可以成功访问了
动态资源还是不变,仍然由应用服务器返回
此时,静态资源是从nginx服务器返回的,不是从应用服务器返回的,也就是做到了动静分离。