关于blob对象(图片)的缓存和提取问题

问题描述

前段时间给客户做了一个会议签到系统系统中涉及到这么一个问题:用户签到的时候有一个页面显示当前签到人的照片和最近签到的6个人的照片,照片数据都以blob对象存储在数据库中的,为了在页面上显示照片,我直接写了一个servlet来处理照片的请求,servlet中直接把blob二进制流输出给jsp界面。jsp以<img src="/conference/image" height="280" width="200">的形式向servlet发送请求来获取照片servlet中以ServletOutputStream out = res.getOutputStream();Blob temp = photo.getPhoto();InputStream is = temp.getBinaryStream();byte buffer[] = new byte[256];while (is.read(buffer, 0, 256) != -1) {out.write(buffer);}out.flush();的形式响应。每当有人签到,jsp页面就自动刷新一次来获取新的6张照片这样设计有几个瓶颈1、照片本身大小比较大,每张都是200+k,每次刷新所有的照片都要重新到后台去获取,对网络的要求比较高,而且如果多个人同时使用这个页面刷新的话,更是问题2、每次请求的blob数据都需要到后台数据库中取数据,而且都是 并发的请求,对数据库的连接和数据库都有很大的压力,容易使服务down了试着改进过,因为每次请求的6张照片中正常情况有5张是重复的,所以我想用hashmap把查出来的结果缓存起来,下次有请求来了,如果在缓存中有了,就直接在缓存中取。没有再到数据库中取,缓存中到了一定数量,再把缓存全部清了,否则肯定会占用大量内存。但是这样又有问题,java的回收机制自动把我hashmap中的blob对象给清掉了。每次取到的persistence是有的可是到persistence中取blob却是空的了。所以jsp界面显示的照片都是空的。不知道有没有高人能提出一个好的解决方案。探讨探讨,如何改进。或者重新设计。不胜感激!问题补充:HashMap问题blob对象被清 是这样的HashMap本来就是放在单子实例中的,肯定也是staticpublic class AnalyseDAO extends BasicDAO {private static AnalyseDAO _instance= new AnalyseDAO();;public static AnalyseDAO getInstance() { if (_instance == null) { _instance = new AnalyseDAO(); } return _instance;}private static HashMap photohash = new HashMap();public TCifPhoto getCifPhoto(String stuempNo){if(photohash.size()>=50){ photohash.clear();}if(photohash!=null && photohash.get(stuempNo)!=null){ TCifPhoto tmp= (TCifPhoto)photohash.get(stuempNo); if(tmp.getPhoto()==null){ System.out.println("omg that's it lob is empty");}return tmp;}else{ Session s = getSession(); String sql = " from TCifPhoto cif where cif.stuempNo= '"+stuempNo+"'";try { Query q = s.createQuery(sql); List list = q.list(); if(list!=null&&list.size()>0){ return (TCifPhoto)list.get(0);}else{ return null;}} catch (HibernateException he) { throw he;}}}这样的设计在tomcat上跑一点问题都没有 HashMap中的数据也能取到,可是一但到websphere上HashMap中存储的TCifPhoto 这个persistence还在,就是persistence里面的二进制lob对象没有了,从代码里看出系统输出了“omg that's it lob is empty”就很明显知道问题的状况。可以判定websphere把lob字段给清了。或者另一种架设是websphere用到了对lob字段的lazyload的方式或者别的。没有找到相应的文档资料。问题补充:又补充讨论一下:现在看来armorking说的应该是对的,blob的操作是逻辑指针,数据库连接释放后就不能取到值了。而tomcat和websphere数据库连接的管理方式又别,所以同样的代码,tomcat能正常运行,websphere就不行。(这有待继续挖掘区别,o(∩_∩)o...)。其实把blob缓存,我觉得不是最好的方案吧,即时做成byte[]缓存解决了原先的问题,但是,每张图片有300k,在签到峰值时期,每个用户客户端与服务器的网络流量将达到很高的程度,假设刷新为2s一次 300K*6=1.8M ,接近1M/s。再加上如果有多个客户端在刷。服务器流量将受到考验。所以我考虑是不是可以把照片缓存到每个客户端ie缓存中。首先把第一次请求的照片数据从数据库中取出缓存到服务器硬盘上。而客户端直接通过url来存取服务器上的照片。每次刷新后,相同的照片ie会自动取ie缓存中的照片,而不会再到服务器上取,这样就能解决原来的两个问题了。不知道大家有什么建议?

解决方案

从lz提供的source来看blob数据检索出来以后,并没有被放到photohash中另外,根据sql的Blob的文档引用默认情况下,驱动程序使用 SQL locator(BLOB) 实现 Blob,这意味着 Blob 对象包含一个指向 SQL BLOB 数据而不是数据本身的逻辑指针。Blob 对象在它被创建的事务处理期间有效。 TCifPhoto.getPhoto()的类型如果是Blob型而不是 byte[]的话,一旦检索事务处理结束了,的确有可能变成null
解决方案二:
这样的情况就有点妖了,按理说只要不是操作系统不一致,java虚拟机的本地实现应该是一致的。缓存图片信息的字节数组看看?
解决方案三:
以我的理解,这个问题跟垃圾回收无关一般来说,对象在servlet中有三种scope:request, session, application其中request < session < application而lz想做的应该是个对象缓存但是每个用户的session是不同的,也就是说不同用户的session是无法共享的所以,应当使用application级别的缓存策略从实现手段上来讲,最简单的,就是一个单例类就能搞定只需要注意两点:1、既然是个“会议签到系统”,那么这个缓存的结构就应该是一个会议对应一个照片缓存2、每次用户签到后缓存的6个相片中最早签到的一张需要被最新签到的用户照片替换这个替换处理需要加上同步处理3、根据实际应用场景,可能需要对缓存做清除处理比如说这个“会议签到系统”应当会对会议的状态管理中有一个“会议结束”的处理那么,在这个“会议结束”处理的最后,应当把对应的缓存清除
解决方案四:
一般情况下,垃圾回收不会去主动清除仍然存在Map中引用的对象,除非是WeakHashMap等特殊的Map实现。建议你检查下代码,看缓存的HashMap是否static。
解决方案五:
每个不同的照片都有个名字吧?相同的相片的名字总是相同吧?用客户端缓存不行吗?相片缓存久点就是了嘛。这样只有初次访问的时候可能会消耗些时间。当每个人的相片都缓存了之后,就不会消耗多少资源了。
解决方案六:
引用但是这样又有问题,java的回收机制自动把我hashmap中的blob对象给清掉了。每次取到的persistence是有的可是到persistence中取blob却是空的了。所以jsp界面显示的照片都是空的。你肯定是把HashMap丢在Servlet中了, 丢在某个单件类中 [就一个系统运行的话] 或者 丢在Session中[多个系统的话].
解决方案七:
把照片放在server的硬盘上吧,显示照片根据签会人的id显示6张照片好了。不过现在你可以把硬盘上不存在的照片从库里读出来,要是硬盘上有,下次就不用读库了。

时间: 2024-10-27 13:25:46

关于blob对象(图片)的缓存和提取问题的相关文章

Java从数据库中读取Blob对象图片并显示的方法_java

本文实例讲述了Java从数据库中读取Blob对象图片并显示的方法.分享给大家供大家参考.具体实现方法如下: 第一种方法: 大致方法就是,从数据库中读出Blob的流来,写到页面中去: 复制代码 代码如下: Connection conn = DBManager.getConnection();   String sql = "SELECT picture FROM teacher WHERE id=1";   PreparedStatement ps = null;   ResultSe

Android异步下载图片并且缓存图片到本地

http://lishuaishuai.iteye.com/blog/1806667 在Android开发中我们经常有这样的需求,从服务器上下载xml或者JSON类型的数据,其中包括一些图片资源,本demo模拟了这个需求,从网络上加载XML资源,其中包括图片,我们要做的解析XML里面的数据,并且把图片缓存到本地一个cache目录里面,并且用一个自定义的Adapter去填充到LIstView,demo运行效果见下图: 通过这个demo,要学会有一下几点 1.怎么解析一个XML 2.demo中用到的

Android图片三级缓存策略(网络、本地、内存缓存)_Android

一.简介 现在的Android应用程序中,不可避免的都会使用到图片,如果每次加载图片的时候都要从网络重新拉取,这样不但很耗费用户的流量,而且图片加载的也会很慢,用户体验很不好.所以一个应用的图片缓存策略是很重要的.通常情况下,Android应用程序中图片的缓存策略采用"内存-本地-网络"三级缓存策略,首先应用程序访问网络拉取图片,分别将加载的图片保存在本地SD卡中和内存中,当程序再一次需要加载图片的时候,先判断内存中是否有缓存,有则直接从内存中拉取,否则查看本地SD卡中是否有缓存,SD

javaScript中Blob对象的学习笔记

Blob表示二进制原始数据,一个Blob对象就是一个包含有只读原始数据的类文件对象. 继承Blob功能的API有: File对象:负责处理那些以文件形式存在的二进制数据,也就是操作本地文件: FileList对象:File对象的网页表单接口: FileReader对象:负责将二进制数据读入内存内容: URL对象:用于对二进制数据生成URL. 一. 创建Blob对象的方法 创建Blob对象的方法有三种,如下: 1)可以调用Blob构造函数. 2)还可以使用一个已有Blob对象上的slice()方法

Android图片三级缓存策略(网络、本地、内存缓存)

一.简介 现在的Android应用程序中,不可避免的都会使用到图片,如果每次加载图片的时候都要从网络重新拉取,这样不但很耗费用户的流量,而且图片加载的也会很慢,用户体验很不好.所以一个应用的图片缓存策略是很重要的.通常情况下,Android应用程序中图片的缓存策略采用"内存-本地-网络"三级缓存策略,首先应用程序访问网络拉取图片,分别将加载的图片保存在本地SD卡中和内存中,当程序再一次需要加载图片的时候,先判断内存中是否有缓存,有则直接从内存中拉取,否则查看本地SD卡中是否有缓存,SD

Android异步下载图片并且缓存图片到本地DEMO详解

在Android开发中我们经常有这样的需求,从服务器上下载xml或者JSON类型的数据,其中包括一些图片资源,本demo模拟了这个需求,从网络上加载XML资源,其中包括图片,我们要做的解析XML里面的数据,并且把图片缓存到本地一个cache目录里面,并且用一个自定义的Adapter去填充到LIstView,demo运行效果见下图: 通过这个demo,要学会有一下几点 1.怎么解析一个XML 2.demo中用到的缓存图片到本地一个临时目录的思想是怎样的? 3.AsyncTask类的使用,因为要去异

php-nginx PHP 图片做缓存处理

问题描述 nginx PHP 图片做缓存处理 用nginx 搭建了一个PHP的网站,网站中很多图片都是长期不会变的.每次访问网站都会去重新读取加载图片,各位大神怎么设置NGINX的图片缓存呢 解决方案 官方文档有的哦.https://www.nginx.com/blog/nginx-caching-guide/ proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m u

数据缓存-Android中数据以及图片的缓存

问题描述 Android中数据以及图片的缓存 在实际开发中,应该如何对图片还有数据进行缓存处理呢?就是,有网络的情况下用户点击进去了好多界面,当关闭网络的时候再进入到原来点击的界面时,展示有网络时缓存的数据!这个应该怎么操作呢????菜鸟求解答3q 解决方案 可以缓存,更好的办法是用GreenDao或者WrapLibrary保存到数据库里 解决方案二: Android--SoftReference缓存图片

存储-Android图片三级缓存的问题

问题描述 Android图片三级缓存的问题 三级缓存我的理解:内存(ram)-手机存储空间(rom)-网络,我在网上找了好几个例子,运行后发现只要把手机存储空间下的缓存数据删掉,在断网情况下就不会在显示图片了,这是为什么,既然是三级,我关掉网络,删除本地缓存文件,不是还有内存这一级吗,为什么不能显示图片了,求解!或者是我对三级缓存理解错了? 解决方案 /** @author zimo2013 @see http://blog.csdn.net/zimo2013 * */ public inter