1、cas ticket统一存储
做cas集群首先需要将ticket拿出来,做统一存储,以便每个节点访问到的数据一致。官方提供基于memcached的方案,由于项目需要,需要做计入redis,根据官方例子改了一个基于redis版本的。
public class RedisTicketRegistry extends AbstractDistributedTicketRegistry{
@NotNull
private final RedisTemplate<String,Object> reidsTemplate;
/**
* TGT cache entry timeout in seconds.
*/
@Min(0)
private final int tgtTimeout;
/**
* ST cache entry timeout in seconds.
*/
@Min(0)
private final int stTimeout;
public RedisTicketRegistry(RedisTemplate<String,Object> reidsTemplate,int tgtTimeout,int stTimeout){
this.reidsTemplate=reidsTemplate;
this.tgtTimeout=tgtTimeout;
this.stTimeout=stTimeout;
}
@Override
public void addTicket(Ticket ticket) {
logger.debug("Adding ticket {}", ticket);
try {
reidsTemplate.opsForValue().set(ticket.getId(),ticket, getTimeout(ticket), TimeUnit.SECONDS);
} catch (final Exception e) {
logger.error("Failed adding {}", ticket, e);
}
}
@Override
public Ticket getTicket(String ticketId) {
try {
final Ticket t = (Ticket) this.reidsTemplate.opsForValue().get(ticketId);
if (t != null) {
return getProxiedTicketInstance(t);
}
} catch (final Exception e) {
logger.error("Failed fetching {} ", ticketId, e);
}
return null;
}
@Override
public boolean deleteTicket(String ticketId) {
logger.debug("Deleting ticket {}", ticketId);
try {
this.reidsTemplate.delete(ticketId);
return true;
} catch (final Exception e) {
logger.error("Failed deleting {}", ticketId, e);
}
return false;
}
@Override
public Collection<Ticket> getTickets() {
throw new UnsupportedOperationException("GetTickets not supported.");
}
@Override
protected void updateTicket(Ticket ticket) {
logger.debug("Updating ticket {}", ticket);
try {
this.reidsTemplate.delete(ticket.getId());
reidsTemplate.opsForValue().set(ticket.getId(),ticket, getTimeout(ticket), TimeUnit.SECONDS);
} catch (final Exception e) {
logger.error("Failed updating {}", ticket, e);
}
}
@Override
protected boolean needsCallback() {
// TODO Auto-generated method stub
return true;
}
private int getTimeout(final Ticket t) {
if (t instanceof TicketGrantingTicket) {
return this.tgtTimeout;
} else if (t instanceof ServiceTicket) {
return this.stTimeout;
}
throw new IllegalArgumentException("Invalid ticket type");
}
}
对应的ticketRegistry.xml的配置如下:
<bean >
<constructor-arg index="0" ref="redisTemplate" />
<constructor-arg index="1" value="1800" />
<constructor-arg index="2" value="10" />
</bean>
<bean >
<property name="maxIdle" value="200" />
<property name="testOnBorrow" value="true" />
</bean>
<bean
p:host-name="redis_server_ip" p:port="6379" p:pool-config-ref="poolConfig"/>
<bean
p:connection-factory-ref="connectionFactory">
</bean>
这里既然使用了redis作为ticket存储,就需要将原来的方案给注释掉:
<!-- Ticket Registry
<bean />
-->
<!--Quartz -->
<!-- TICKET REGISTRY CLEANER
<bean
p:ticketRegistry-ref="ticketRegistry"
p:logoutManager-ref="logoutManager" />
<bean
p:targetObject-ref="ticketRegistryCleaner"
p:targetMethod="clean" />
<bean
p:jobDetail-ref="jobDetailTicketRegistryCleaner"
p:startDelay="20000"
p:repeatInterval="5000000" />
-->
到这里,cas的改进就OK了,下面就需要将session也做集群同步。
2、tomcat session集群同步
这里采用开源的tomcat-redis-session-manager,git hub地址为:https://github.com/jcoleman/tomcat-redis-session-manager
这里只使用的是jdk1.7,tomcat7,tomcat6需要重新编译好像。
1)拷贝编译打包之后的tomcat-redis-session-manager-VERSION.jar,jedis-2.5.2.jar,commons-pool2-2.2.jar到tomcat/lib目录下
2)修改Tomcat context.xml (or the context block of the server.xml if applicable.)
<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve"/>
<Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
host="redis_server_name"
port="6379"
database="0"
maxInactiveInterval="1800"/>
至此cas集群配置就可以了。
http://www.cnblogs.com/lcxdever/p/4308759.html