# 静态态资源文件分离发布

 遇到的问题

多节点web服务器部署期间,访问静态资源可能会出现404。

为什么?

如果java进程我们以jar打包的方式打包文件并启动。假设有N多个pod,客户端请求会随机访问某个pod,有的请求访问为重启过的新pod,有的请求可能会访问到老的pod。

 

如图假设

 

LNMP 动静分离架构示意图 动静分离部署_静态资源

 

 

 

每次发布与部署都需要重启后端

java进程的重启会导致后端服务的波动。用户使用高峰时,在后端负载较高的情况下重启服务会有出现意外的可能性。 单纯静态资源文件的修改就可以在任意时段单独发布,且风险较低。 

 

# 解决思路

基本思路为静态资源文件与api分离。 

静态资源文件永远不会变化,客户端请求静态资源时,不从k8s里面对等的pod中获取,而是想个办法能从某个地方统一完整快速的取到所需的文件。 

nginx!稳定高效好用。

 

LNMP 动静分离架构示意图 动静分离部署_静态资源_02

 

 

# 动静分离带来的更多好处

1、 不用java来处理静态资源文件了。

tomcat等web服务虽然对静态资源都能处理,但是效率还是不如nginx。

参考
2、cookie free。访问静态资源文件一般都需要cookie信息,相同域名浏览器会主动携带cookie信息,当静态资源文件分离时,可将静态资源文件放到不同的域名下, 节省服务流量。静态资源文件分离能更方便的支持更换域名。

3、静态资源文件分离, 方便cdn的接入。 

 

 

# 前后端分离应用部署方案 

 通常单页应用只有一张入口页html,入口也引用了相应的静态资源文件。

先,部署后端,需要保证后端服务能兼容新老版本。

后,部署前端,需要保证新老资源文件都能获取到。

与webpack等前端应用已经将前端的资源文件打包好, 我们只需要把打包好的静态资源文件抽出来,发布到nginx服务器的静态资源文件目录下,当客户端的请求发现是静态资源文件时,直接通过nginx获取。

LNMP 动静分离架构示意图 动静分离部署_html_03

 

 

 

为什么要分两个目录?  每次发布静态文件的不同地方是什么?

前后端分离应用,前端部署对客户端而言,唯一变化的是入口页不同。入口页引的js,css等静态资源文件也可能不同。那我们是不是只要保证每次发布,入口页替换成新版,静态资源文件新老版本都能取到就可以了。

  • /data/html 首页不需要保留老页面,每次发布直接替换文件
  • /data/static等静态资源需要保留历史内容,每次发布追加内容

客户端如果缓存了入口页html怎么办?

客户端禁止缓存入口页html。

如何区分新版旧版js,css等静态资源文件?

js,css文件假设新老版本文件名字一致,那岂不是也被替换掉了?客户端旧html将会取到名字相同的新js,css。

非入口静态资源文件名字需要加入hash值。

 

nginx示例

location / {
          http://$mainUpstream;
          off;
    }
 
    location ~* \.(?:css|js|ico|gif|jpe?g|png|woff|ttf)$ {
            1y;
                "/data/static";
    }
 
    location ~*  index.html$ {
          Cache-Control "no-store";
              "/data/html";
    }

 注意点:gzip配置, 静态资源文件直接从nginx获取需要配置支持压缩的后缀名。

 

静态文件追加方式

rsync.

首页发布方式

scp直接复制

 

灰度环境链路

在此基础上,如何加入灰度环境?

灰度环境和生产环境的区别是什么,还是入口页html不同。

LNMP 动静分离架构示意图 动静分离部署_LNMP 动静分离架构示意图_04

 

 

  

nginx示例

 

map $cookie_SERVER $html {
    default "/data/html-product";
      "/data/html-grey";
   }
 
   location ~* /(index|index_grey)\.html$ {
          Cache-Control "no-store";
              $html;
    }

所有其他静态资源往/data/static文件夹里面追加,无论灰度还是正式环境都能正常获取。

 

发布时注意点

先追加静态文件,后替换首页入口html.

初次发布需要保证发布的静态资源文件与生产环境一致。

 

# freedmarker部署方案

 

freemarker项目与普通单页应用的不同点是什么? 

单页应用的首页html和静态资源打包好之后不会再可能改变了,freemarker无固定首页,html是后端动态渲染产生的,后端重启直接可能改变html,导致静态资源文件地址改变,或者出现新的请求。

静态文件分离思路一致,也是把css,js提取,nginx提前返回。

  • 先,部署静态资源文件,追加的方式部署,保证新旧js,css都能正常获取
  • 后,重启后端服务

 

LNMP 动静分离架构示意图 动静分离部署_css_05

 

 

后端请求有没有可能404

假设ftl存在这样一段代码,<form action="/login.shtml" method=“post”>

某次调整改成了。

在发布重启过程中,某次请求访问到了新节点,渲染出了/login2.shtml的模板html, 再次去访问/login2.shtml时访问到了老节点,还是会出现访问不到的情况。