java中的缓存

@Service就相当于new了这个Service类,可供Controller调用


ehcache的缓存有两种方式,一种是用Ehcache Annotations for Spring在业务逻辑层里对其进行缓存
,另一种是在mybatis里面用mybatis-ehcache对其进行缓存,这两种有必要共存吗,如果不必要,
应该使用哪一种比较合理,或者是说常用的是哪一种???


缓存是在数据库查询的时候进行缓存
第二次调用数据库查询就可以去缓存查


查询语句有 setCache


想用ehcache进行缓存管理,如果在业务逻辑层
加上了缓存,那么在mybatis还需要再加上ehcache的缓存吗?



<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.2.5</version>






web中缓存的几种方式


看了构建高性能的web站点一书,对其中的集中web缓存进行一个总结


1 应用程序实现的动态页面缓存


应用程序把动态文件生成的html文件缓存到文件服务器,以后用户请求动态文件,直接从文件服务器加载对应的静态缓存的html文件返回给用户,这里面主要节省了动态语言的执行时间和数据库访问时间。但是会增加了缓存框架的加载和缓存查找的时间。


 


2 把解释执行的开发语言编译成为目标代码


这个主要把解释执行的高级语言,例如java,php直接编译成为平台相关的目标代码,汇编代码。在java里面,比较著名的就是即时编译器(JIT),其他的语言也要类似的机制。这里面主要节省了就是解释执行代码的时间。这个会增加即时编译的时间。


 


3 利用反向代理服务器的缓存


利用类似nginx的反向代理服务器,对请求的url对应的输出的进行缓存。这个缓存和应用程序实现的动态页面缓存类似,只不过用反向代理充当了应用程序的缓存实现。主要节省了动态余元执行时间和数据库访问时间。


 


4 客户端浏览器缓存


客户端浏览器缓存主要是通过在http头部增加


Last-Modified,If-Modified-Since,Expires,Cache-Control等标识,和服务器进行协商,是否是采用客户的本机缓存来实现。


其中这里面也会分为三种方式


1 通过Last-Modified,If-Modified-Since方式和服务器通信,客户发出http请求中包含If-Modified-Since,如果服务器端代码没有修改,服务器端返回302响应代码的请求响应头(内容不返回)客户端则直接用本机缓存的内容缓存显示结果。相当于节省了服务器执行代码时间以及数据传输时间。


2 通过Expires,Cache-Control控制,客户端发现如果上次请求的页面还未过期,通过Expires或者Cache-Control进行辨别,则直接显示本机缓存的内容,不与服务器进行通信。


 


总结一下:1 一般的高并发的应用程序,都在web层采用了以上几种缓存,一般静态资源(图片,js,css)都会采用nginx反向代理+客户端缓存来实现。


              2  对于门户网站,尤其是首页的新闻,一般都会缓存起来,可以通过反向代理也可以通过应用程序缓存实现方式


              3 对于下载或者视频网站,由于数据传输比较大,直接采用浏览器本地缓存实现。


 
 
 


缓存机制详解
一. 为什么要使用缓存
如果每次进入页面的时候都查询数据库生成页面内容的话,如果访问量非常大,则网站性能会非常差。而如果只有第一次访问的时候才查询数据库生成页面内容,以后都直接输出内容,则能提高系统性能。这样无论有多少人访问都只访问一次数据库,数据库压力不变。
二. 什么是缓存:
缓存(Cache)是一种用空间换取时间的技术,存在于计算机中很多地方,用来将一些慢速设备中的常用数据保存在快速设备中,取数据的时候直接从快速设备中取。比如CPU二级缓存、内存、windows文件读取缓存。缓存是改进网站性能的第一个手段,就像索引是改进数据库性能的第一个手段一样
 
三. 缓存存在的问题:
   缓存存在失效的问题:为了保证从缓存中读取数据和慢速数据(数据库)中数据一致,则需要在慢速数据(数据库)中对应的数据发生变化的时候,清除缓存中相应的数据(缓存依赖)。
四. 下面介绍asp.net中的三种形式的缓存:
  页面缓存(中庸)、数据源缓存(最不灵活的)、数据缓存(灵活)这三种主要类型。
 
1) 页面缓存:
简单的有关介绍:
l 给页面添加<%@ OutputCache Duration=“15”  VaryByParam=“none”%>标签就可以启用页面缓存,这样整个页面的内容都会被缓存,页面中的ASP.Net代码、数据源在缓存期间都不会被运行,而是直接输出缓存的页面内容。 Duration表示缓存时间,以秒为单位,超过这个时间则缓存失效,再次生成以后会再缓存15秒,以此类推。在Page_Load处设置断点、修改数据库数据测试。这个缓存是在服务器缓存的,不是在客户端,因为用HttpWatch还是能看到向服务器提交的请求的,只不过服务器看到有缓存就没有再执行页面类。一般只有看帖、看新闻、看视频的页面才缓存,CUD的页面没必要缓存。
l 缓存是针对所有这个页面的访问者。这样1个访问者和1万个访问者、一次访问和100万次访问对数据库的压力是一样的。
l 下面开始介绍也页面缓存机制:
当浏览器第一次请求页面后,发送了请求报文,服务器端会分析请求的报文,然后判端服务器缓存中有没有该页面的数据的html代码,有发送304告诉浏览器,你那边(浏览器端)有该页面的缓存数据,发送Last-Modified时间。告诉浏览器从浏览器那边拿数据。没有就重新运行页面,创建页面类,读取数据库,返回数据,产生html代码放在服务器缓存区,并设置缓存事件时间为多少,并发送html代码给浏览器。当改浏览器再次发送同一个页面的请求时,会带着上次发来的Last-Modified
时间放在请求报文里,服务器接受到请求报文,分析,一看,这个时间还在设置的缓存时间之内,然后发送304给浏览器,还有Last-Modified时间,告诉浏览器,从自己的缓存区中拿数据html代码。此时,在服务器端没有创建页面类。减少了服务器端的负载。
 
但是问题来了:那么为什么在服务器端也设置服务器端缓存呢?
 
这是为了,其他用户的浏览器访问同一个页面时候,服务器要判断服务器端有没有该页面的缓存的html代码,如果有的话,那么就把这个缓存区的html代码发给这个用户的浏览器,
还有一个时间Last-Modified。此时浏览器会在下次再访问该网站页面的时候以If-Modified-Since值的方式提交的服务器。那么服务器就会向上面一样,返回状态码304给服务器。让浏览器从自己的换存中读取数据。他们之间的通信主要通过Last-Modified,和
       If-Modified-Since进行判断缓存是否消失。
 
   但是问题又来了:
 
l 对于看新闻页面来讲,如果如上设置的话,则会缓存在第一个看到的新闻,因为?id=2、?id=3只是页面的不同参数而已,为了能让不同的新闻各自缓存,因此可以设置VaryByParam=“id”,表示对于相同页面的不同的id参数进行单独缓存。如果有多个确定缓存的参数,则将参数名用分号隔开即可,比如VaryByParam=“id;number”。测试。缓存可能会有过期数据的问题,因此根据需求选用。
l 如果想让任何不同的查询字符串都创建不同的缓存,则设置VaryByParam="*",一般情况下设置“*”就足够。
l 所以设置VaryByParam=”none“是不管你带上什么参数,在服务器端缓存的都是第一次访问的页面。 如果参上多个参数,就会根据你的参数来缓存不同的页面的数据的html代码。
 
2) 数据源缓存:
设定ObjectDataSource的CacheDuration(缓存时间:秒),EnableCaching=true。这样每隔CacheDuration指定的时间段才调用SelectMethod指定的方法来执行数据库查询,其他时候都是直接返回缓存的数据。取数据的过程缓存,在缓存期间,绑定控件向ObjectDataSource要数据, ObjectDataSource直接将缓存的数据返回给控件,不再去向TypeName指向的类要数据。
 
注意:
缓存固定的时间适用于首页、文章列表等访问频繁的页面,对于看贴页面则不适合,假设有100万个帖子,如果每个帖子都是固定缓存1小时的话,假设一小时之内有10万个帖子被看了,那么就要缓存十万个帖子,非常占用内存,因为“百年一看”的“坟帖”偶然被访问一次也缓存一个小时,占用内存。这时候可以采用“滑动窗口(sliding)”策略,比如帖子缓存10分钟,如果10分钟之内又访问了,则缓存的失效时间修改为从被访问这一刻起的10分钟之后,以此类推。这样经常访问的帖子就可以“长期缓存”,而不经常访问的帖子也不会因为偶然访问而长期占用缓存。设置方法,数据源:CacheExpirationPolicy="Sliding"。面试可聊。todo:貌似滑动有问题。不是问题,Sliding只是策略,服务器会参考。
 
3)缓存依赖:
l  依赖于文件内容
CacheDependency cDep = new CacheDependency(filePath);
l 依赖于数据库内容(轮询机制/通知机制)
一:轮询机制 –fw主动到数据库检查数据是否改变
1.使用C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727中的aspnet_regsql.exe:
注册:aspnet_regsql -S . -E -ed -d 数据库名 -et -t 表名
删除:aspnet_regsql -S . -E -d 数据库名 -dt -t 表名
取消数据库缓存依赖: aspnet_regsql -S . -E -dd 数据库名
数据库名 列出已注册表:aspnet_regsql -S . -E -d 数据库名 -lt
2.配置web.config(见备注)
3.数据库依赖对象
SqlCacheDependency cDep = 
   new SqlCacheDependency("GSSMS", "Students");
 
下面介绍两种依赖的详细:
1.依赖于文件System.Web.Caching.CacheDependency cDep = new System.Web.Caching.CacheDependency(filePath);
Cache.Add("fmsg", msg, cDep, System.Web.Caching.Cache.NoAbsoluteExpiration, System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.Normal, RemovedCallback);
aspnet_regsql -S . -E(集成登陆)/-U sa -P 123 -ed(启动/-dd关闭) -d(数据库名) GSSMS -et(指定缓存依赖的表名/-dt禁用表名) -t(表名) Aticle
2.依赖于数据库的web.config配置
<system.web>
<caching>
<sqlCacheDependency enabled="true">
<databases>
<add name="GSSMS" connectionStringName="conStr2" pollTime="15000"/>
</databases>
</sqlCacheDependency>
</caching>
 
4).自定义缓存:
定义缓存使用类Cache,使用时先判断有没有缓存数据
if (Cache["uList"] != null)
    {
     sbHtml = Cache["uList"].ToString();
     Response.Write("缓存里有数据");
     }
这个和Session保存,取出差不多。
 1.使用 绝对过期时间设置缓存
Cache.Insert("uList",sbHtml,null,DateTime.Now.AddSeconds(15),System.Web.Caching.Cache.NoSlidingExpiration);
2.使用相对过期时间 设置缓存
 Cache.Insert("uList", sbHtml, null,DateTime.MaxValue, new TimeSpan(0, 0, 15));
其中uList是要缓存的对象的数据。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值