环境:
java 1.7
SSM架构
Oracle 11g 数据库
tomcat 部署
服务器操作系统是linux,具体版本未知
业务情景:
上传、查看图片的一个页面功能。由于没有专门的服务器,全家老小都在一个oracle数据库里,因此要将图片转为base64格式存在数据库里(clob类型)。开发的时候自测上传和查看都没问题,上传一般会消耗十几秒,而打开页面会加载十几个压缩图(保存前压缩,保存时向数据库存原图base64和压缩图base64),两三秒就能出来。上传和获取缩略图的代码都在同一个类中。
问题情景:
某日,客户集中进行上传,上传并发量推测为几十,此时打开页面会出现明显延时,上传是否受影响不清楚。
因为是公司项目,不方便贴出代码,请见谅。
尝试过的方法 :
因为出现明显卡顿,我用自己的电脑运行项目进行访问(本地项目运行时连接的数据库就是生产数据库),发现加载页面并无卡顿。由此我推测卡顿问题与数据库性能无关,可能是并发的访问请求争抢服务器与数据的连接数造成的。但由于我经验极少,不知道该从什么角度入手分析这个问题,且该并发情景很可能只发生这一次,客户和上级都没有要求对此进行优化。原本想通过线程池限制上传并发数,但因为不要求优化就没能进行实验。
我想要达到的结果:
尽管不需要优化,我还是想知道该如何分析并解决此类问题,以免以后再遇到。这里希望加载页面不受明显影响,上传速度可以被牺牲,因为加载页面原本时间短,而上传原本就很耗时,保证加载速度可以有效保护用户体验。
数据库对于二进制数据和大字符串数据的处理能力是很低下的。
我们做开发的,几乎没有将图片存入数据库的,都是存在硬盘里面,或者,保存在文件中心当中。
你这种情况,一般不会转成Base64在存入数据库CLob字段,一般直接存BLob字段,效率要高很多,也省硬盘。
BLob或者CLob,最好单独建表,通过主外键进行关联。
图片的上传下载,单独写接口完成。图片的显示,提供一个带有ID的连接出来,用于前端页面的显示。
楼主说的卡顿现象,应该是同时有人上传或更改数据,把表锁上了吧,人家没有上传更改完毕,你就无法进行更改。
这种情况,再多并发也没啥卵用。
按我说的,BLob/CLob字段,单独拿出去建表。
更新其他字段的时候,锁那个主表,更新图片的时候,所当前新建的表。
由于是通过主外键关联的,新建的表,通过主外键关系,更新记录的时候,使用的是行锁,不会所整张表,换句话说,就是不影响其他人上传。
主表在更新的时候,更新语句的选择条件也替换成ID,这样的话,也是行锁,不影响其他人更改数据。
把更改和删除的查询条件,统一都换成ID的形式,每次只更改或删除一条记录,然后就没有那么多毛事儿了。
如果这样改完了还卡,那就把网络带宽再升级一下,数据库服务器的配置再升级一下就可以了。
图片就不要保存到数据库吧,保存文件名称到数据库,图片保存在文件夹里面。