动静分离-前后端分离部署
# 静态态资源文件分离发布
遇到的问题
多节点web服务器部署期间,访问静态资源可能会出现404。
为什么?
如果java进程我们以jar打包的方式打包文件并启动。假设有N多个pod,客户端请求会随机访问某个pod,有的请求访问为重启过的新pod,有的请求可能会访问到老的pod。
如图假设
每次发布与部署都需要重启后端
java进程的重启会导致后端服务的波动。用户使用高峰时,在后端负载较高的情况下重启服务会有出现意外的可能性。 单纯静态资源文件的修改就可以在任意时段单独发布,且风险较低。
# 解决思路
基本思路为静态资源文件与api分离。
静态资源文件永远不会变化,客户端请求静态资源时,不从k8s里面对等的pod中获取,而是想个办法能从某个地方统一完整快速的取到所需的文件。
nginx! 稳定高效好用。
# 动静分离带来的更多好处
1、 不用java来处理静态资源文件了。
tomcat等web服务虽然对静态资源都能处理,但是效率还是不如nginx。
参考 https://www.cnblogs.com/wskwbog/p/10816345.html
2、cookie free。访问静态资源文件一般都需要cookie信息,相同域名浏览器会主动携带cookie信息,当静态资源文件分离时,可将静态资源文件放到不同的域名下, 节省服务流量。静态资源文件分离能更方便的支持更换域名。
3、静态资源文件分离, 方便cdn的接入。
# 前后端分离应用部署方案
通常单页应用只有一张入口页html,入口也引用了相应的静态资源文件。
* 先,部署后端,需要保证后端服务能兼容新老版本。
* 后,部署前端,需要保证新老资源文件都能获取到。
gulp与webpack等前端应用已经将前端的资源文件打包好, 我们只需要把打包好的静态资源文件抽出来,发布到nginx服务器的静态资源文件目录下,当客户端的请求发现是静态资源文件时,直接通过nginx获取。
为什么要分两个目录? 每次发布静态文件的不同地方是什么?
前后端分离应用,前端部署对客户端而言,唯一变化的是入口页不同。入口页引的js,css等静态资源文件也可能不同。那我们是不是只要保证每次发布,入口页替换成新版,静态资源文件新老版本都能取到就可以了。
- /data/html 首页不需要保留老页面,每次发布直接替换文件
- /data/static js,css等静态资源需要保留历史内容,每次发布追加内容
客户端如果缓存了入口页html怎么办?
客户端禁止缓存入口页html。
如何区分新版旧版js,css等静态资源文件?
js,css文件假设新老版本文件名字一致,那岂不是也被替换掉了?客户端旧html将会取到名字相同的新js,css。
非入口静态资源文件名字需要加入hash值。
nginx示例
location / {
proxy_pass http://$mainUpstream;
access_log off;
}
location ~* \.(?:css|js|ico|gif|jpe?g|png|woff|ttf)$ {
expires 1y;
root "/data/static";
}
location ~* index.html$ {
add_header Cache-Control "no-store";
root "/data/html";
}
注意点: gzip配置, 静态资源文件直接从nginx获取需要配置支持压缩的后缀名。
静态文件追加方式
rsync.
首页发布方式
scp直接复制
# 灰度环境链路
在此基础上,如何加入灰度环境?
灰度环境和生产环境的区别是什么, 还是入口页html不同。
nginx示例
map $cookie_SERVER $html {
default "/data/html-product";
0 "/data/html-grey";
}
location ~* /(index|index_grey)\.html$ {
add_header Cache-Control "no-store";
root $html;
}
所有其他静态资源往/data/static文件夹里面追加,无论灰度还是正式环境都能正常获取。
发布时注意点
先追加静态文件,后替换首页入口html.
初次发布需要保证发布的静态资源文件与生产环境一致。
# freedmarker部署方案
freemarker项目与普通单页应用的不同点是什么?
单页应用的首页html和静态资源打包好之后不会再可能改变了,freemarker无固定首页,html是后端动态渲染产生的,后端重启直接可能改变html,导致静态资源文件地址改变,或者出现新的请求。
静态文件分离思路一致,也是把css,js提取,nginx提前返回。
- 先,部署静态资源文件,追加的方式部署,保证新旧js,css都能正常获取
- 后,重启后端服务
后端请求有没有可能404?
假设ftl存在这样一段代码,<form action="/login.shtml" method=“post”>
某次调整改成了 <form action="/login2.shtml" method=“post”>。
在发布重启过程中,某次请求访问到了新节点,渲染出了/login2.shtml的模板html, 再次去访问/login2.shtml时访问到了老节点,还是会出现访问不到的情况。
如何解决?