Nginx配置文件 nginx.conf
#集群配置:服务器列表,weight 采取均匀分配方式,weight越大,分配几率越大
upstream localhost {
server localhost:8001 weight=1;
server localhost:8002 weight=1;
}
2、http模块中,使用 upstream localhost,在此还做了动静分离,其中静态的就指向一个目录即可,后续在更新的时候也只需要更新着一个目录,当然,如果做CDN,又是另外一种配置方式了。
location / {
proxy_connect_timeout 3;
proxy_send_timeout 30;
proxy_read_timeout 30;
proxy_pass http://localhost;
}
#配置Nginx动静分离,定义的静态页面直接从Nginx发布目录读取。
location ~*\.(js|css|png|gif|jpg|jpeg)$ {
root D:/pnf_etp/app1/;
}
tomcat8 主要是修改 server.xml 中对应的端口,确保不同的tomcat端口不冲突即可。
EhCache主要在配置文件ehcache.xml进行配置修改,完整例子如下:
<?xml version="1.0" encoding="UTF-8"?>
<!-- 缓存配置 name:缓存名称。 maxElementsInMemory:缓存最大个数。 eternal:对象是否永久有效,一但设置了,timeout将不起作用。
timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。 diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
maxElementsOnDisk:硬盘最大缓存个数。 diskPersistent:是否缓存虚拟机重启期数据 Whether the disk
store persists between restarts of the Virtual Machine. The default value
is false. diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。 memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
clearOnFlush:内存数量最大时是否清除。 参考: http://blog.csdn.net/mlitsn/article/details/1909192
http://blog.csdn.net/u013366812/article/details/51725335 -->
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="false"
monitoring="autodetect" dynamicConfig="true">
<cacheManagerPeerListenerFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
properties="hostName=localhost,port=4081,socketTimeoutMillis=8000" />
<cacheManagerPeerProviderFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
properties="peerDiscovery=manual,rmiUrls=//localhost:4082/userSessionCache|//localhost:4082/userTokenCache|//localhost:4082/userAllowMenuUri|//localhost:4082/FormToken|//localhost:4082/orderToken|//localhost:4082/AccessTokenCache|//localhost:4082/OAuth2AccessTokenCache|//localhost:4082/MQCache" />
<diskStore path="java.io.tmpdir" />
<defaultCache maxEntriesLocalHeap="10000" eternal="false"
overflowToDisk="true" timeToIdleSeconds="20" timeToLiveSeconds="20">
</defaultCache>
<!-- 用户SessionID,通过getSession(true).getId,获取 -->
<cache name="SessionIDCache" maxElementsInMemory="10000"
maxElementsOnDisk="100000" maxEntriesLocalHeap="10000"
maxEntriesLocalDisk="1000" eternal="true" overflowToDisk="true"
diskSpoolBufferSizeMB="100" memoryStoreEvictionPolicy="FIFO"
diskPersistent="true" transactionalMode="off" clearOnFlush="false" />
<!-- 用户登录session缓存 -->
<cache name="userSessionCache" maxEntriesLocalHeap="10000"
maxEntriesLocalDisk="0" eternal="false" overflowToDisk="true"
diskSpoolBufferSizeMB="20" timeToIdleSeconds="3600" timeToLiveSeconds="86400"
memoryStoreEvictionPolicy="LRU" diskPersistent="true"
diskExpiryThreadIntervalSeconds="120" transactionalMode="off"
clearOnFlush="true">
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicateAsynchronously=false,replicatePuts=true,replicateUpdates=true,replicateUpdatesViaCopy=true,replicateRemovals=true" />
</cache>
<!-- 用户API Token 缓存 -->
<cache name="userTokenCache" maxEntriesLocalHeap="10000"
maxEntriesLocalDisk="1000" eternal="false" overflowToDisk="true"
diskSpoolBufferSizeMB="20" timeToIdleSeconds="3600" timeToLiveSeconds="7200"
memoryStoreEvictionPolicy="LRU" diskPersistent="true"
diskExpiryThreadIntervalSeconds="120" transactionalMode="off"
clearOnFlush="true">
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicateAsynchronously=false,replicatePuts=true,replicateUpdates=true,replicateUpdatesViaCopy=true,replicateRemovals=true" />
</cache>
<!-- 用户菜单缓存 -->
<cache name="userMenuCache" maxEntriesLocalHeap="10000"
maxEntriesLocalDisk="1000" eternal="false" overflowToDisk="true"
diskSpoolBufferSizeMB="20" timeToIdleSeconds="7200" timeToLiveSeconds="86400"
memoryStoreEvictionPolicy="LRU" diskPersistent="true"
diskExpiryThreadIntervalSeconds="120" transactionalMode="off"
clearOnFlush="true" />
<!-- 用户有权访问菜单缓存 -->
<cache name="userAllowMenuUri" maxEntriesLocalHeap="10000"
maxEntriesLocalDisk="1000" eternal="false" overflowToDisk="true"
diskSpoolBufferSizeMB="20" timeToIdleSeconds="3600" timeToLiveSeconds="86400"
memoryStoreEvictionPolicy="LRU" diskPersistent="true"
diskExpiryThreadIntervalSeconds="120" transactionalMode="off"
clearOnFlush="true">
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicateAsynchronously=false,replicatePuts=true,replicateUpdates=true,replicateUpdatesViaCopy=true,replicateRemovals=true" />
</cache>
<!-- 字典缓存,全局使用 -->
<cache name="dictCache" maxEntriesLocalHeap="10000"
maxEntriesLocalDisk="1000" eternal="true" overflowToDisk="true"
diskSpoolBufferSizeMB="20" memoryStoreEvictionPolicy="LRU"
diskPersistent="true" diskExpiryThreadIntervalSeconds="120"
transactionalMode="off" clearOnFlush="true" />
<!-- 微信access_token缓存 -->
<cache name="AccessTokenCache" maxEntriesLocalHeap="1000"
maxEntriesLocalDisk="100" eternal="false" overflowToDisk="true"
diskSpoolBufferSizeMB="20" timeToIdleSeconds="3600" timeToLiveSeconds="7200"
memoryStoreEvictionPolicy="LRU" diskPersistent="true"
diskExpiryThreadIntervalSeconds="120" transactionalMode="off"
clearOnFlush="true">
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicateAsynchronously=false,replicatePuts=true,replicateUpdates=true,replicateUpdatesViaCopy=true,replicateRemovals=true" />
</cache>
<!-- 微信oAuth2 access_token缓存 -->
<cache name="OAuth2AccessTokenCache" maxEntriesLocalHeap="1000"
maxEntriesLocalDisk="100" eternal="false" overflowToDisk="true"
diskSpoolBufferSizeMB="20" timeToIdleSeconds="3600" timeToLiveSeconds="7200"
memoryStoreEvictionPolicy="LRU" diskPersistent="true"
diskExpiryThreadIntervalSeconds="120" transactionalMode="off"
clearOnFlush="true">
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicateAsynchronously=false,replicatePuts=true,replicateUpdates=true,replicateUpdatesViaCopy=true,replicateRemovals=true" />
</cache>
<!-- 消息队列信息缓存 -->
<cache name="MQCache" maxElementsInMemory="10000"
maxElementsOnDisk="100000" maxEntriesLocalHeap="10000"
maxEntriesLocalDisk="1000" eternal="true" overflowToDisk="true"
diskSpoolBufferSizeMB="100" memoryStoreEvictionPolicy="FIFO"
diskPersistent="true" transactionalMode="off" clearOnFlush="false">
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicateAsynchronously=false,replicatePuts=true,replicateUpdates=true,replicateUpdatesViaCopy=true,replicateRemovals=true" />
</cache>
<!-- 关键form提交token,用于防止非法或者重复提交 -->
<cache name="FormToken" maxEntriesLocalHeap="10000"
maxEntriesLocalDisk="0" eternal="false" overflowToDisk="true"
diskSpoolBufferSizeMB="20" timeToIdleSeconds="3600" timeToLiveSeconds="86400"
memoryStoreEvictionPolicy="LRU" diskPersistent="true"
diskExpiryThreadIntervalSeconds="120" transactionalMode="off"
clearOnFlush="true">
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicateAsynchronously=false,replicatePuts=true,replicateUpdates=true,replicateUpdatesViaCopy=true,replicateRemovals=true" />
</cache>
<!-- 交易订单OrderId token,用于防止非法或者重复提交 -->
<cache name="orderToken" maxEntriesLocalHeap="10000"
maxEntriesLocalDisk="0" eternal="false" overflowToDisk="true"
diskSpoolBufferSizeMB="20" timeToIdleSeconds="3600" timeToLiveSeconds="86400"
memoryStoreEvictionPolicy="LRU" diskPersistent="true"
diskExpiryThreadIntervalSeconds="120" transactionalMode="off"
clearOnFlush="true">
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicateAsynchronously=false,replicatePuts=true,replicateUpdates=true,replicateUpdatesViaCopy=true,replicateRemovals=true" />
</cache>
</ehcache>
其中,关键节点说明:
1、使用RMI方式进行分布式缓存模块的共享方式,hostName为主机ID,如果是本机使用localhost,port是通讯端口,必须确保不同的应用有不同端口
<cacheManagerPeerListenerFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
properties="hostName=localhost,port=4081,socketTimeoutMillis=8000" />
2、共享的具体cache模块,在rmiUrls中增加,其中 //localhost:4082是另外一个tomcat的ehcache.xml配置的上面模块的配置localhost 和port参数,需要共享几个,就配置几个Cache
<cacheManagerPeerProviderFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
properties="peerDiscovery=manual,rmiUrls=//localhost:4082/userSessionCache|//localhost:4082/userTokenCache|//localhost:4082/userAllowMenuUri|//localhost:4082/FormToken|//localhost:4082/orderToken|//localhost:4082/AccessTokenCache|//localhost:4082/OAuth2AccessTokenCache|//localhost:4082/MQCache" />
以上配置成功后,若tomcat启动成功,可以通过写一个测试 Controller代码验证是否已共享了其中的cache
例如:
public void index(){
if(CacheKit.get("testCacheName","abc")==null){
System.out.println("第一次创建testCacheName");
CacheKit.put("testCacheName","abc",getSession(true).getId());
}
System.out.println(CacheKit.get("testCacheName","abc"));
}
启动Nginx,启动两个tomcat,不断刷新测试Controller对应方法的页面,查看两个Tomcat的控制台页面输入的SessionID是否为同一个,一致则表示共享成功。
通过以上方式,把要共享的Session都存在ehcache中,从而实现多tomcat共享的目的。所以,在jfinal中,不要再单独使用getSession或者setSession等方法,这样会造成集群访问时Session失效。全部采取ehcache来保存Session,当然,可以根据业务情况来决定对Session用完之后的去留。