为什么我执行了发布操作,但是线上的资源并没有更新?

  随着整个互联网时代的发展,前后端职能的分离,在过去的一段时间里,前后端各自仅只关注自己最擅长的领域。但是,随着“大前端”时代的到来,前端们又一次开始需要关注后端,或者前后端链接的问题了。

  本文起源于笔者的一次线上发布经历,事情的前因后果大概就如何题目所提到的,但是诡异的还不仅如此,当笔者执行了release操作之后,如果用之前访问的链接(如http://www.examplae.com)去访问执行了发布的web应用的话,会发现资源并没有更新,但是如果给这个链接加上一个参数(如http://www.example.com/?t=1),那么整个web应用则神奇的更新了,这到底是怎么回事呢?笔者开始了一次意外之旅。

  首先,笔者想到通过查看network(chrome dev tools)去看看What`s going on?

  我们都知道,一次完整的http请求过程由以下几部分构成:

    1、首先客户端发起请求建立连接,这个阶段会先发送header(当然在应用层协议之前,我们需要先构建通过传输层协议也就是常说的TCP,我们常说的三次握手的过程就发生在这个阶段)

    2、当服务端验证通过并允许通信之后,客户端开始发送请求(也即AJAX请求,或说XHR请求)

    3、然后服务端根据客户端请求的参数,对客户端的请求作出响应,返回响应报文(在响应结束后,连接通常会被关闭,当然header中有connnection:keep-alive除外)

  到底是哪一步出了问题呢?既然东西没有变化,那么多半就是缓存了吧?但是当笔者打开network的时候,却发现了更奇怪的东西

  

  http status code为200的情况下,出现了一些from disk cache和from memory cache的资源,难道是这些缓存的原因?难道笔者的问题也是这个原因引起的么?

  但是清空缓存之后,笔者发现,虽然同名的资源变成了正常的size显示,但是wep应用并没有得到更新。这个code为200的奇怪的缓存似乎,并不是笔者问题的原因,不过这个code为200的缓存倒是引起了笔者进一步的兴趣。

  我们都知道,http status code的状态码常见的大概是有这几种:

    1XX 几乎没见过的表示临时响应,并且需要请求者继续执行操作(其实这个并不常见)

    200 请求成功,最常见的状态

    304 not modified,表示服务端验证发现没有任何修改,直接让客户端使用浏览器缓存

    404 not found,服务器没找到该页面

    403 forbidden,服务器主动拒绝了访问

     503 服务无法使用,服务出错也是这个code

  也即是说,常见的缓存都是指的304这个code,但是这个缓存偏偏是从200出来的,这倒是令笔者挺在意的,google了一番之后解释如下:

    code为200的请求可以简单的理解成客户端直接没有发起请求,而是根据上次请求时服务端下发的过期时间,做了过期校验(依赖头中的cache-control: max-age字段和expires字段),在不清除缓存的前提下直接使用客户端的缓存

    而与之对应的code为304的请求则是客户端依然发起了请求,请求到达服务端之后,服务端检测发现并没有内容修改,则返回304,让客户端使用缓存。

  到这从network中能查找的线索基本已经用尽了,笔者觉得需要往更深入的地方去找了。

  然后,由于可见部分的原因已经排除,那么笔者觉得就需要往不可见的方向上去探寻原因了。对前端而言,透明的自然是服务端,但是服务端发布又有什么不同呢?笔者试着对比了之前的发布的场景:

  第一种的web应用实际上是依托于一个.net项目的,每次发布,.net项目和静态资源走单独的发布通道release,每次发布时都会通过时间戳的方式生成不同的静态资源版本,以免产生缓存,这个在实际运用中并没有出现过缓存的问题;

  第二种的发布流程实际上是发布的是一个基于webpack打包的纯静态项目,所有的静态资源每次release的名字几乎都是不一样的(除了那些静态的公共资源以外)来保证不会缓存,虽然设想得很好,但是这样发布的web应用出现了笔者遇到的缓存问题。

  看到这里笔者似乎并没有发现什么不同,但是等等,有一个很重要的区别,第二种发布方式html有关的缓存该怎么办呢?第一种方式是基于http请求的,服务端代码更新了对应的cshtml也买你就会得到更新,但是第二种方式则不是,html的缓存更新之前会一直存在,那不就是缓存不更新的原因么?即使静态资源每次都更新了,但是html的缓存却没有更新,用户访问了旧的html拉取了就的静态资源,得到了旧的页面。。

  那么问题找到了,但是具体出现在哪呢?

  最后,笔者顺藤摸瓜,在确认了只出的服务并没有缓存的前提下,能产生缓存就只剩下CDN了。

  问题的答案最后是这样的:当笔者release了最新的v2之后,笔者通过旧的链接访问,浏览器发现有DNS缓存,然后CDN会将上次请求web站点的缓存内容直接返回给客户端,所以产生了笔者虽然release v2但是访问的web应用的内容,仍然是v1的情况;当笔者更换了链接之后,由于CDN并没有关于该链接的缓存,也即没有缓存的内容,于是请求了web站点去获取内容,将其返回给客户端,于是v2便可以访问了。

  在日常的工作中,我们常常会碰到一些奇奇怪怪的问题,有时候我们并没有时间去将它们一一解决,我们会用自己的方式“巧妙”的绕开它,但是如果一直绕着走,最终,我们将一无所获。

  勇敢的直面生活中的苦难,不正是生活最有意思的一部分么?(哪怕是在后面复盘XD)

后记:

  1、在以往的时代,后端离前端其实很远,但是随着时代的更迭,node的出现,我们对后端的认知也一步步深入,更多的,已有的解决方案甚至都不能满足我们的需求(例如内部通信的场景,如果我们仍使用http的协议的话,由于量级与对外时的数量有着很大的区别,且http协议中关于安全验证和很多header透传的处理并不适用于内部通信的场景,使我们不得不基于TCP协议自己重新实现一次类http的通信过程)

  2、http其实都算是一个过去时了,http2也意味着新时代的到来,无论是数据传输格式的多样化(从文本到二进制),头部压缩(解决老大难的header体积过大的问题),多路复用(http1.x的pipeline会照成多请求的阻塞,并不是真正的并发),以及server push,都是对http1.x诸多诟病的扩展,想了解更多的话可以参考HTTP2的世界,笔者就不再展开了。

  其实,写到这里,笔者想起了刚上本科的,第一节专业基础课,一位教程序设计基础的老教授说的一段话:

  “同学们,当你们踏入计算机这个行业,就已经注定你们需要终身学习了,所以,你们做好准备了么?也许,通过这门课的学习,你们就已经可以实现任何你们想要的功能了,但是实现往往只是第一步,后面的路,还远着呢。”

  其实,回过头来反观自己的生活,又何尝不是处于一个始终、或说终身学习的过程之中呢?

   

时间: 2024-10-09 20:49:39

为什么我执行了发布操作,但是线上的资源并没有更新?的相关文章

发布或重启线上服务时抖动问题解决方案

发布或重启线上服务时抖动问题解决方案 一.问题描述       在发布或重启某线上某服务时(jetty8作为服务器),常常发现有些机器的load会飙到非常高(高达70),并持续较长一段时间(5分钟)后回落(图1),与此同时响应时间曲线(图2)也与load曲线一致.注:load飙高的初始时刻是应用服务端口打开,流量打入时(load具体指什么可参考http://www.cnblogs.com/amsun/p/3155246.html). 图1 发布时候load飙高 图2 发布时候响应时间飙高 二.问

线上操作与线上问题排查实战

转自:https://mp.weixin.qq.com/s?__biz=MjM5ODYxMDA5OQ==&mid=2651960323&idx=1&sn=e04af14d2ebf939133869e0f18bb0dd1&chksm=bd2d01df8a5a88c98c3cb94a99334a16b372fd997f36bc757a38bb44b70d977797fa840064dc&mpshare=1&scene=23&srcid=0816Yl1Rl

(转) 发布或重启线上服务时抖动问题解决方案

转自 http://www.cnblogs.com/LBSer/p/3703967.html 相关: load.jstack.Java编译.Java运行模式 一.问题描述       在发布或重启某线上某服务时(jetty8作为服务器),常常发现有些机器的load会飙到非常高(高达70),并持续较长一段时间(5分钟)后回落(图1),与此同时响应时间曲线(图2)也与load曲线一致.注:load飙高的初始时刻是应用服务端口打开,流量打入时(Load指的是运行队列(run-queue)的长度:L=等

TFS线上生成环境发布历程

继前文 TFS在项目中Devops落地进程(上) TFS在项目中DevOps落地进程(下) 自从之前将开发环境使用TFS进行了自动化之后,就享受在此成果中,其他后续进度就停顿了好一段时间. 毕竟在我们这对于开发而言,做出代码交出发布包事情就结束了,而我们的TFS已经完美的将这个流程给自动化掉了. 本文将聚焦在TFS发布到线上生产环境中所做的一些工作和实践,如果只是纠结于如何使用TFS可以参考上面的2个链接. 之前的线上发布流程 说下我们大概的背景,我们的程序上线流程目前还是相对传统一些,大体是:

vCenter线上操作磁盘扩容

以下截图是生产机器,目前是有一块盘,且根分区是/dev/sda3,因为磁盘不足,需要备份的数据要远远超过此时的空间大小:正常情况下,是可以新增硬盘硬盘作为备份 但是作为宿主机下的虚机,因为一些不规范的操作,我们直接在线扩容,导致新增的磁盘空间没有生效 新增之后,我们通过fdisk -l查看,硬盘空间并未变化,此时我们reboot重启生效 我们可以发现,虽然重启之后,只是硬盘大小生效了,此时我们需要创建分区,并且挂载才能使新增的200G空间剥离出来! 接下来是格式化/dev/sda4分区,如果我们

线上问题排查

线上操作与线上问题排查实战 技术同学需要经常登录线上的服务器进行操作,58到家架构部/运维部/58速运技术部,联合进行了一次线上操作与线上问题排查实战演练,同学们反馈有收获,特将实战演练的问题和答案公布出来,希望对大家也有帮助. 一.了解机器连接数情况 问题:1.2.3.4的sshd的监听端口是22,如何统计1.2.3.4的sshd服务各种连接状态(TIME_WAIT/ CLOSE_WAIT/ ESTABLISHED)的连接数. 参考答案: netstat -n | grep 1.2.3.4:2

【MVC2】发布到IIS7.5上后Session为null

MVC2代码「Session.IsNewSession」在VS中可以正常执行,发布到IIS7.5上之后Session为null导致出错. if (Session.IsNewSession) { ...... } 解决方法是在Web.config中追加如下设定: <configuration> <system.webServer> <modules> <remove name="Session"/> <add name="S

数据库操作:编辑表向线上表更新

需求:表edit需要将数据更新到表release,里边会涉及增删改操作,如何做比较好??? 1.edit表是最新的数据,release表是线上表. 2.会有不同的容器调用release表,也就是需要解决容器之间的锁的问题,其他容器只有读操作,正在操控的容器有读写操作,因为更新操作无法做到原子,所以在操作之间可能会遇到其他容器查询为空或读了一半等出错的状态 a.   在另外一张表version里,打上到底使用哪张表.   即读取数据的时候是在两个表之间来回跳跃的 以下操作在我们做update的容器

不借助工具在浏览器中通过Web API执行Dynamics 365操作(Action)实例

摘要: 本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复262或者20170727可方便获取本文,同时可以在第一间得到我发布的最新的博文信息,follow me!我的网站是 www.luoyong.me . 我的上一篇文章 利用Fiddler修改请求信息通过Web API执行Dynamics 365操作(Action)实例 借助了Fiddler工具,你可能会问,如果不借助工具,我只有浏览器可行吗?这就是本文要讲述的. 我们知道一般浏览器按F12会出来开发者工具,我们以Chrome为例来讲解