Linux下DNS缓存实现通常有两种方式:
一种是用DNS缓存程序NSCD(name service cache daemon)负责管理DNS缓存。
一种实现DNS缓存则是用Bind来架设Caching Name Server来实现。
如果是清除NSCD上的Cache,可重新启动NSCD服务来达成清除DNS Cache的效果。用这个命令:
# service nscd restart
或是
#/etc/initd/nscd restart
如果是清除BIND服务器上的CACHE,用这个命令:
# rndc flush
如果你的DNS服务器是用dnsmasq实现的,用下面这个命令:
$ sudo /etc/initd/dnsmasq restart
注:DNSmasq是一个轻巧的,容易使用的DNS服务工具,它可以应用在内部网和Internet连接的时候的IP地址NAT转换,也可以用做小型网络的DNS服务。
1、ipconfig
/flushdns的作用
ipconfig
/flushdns
这是清除DNS缓存用的。
当访问一个网站时系统将从DNS缓存中读取该域名所对应的IP地址,当查找不到时就会到系统中查找hosts文件,如果还没有那么才会向DNS服务器请求一个DNS查询,DNS服务器将返回该域名所对应的IP,在你的系统收到解析地址以后将使用该IP地址进行访问,同时将解析缓存到本地的DNS缓存中。
如果DNS地址无法解析,或者是DNS缓存中的地址错误,一般才会使用ipconfig/flushdns来清除所有的DNS缓存。
2、通过调用API函数来实现该命令行命令的执行
通过该命令的组成形式即可得知,/flushdns应该是作为参数传给ipconfigexe可执行程序的。如果要实现该命令的执行,可以使用system()函数,将ipconfig
/flushdns作为参数来传入,该函数的执行受环境变量的影响,实际使用时可能存在问题。也可以考虑使用ShellExecute启动ipconfigexe,并将/flushdns作为参数传递进来,但这样做也有问题,比如可能会遭到杀毒软件的拦截,对于Win7、Win8系统,可能会因为UAV权限问题被警告。
所以要看看有没有对应的API函数可供使用,直接调用API则最有效最安全。于是到MSDN中尝试着搜索,但是找不到相关的函数。既然是传递/flushdns参数执行ipconfigexe,那尝试着使用VC自带的Depends工具看看能否找到对应的接口。结果发现了其依赖的DNSAPIDLL中有叫做DnsFlushResolverCache函数,如下图所示:
这个函数应该是非公开的API函数,那可以使用LoadLibrary显示加载,并用GetProcess得到函数指针,直接调用之即可。通过搜索,得到该函数的原型声明:
[cpp]
view
plain
copy
BOOL
WINAPI
DnsFlushResolverCache(VOID);
从DNSAPIDLL动态库中显式加载调用DnsFlushResolverCache的代码如下所示:
[cpp]
view
plain
copy
BOOL
__stdcall
DnsFlushResolverCache()
{
BOOL
bRet
=
FALSE;
typedef
BOOL
(WINAPI
PfuncDnsFlushResolverCache)(VOID);
HMODULE
hDnsModule
=
LoadLibrary(
_T("dnsapidll")
);
if
(
hDnsModule
!=
NULL
)
{
PfuncDnsFlushResolverCache
pFlushFun
=
GetProcAddress(
hDnsModule,
"DnsFlushResolverCache"
);
if
(
pFlushFun
!=
NULL
)
{
pFlushFun();
bRet
=
TRUE;
}
FreeLibrary(
hDnsModule
);
}
return
bRet;
}
3、通过调用API函数来实现该命令行命令的执行
今天因为系统出现故障,终端一直无法登录到平台。为了解决该问题,将平台的网络由联通的网络切换到电信的网络,结果就出现了部分终端能够登录,部分终端不能登录的情况。考虑到可能是系统DNS缓存引起的,终端侧将域名解析出来的地址一直是之前的联通地址(即缓存中的地址),所以一直无法登录。于是使用ipconfig
/flushdns命令清理了一下系统的DNS缓存即可正常登录了。为了规避这样由网络切换和DNS缓存引起的问题,可以考虑在多次登录失败后自动去清理系统的DNS缓存。
怎么不用hosts修改DNS解析程序缓存
两种可能:
一:要访问的网站服务器连接错误;
二:本地网络设置DNS设置错误。
当DNS解析出现错误,例如把一个域名解析成一个错误的IP地址,或者根本不知道某个域名对应的IP地址是什么时,就无法通过域名访问相应的站点了,这就是DNS解析故障。出现DNS解析故障最大的症状就是访问站点对应的IP地址没有问题,然而访问他的域名就会出现错误。
(1)用nslookup(网路查询)来判断是否真的是DNS解析故障:
要想百分之百判断是否为DNS解析故障就需要通过系统自带的NSLOOKUP来解决了。
第一步:确认自己的系统是windows 2000和windows xp以上 *** 作系统,然后通过“开始->运行->输入CMD”后回车进入命令行模式。
第二步:输入nslookup命令后回车,将进入DNS解析查询界面。
第三步:命令行窗口中会显示出当前系统所使用的DNS服务器地址,例如笔者的DNS服务器IP为202106020。
第四步:接下来输入无法访问的站点对应的域名。假如不能访问的话,那么DNS解析应该是不能够正常进行的,会收到DNS request timed out,timeout was 2 seconds的提示信息。这说明本地计算机确实出现了DNS解析故障。
小提示:如果DNS解析正常的话,会反馈回正确的IP地址。
(2)查询DNS服务器工作是否正常:
这时候要看本地计算机使用的DNS地址是多少了,并且查询他的运行情况。
第一步:通过“开始->运行->输入CMD”后回车进入命令行模式。
第二步:输入ipconfig/all命令来查询网络参数。
第三步:在ipconfig /all显示信息中能够看到一个地方写着DNS SERVERS,这个就是本地的DNS服务器地址。例如笔者的是202106020和20210646151。从这个地址可以看出是个外网地址,如果使用外网DNS出现解析错误时,可以更换一个其他的DNS服务器地址即可解决问题。
第四步:如果在DNS服务器处显示的是个人公司的内部网络地址,那么说明该公司的DNS解析工作是交给公司内部的DNS服务器来完成的,这时需要检查这个DNS服务器,在DNS服务器上进行nslookup *** 作看是否可以正常解析。解决DNS服务器上的DNS服务故障,一般来说问题也能够解决。
(3)清除DNS缓存信息法:
第一步:通过“开始->运行->输入CMD”进入命令行模式。
第二步:在命令行模式中我们可以看到在ipconfig /中有一个名为/flushdns的参数,这个就是清除DNS缓存信息的命令。
第三步:执行ipconfig /flushdns命令,当出现“successfully flushed the dns resolver cache”的提示时就说明当前计算机的缓存信息已经被成功清除。
第四步:接下来我们再访问域名时,就会到DNS服务器上获取最新解析地址,再也不会出现因为以前的缓存造成解析错误故障了。
(4)修改HOSTS(主机)文件法:
第一步:通过“开始->搜索”,然后查找名叫hosts的文件。
第二步:当然对于已经知道他的路径的读者可以直接进入c:\windows\system32\drivers\etc目录中找到HOSTS文件。如果你的系统是windows 2000,那么应该到c:\winnt\system32\drivers\etc目录中寻找。
第三步:双击HOSTS文件,然后选择用“记事本”程序将其打开。
第四步:之后我们就会看到HOSTS文件的所有内容了,默认情况下只有一行内容“127001 localhost”。(其他前面带有#的行都不是真正的内容,只是帮助信息而已)
第五步:将你希望进行DNS解析的条目添加到HOSTS文件中。具体格式是先写该域名对应的IP地址,然后空格接域名信息。
第六步:设置完毕后我们访问网址时就会自动根据是在内网还是外网来解析了。
很多人对二级缓存都不太了解,或者是有错误的认识,我一直想写一篇文章介绍一下hibernate的二级缓存的,今天终于忍不住了。
我的经验主要来自hibernate21版本,基本原理和30、31是一样的,请原谅我的顽固不化。
hibernate的session提供了一级缓存,每个session,对同一个id进行两次load,不会发送两条sql给数据库,但是session关闭的时候,一级缓存就失效了。
二级缓存是SessionFactory级别的全局缓存,它底下可以使用不同的缓存类库,比如ehcache、oscache等,需要设置hibernatecacheprovider_class,我们这里用ehcache,在21中就是
hibernatecacheprovider_class=netsfhibernatecacheEhCacheProvider
如果使用查询缓存,加上
hibernatecacheuse_query_cache=true
缓存可以简单的看成一个Map,通过key在缓存里面找value。
Class的缓存
对于一条记录,也就是一个PO来说,是根据ID来找的,缓存的key就是ID,value是POJO。无论list,load还是iterate,只要读出一个对象,都会填充缓存。但是list不会使用缓存,而iterate会先取数据库select id出来,然后一个id一个id的load,如果在缓存里面有,就从缓存取,没有的话就去数据库load。假设是读写缓存,需要设置:
<cache usage="read-write"/>
如果你使用的二级缓存实现是ehcache的话,需要配置ehcachexml
<cache name="comxxxpojoFoo" maxElementsInMemory="500" eternal="false" timeToLiveSeconds="7200" timeToIdleSeconds="3600" overflowToDisk="true" />
其中eternal表示缓存是不是永远不超时,timeToLiveSeconds是缓存中每个元素(这里也就是一个POJO)的超时时间,如果eternal="false",超过指定的时间,这个元素就被移走了。timeToIdleSeconds是发呆时间,是可选的。当往缓存里面put的元素超过500个时,如果overflowToDisk="true",就会把缓存中的部分数据保存在硬盘上的临时文件里面。
每个需要缓存的class都要这样配置。如果你没有配置,hibernate会在启动的时候警告你,然后使用defaultCache的配置,这样多个class会共享一个配置。
当某个ID通过hibernate修改时,hibernate会知道,于是移除缓存。
这样大家可能会想,同样的查询条件,第一次先list,第二次再iterate,就可以使用到缓存了。实际上这是很难的,因为你无法判断什么时候是第一次,而且每次查询的条件通常是不一样的,假如数据库里面有100条记录,id从1到100,第一次list的时候出了前50个id,第二次iterate的时候却查询到30至70号id,那么30-50是从缓存里面取的,51到70是从数据库取的,共发送1+20条sql。所以我一直认为iterate没有什么用,总是会有1+N的问题。
(题外话:有说法说大型查询用list会把整个结果集装入内存,很慢,而iterate只select id比较好,但是大型查询总是要分页查的,谁也不会真的把整个结果集装进来,假如一页20条的话,iterate共需要执行21条语句,list虽然选择若干字段,比iterate第一条select id语句慢一些,但只有一条语句,不装入整个结果集hibernate还会根据数据库方言做优化,比如使用mysql的limit,整体看来应该还是list快。)
如果想要对list或者iterate查询的结果缓存,就要用到查询缓存了
查询缓存
首先需要配置hibernatecacheuse_query_cache=true
如果用ehcache,配置ehcachexml,注意hibernate30以后不是netsf的包名了
<cache name="netsfhibernatecacheStandardQueryCache"
maxElementsInMemory="50" eternal="false" timeToIdleSeconds="3600"
timeToLiveSeconds="7200" overflowToDisk="true"/>
<cache name="netsfhibernatecacheUpdateTimestampsCache"
maxElementsInMemory="5000" eternal="true" overflowToDisk="true"/>
然后
querysetCacheable(true);//激活查询缓存
querysetCacheRegion("myCacheRegion");//指定要使用的cacheRegion,可选
第二行指定要使用的cacheRegion是myCacheRegion,即你可以给每个查询缓存做一个单独的配置,使用setCacheRegion来做这个指定,需要在ehcachexml里面配置它:
<cache name="myCacheRegion" maxElementsInMemory="10" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="7200" overflowToDisk="true" />
如果省略第二行,不设置cacheRegion的话,那么会使用上面提到的标准查询缓存的配置,也就是netsfhibernatecacheStandardQueryCache
对于查询缓存来说,缓存的key是根据hql生成的sql,再加上参数,分页等信息(可以通过日志输出看到,不过它的输出不是很可读,最好改一下它的代码)。
比如hql:
from Cat c where cname like
生成大致如下的sql:
select from cat c where cname like
参数是"tiger%",那么查询缓存的key大约是这样的字符串(我是凭记忆写的,并不精确,不过看了也该明白了):
select from cat c where cname like , parameter:tiger%
这样,保证了同样的查询、同样的参数等条件下具有一样的key。
现在说说缓存的value,如果是list方式的话,value在这里并不是整个结果集,而是查询出来的这一串ID。也就是说,不管是list方法还是iterate方法,第一次查询的时候,它们的查询方式很它们平时的方式是一样的,list执行一条sql,iterate执行1+N条,多出来的行为是它们填充了缓存。但是到同样条件第二次查询的时候,就都和iterate的行为一样了,根据缓存的key去缓存里面查到了value,value是一串id,然后在到class的缓存里面去一个一个的load出来。这样做是为了节约内存。
可以看出来,查询缓存需要打开相关类的class缓存。list和iterate方法第一次执行的时候,都是既填充查询缓存又填充class缓存的。
这里还有一个很容易被忽视的重要问题,即打开查询缓存以后,即使是list方法也可能遇到1+N的问题!相同条件第一次list的时候,因为查询缓存中找不到,不管class缓存是否存在数据,总是发送一条sql语句到数据库获取全部数据,然后填充查询缓存和class缓存。但是第二次执行的时候,问题就来了,如果你的class缓存的超时时间比较短,现在class缓存都超时了,但是查询缓存还在,那么list方法在获取id串以后,将会一个一个去数据库load!因此,class缓存的超时时间一定不能短于查询缓存设置的超时时间!如果还设置了发呆时间的话,保证class缓存的发呆时间也大于查询的缓存的生存时间。这里还有其他情况,比如class缓存被程序强制evict了,这种情况就请自己注意了。
另外,如果hql查询包含select字句,那么查询缓存里面的value就是整个结果集了。
当hibernate更新数据库的时候,它怎么知道更新哪些查询缓存呢?
hibernate在一个地方维护每个表的最后更新时间,其实也就是放在上面netsfhibernatecacheUpdateTimestampsCache所指定的缓存配置里面。
当通过hibernate更新的时候,hibernate会知道这次更新影响了哪些表。然后它更新这些表的最后更新时间。每个缓存都有一个生成时间和这个缓存所查询的表,当hibernate查询一个缓存是否存在的时候,如果缓存存在,它还要取出缓存的生成时间和这个缓存所查询的表,然后去查找这些表的最后更新时间,如果有一个表在生成时间后更新过了,那么这个缓存是无效的。
可以看出,只要更新过一个表,那么凡是涉及到这个表的查询缓存就失效了,因此查询缓存的命中率可能会比较低。
Collection缓存
需要在hbm的collection里面设置
<cache usage="read-write"/>
假如class是Cat,collection叫children,那么ehcache里面配置
<cache name="comxxxpojoCatchildren"
maxElementsInMemory="20" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="7200"
overflowToDisk="true" />
Collection的缓存和前面查询缓存的list一样,也是只保持一串id,但它不会因为这个表更新过就失效,一个collection缓存仅在这个collection里面的元素有增删时才失效。
这样有一个问题,如果你的collection是根据某个字段排序的,当其中一个元素更新了该字段时,导致顺序改变时,collection缓存里面的顺序没有做更新。
缓存策略
只读缓存(read-only):没有什么好说的
读/写缓存(read-write):程序可能要的更新数据
不严格的读/写缓存(nonstrict-read-write):需要更新数据,但是两个事务更新同一条记录的可能性很小,性能比读写缓存好
事务缓存(transactional):缓存支持事务,发生异常的时候,缓存也能够回滚,只支持jta环境,这个我没有怎么研究过
读写缓存和不严格读写缓存在实现上的区别在于,读写缓存更新缓存的时候会把缓存里面的数据换成一个锁,其他事务如果去取相应的缓存数据,发现被锁住了,然后就直接取数据库查询。
在hibernate21的ehcache实现中,如果锁住部分缓存的事务发生了异常,那么缓存会一直被锁住,直到60秒后超时。
不严格读写缓存不锁定缓存中的数据。
使用二级缓存的前置条件
你的hibernate程序对数据库有独占的写访问权,其他的进程更新了数据库,hibernate是不可能知道的。你 *** 作数据库必需直接通过hibernate,如果你调用存储过程,或者自己使用jdbc更新数据库,hibernate也是不知道的。hibernate30的大批量更新和删除是不更新二级缓存的,但是据说31已经解决了这个问题。
这个限制相当的棘手,有时候hibernate做批量更新、删除很慢,但是你却不能自己写jdbc来优化,很郁闷吧。
SessionFactory也提供了移除缓存的方法,你一定要自己写一些JDBC的话,可以调用这些方法移除缓存,这些方法是:
void evict(Class persistentClass)
Evict all entries from the second-level cache
void evict(Class persistentClass, Serializable id)
Evict an entry from the second-level cache
void evictCollection(String roleName)
Evict all entries from the second-level cache
void evictCollection(String roleName, Serializable id)
Evict an entry from the second-level cache
void evictQueries()
Evict any query result sets cached in the default query cache region
void evictQueries(String cacheRegion)
Evict any query result sets cached in the named query cache region
不过我不建议这样做,因为这样很难维护。比如你现在用JDBC批量更新了某个表,有3个查询缓存会用到这个表,用evictQueries(String cacheRegion)移除了3个查询缓存,然后用evict(Class persistentClass)移除了class缓存,看上去好像完整了。不过哪天你添加了一个相关查询缓存,可能会忘记更新这里的移除代码。如果你的jdbc代码到处都是,在你添加一个查询缓存的时候,还知道其他什么地方也要做相应的改动吗?
----------------------------------------------------
总结:
不要想当然的以为缓存一定能提高性能,仅仅在你能够驾驭它并且条件合适的情况下才是这样的。hibernate的二级缓存限制还是比较多的,不方便用jdbc可能会大大的降低更新性能。在不了解原理的情况下乱用,可能会有1+N的问题。不当的使用还可能导致读出脏数据。
如果受不了hibernate的诸多限制,那么还是自己在应用程序的层面上做缓存吧。
在越高的层面上做缓存,效果就会越好。就好像尽管磁盘有缓存,数据库还是要实现自己的缓存,尽管数据库有缓存,咱们的应用程序还是要做缓存。因为底层的缓存它并不知道高层要用这些数据干什么,只能做的比较通用,而高层可以有针对性的实现缓存,所以在更高的级别上做缓存,效果也要好些吧。
终于写完了,好累……
"CachedNSexe" 是 Windows *** 作系统中的一个系统进程,通常情况下,它负责 DNS 缓存的维护和管理。如果你看到"CachedNSexe 储存空间不足无法处理"的提示,可能是因为该文件的缓存文件安装在了空间不足的磁盘上,导致无法进行维护和管理。 为了解决这个问题,你可以尝试以下几种方法: 1清除 DNS 缓存:使用命令行工具清除 Windows 中的 DNS 缓存,可以释放与“CachedNSexe”相关联的磁盘空间。打开命令提示符并输入 "ipconfig /flushdns",等待命令执行完成。 2清理磁盘空间:删除不必要的文件或卸载不常用的程序可以释放磁盘空间。你可以使用 Windows 的内置磁盘清理工具来清理磁盘空间。同时,建议可以考虑增加计算机的硬盘存储空间。 3关闭“CachedNSexe”进程:在 Windows 任务管理器中终止“CachedNSexe”进程,可能会暂时解决该问题,但需要注意的是,这将导致 DNS 缓存失效,可能会影响到访问特定网站时的速度。 如果以上方法都不能解决问题,建议尝试通过重新启动计算机重置 DNS 缓存。
Service 代码:
@Service
public class GameareaServiceImpl extends BaseServiceImpl<Gamearea> implements IGameareaService{
@Resource
private GameareaMapper gameareaMapper;
@Override
@Cacheable(value="myCache")
public Gamearea find(int id) {
return gameareaMapperfind(id);
}
@Override
@Cacheable(value="myCache")
public HandlerResult list(Map map) {
HandlerResult rs = new HandlerResult();
rssetResultObj(gameareaMapperlist(map));
return rs;
}
@Override
@Cacheable(value="myCache")
public Gamearea findByParameter(Gamearea gamearea) {
return gameareaMapperfindByParameter(gamearea);
}
}
webxml;
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContextxml</param-value>
</context-param>
applicationContextxml:
<context:component-scan base-package="comjadyer"/>
<!-- 缓存配置 -->
<!-- 启用缓存注解功能(请将其配置在Spring主配置文件中) -->
<cache:annotation-driven cache-manager="cacheManager"/>
<!-- Spring自己的基于javautilconcurrentConcurrentHashMap实现的缓存管理器(该功能是从Spring31开始提供的) -->
<!--
<bean id="cacheManager" class="orgspringframeworkcachesupportSimpleCacheManager">
<property name="caches">
<set>
<bean name="myCache" class="orgspringframeworkcacheconcurrentConcurrentMapCacheFactoryBean"/>
</set>
</property>
</bean>
-->
<!-- 若只想使用Spring自身提供的缓存器,则注释掉下面的两个关于Ehcache配置的bean,并启用上面的SimpleCacheManager即可 -->
<!-- Spring提供的基于的Ehcache实现的缓存管理器 -->
<bean id="cacheManagerFactory" class="orgspringframeworkcacheehcacheEhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:ehcachexml"/>
</bean>
<bean id="cacheManager" class="orgspringframeworkcacheehcacheEhCacheCacheManager">
<property name="cacheManager" ref="cacheManagerFactory"/>
</bean>
</beans>
ehcachexml
<!-- Ehcache2x的变化(取自>
以上就是关于如何清空linux中dns缓存全部的内容,包括:如何清空linux中dns缓存、怎么使用ipconfig清空dns缓存、怎么不用hosts修改DNS解析程序缓存等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)