因缓存机制产生的数据实时性问题

问题描述:

项目和测试环境都存在门户换肤问题。

现象:

1、设置新的主题时,样式没有彻底换过来。

2、同一个浏览器上切换账号登陆门户后, 门户还是会使用之前登陆用户的主题样式。

 

 

图1.01 用户一登陆的主题样式

 

1.02 用户二登陆后的主题样式

问题分析:

1、浏览器的缓存机制:

一般浏览器都会存有自己的缓存,这是用户自己私有缓存。浏览器作为代理服务器,可以减少前端与服务器的一些不必要的交互,当数据没有更新的时候,浏览器就代替服务器返回上缓存的有的数据,提高了前端的响应速度。

当浏览器收到数据的请求时,http报文时,会对报文进行解析,并提取url和各种首部,然后查看缓存中是否有本地副本,如果没有就请求服务器获得副本,如果缓存中有副本的新鲜度过了,则会主动请求服务器看是否要更新,然后缓存变创建响应报文响应客户端,并记录下日志。

 

2、浏览器的缓存问题:

对于缓存,浏览器一个来自前端的请求的处理过程如下图所示:

 

图1.04 处理缓存的流程图

文本的新鲜度可以通过以下五种方式来定义缓存:

1.cache-control:no-store;

2.cache-control:no-chache;

3.cache-control:must-revalidate;

4.cache-contro:max-age;

5.附加Expires过期日期到响应中去。

也可以不加附加信息,让缓存自己确定文本副本的过期日期。

 

关于副本的验证,可以通过往报文中添加特殊的条件首部,而缓存验证的首部有If-Modified-Since:DateIf-None-Match:tags两种,If-Modified-Since:Date是指如果从指定日期之后文档被修改过了,就执行请求的方法,而If-None-Match:tags则是服务器为文档提供特殊的标签,类似序列号,当已缓存的标签和服务器文档中的标签有所不同,就会执行所请求的方法。在项目中用的方法是前者,如下图所示:

 

图1.03 home.css的请求

 

 

 

 

当在文本副本的有效期过后,浏览器会向服务器再核对文本的新鲜度,也就是上图1.03的服务器再验证,规则是上述说的If-Modified-Since:Date或者If-Modified-Since:Date。如果在服务器的文本内容没有改变,则会返回304响应,并对新鲜度进行更新。如果改变了则返回带有新文本内容的200响应,并将文本内容放入缓存中提供给客户端。在项目中,由于缓存的是一开始的登陆者的样式缓存,换了登陆者时,这时候浏览器进行再验证的时候,由于验证的文本是缓存中的上一个登陆者的验证文本,而在服务器中此写文本是没有改变的,因此服务器返回的响应时304响应,如下图所示:

 

         

 

所以浏览器会一直用之前上个登陆者用的样式文件缓存,所以才有主题用的还是之前的样式的问题。因此我们需要在登陆加载到主页面的时候,强制绕过浏览器缓存直接请求服务器刷新文本数据,同时也更新服务器缓存的副本。

 

问题解决方案:

思路:利用window.location.reload(true)方法,绕过浏览器缓存,强制向服务器请求样式

做法:在home.jsp中内嵌iframe用于强制刷新样式文件

$(window).load(function() {

 $("#loadCssFrame").contentWindow.location.reload(true);

});

好处:在需要的时候,刷新样式文件,在业务系统操作界面上,不需要加载样式文件

缺点:在home.jsp会加载多余的样式文件

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Python中使用缓存和队列可以有效处理实时数据。下面是一个基本的示例,展示如何使用缓存和队列来处理实时数据: ```python import time from queue import Queue # 创建一个队列用于缓存数据 data_queue = Queue(maxsize=100) # 设置队列最大容量 # 创建一个线程或进程来接收实时数据,并将数据放入队列 def data_receiver(): while True: # 模拟接收实时数据 data = receive_data() # 将数据放入队列,如果队列已满则阻塞等待 data_queue.put(data) # 创建一个线程或进程来处理队列中的数据 def data_processor(): while True: # 从队列中获取数据,如果队列为空则阻塞等待 data = data_queue.get() # 处理数据 process_data(data) # 示例函数:模拟接收实时数据 def receive_data(): # 假设每隔1秒接收一次数据 time.sleep(1) data = "Real-time data" return data # 示例函数:处理数据 def process_data(data): print("Processing data:", data) # 创建并启动数据接收线程或进程 data_receiver_thread = threading.Thread(target=data_receiver) data_receiver_thread.start() # 创建并启动数据处理线程或进程 data_processor_thread = threading.Thread(target=data_processor) data_processor_thread.start() ``` 在上面的示例中,我们使用了一个`Queue`对象作为数据缓存队列。数据接收线程周期性地模拟接收实时数据,并将数据放入队列中。数据处理线程则从队列中获取数据,并进行相应的处理。通过使用缓存队列,即使数据接收和处理的速度不同步,也能保证数据的连续性和实时性。 需要注意的是,缓存和队列的大小需要根据实际情况进行合理设置。如果队列太小,可能会导致数据丢失;如果队列太大,可能会占用过多的内存。根据数据产生的速率和处理的能力,选择适当的大小。 另外,以上代码仅为示例,实际情况下可能需要根据具体需求进行适当的修改和扩展。例如,可以添加错误处理、线程同步等机制来提高代码的健壮性和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值