CAS 4.0 Cluster/Tomcat redis Session manager/Token(TGT)Redisクラスタ/Nginx負荷格納

34408 ワード

Nginx conf:
どのようにTomcatはSESSION共有をしないでIP_を開くことができますHASH.
upstream tomcat {
    ##ip_hash;
    server 200.10.10.67:8110;
    server 200.10.10.67:8120;
}

Tomcat Session参照【1】
-jarバージョン番号に注意
CAS対応開発構成
Pom.xml構成:
対応するPOMファイルのdependencyの導入
        <dependency>
            <groupId>org.apache.commonsgroupId>
            <artifactId>commons-pool2artifactId>
            <version>2.2version>
        dependency>
        <dependency>
            <groupId>redis.clientsgroupId>
            <artifactId>jedisartifactId>
            <version>2.8.1version>
        dependency>

ticketRegistry.xml構成内容
index=0はredisクラスタアドレスindex=1はTGT有効期限index=2はTGT有効期限
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <description>
        Configuration for the default TicketRegistry which stores the tickets in-memory and cleans them out as specified intervals.
    description>

  
    <bean id="ticketRegistry" class="org.jasig.cas.ticket.registry.RedisTicketRegistry">
            <constructor-arg index="0" value="Centos6701:6379,Centos6701:6380,Centos6702:6380,Centos6702:6379,Centos6703:6380,Centos6703:6379" />
            <constructor-arg index="1" value="28800" />
            <constructor-arg index="2" value="200" />
    bean>
    beans>

RedisストレージToken
RedisTicketRegistry.java
/*
 * Licensed to Jasig under one or more contributor license
 * agreements. See the NOTICE file distributed with this work
 * for additional information regarding copyright ownership.
 * Jasig licenses this file to you under the Apache License,
 * Version 2.0 (the "License"); you may not use this file
 * except in compliance with the License.  You may obtain a
 * copy of the License at the following location:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.jasig.cas.ticket.registry;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import javax.validation.constraints.Min;

import org.jasig.cas.ticket.ServiceTicket;
import org.jasig.cas.ticket.Ticket;
import org.jasig.cas.ticket.TicketGrantingTicket;
import org.jasig.cas.ticket.registry.util.RedisTools;
import org.jasig.cas.ticket.registry.util.serialize.ObjectsTranscoder;

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;

/**
 * Key-value ticket registry implementation that stores tickets in redis keyed on the ticket ID.
 *
 * @author lumz
 * @author 2016-7-12 10:17:30
 * @since 1.0
 */
public final class RedisTicketRegistry extends AbstractDistributedTicketRegistry {


    private JedisCluster jedisCluster;
    private RedisTools handle;
    private String redisServers;
    /**
     * 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(String redisServers,int tgtTimeout,int stTimeout){
        logger.info("CoreRdisTicketRegistry {true} Init Redis Service : " + redisServers);
        this.redisServers = redisServers;
        this.tgtTimeout=tgtTimeout;
        this.stTimeout=stTimeout;
        Set jedisClusterNodes = new HashSet();

        for (String server : redisServers.split(",")) {
            jedisClusterNodes.add(new HostAndPort(server.split(":")[0], Integer
                    .parseInt(server.split(":")[1])));
        }
        jedisCluster = new JedisCluster(jedisClusterNodes);
        handle = new RedisTools(jedisCluster);
        logger.info("Init Redis Service sucess!");
        logger.info("---------------------------CoreRdisTicketRegistry {true} ----------------------------=" + redisServers);
    }
    @Override
    public void addTicket(Ticket ticket) {
        logger.debug("Adding ticket {}", ticket);
        try {

            /*reidsTemplate.opsForValue().set(ticket.getId(),ticket, getTimeout(ticket), TimeUnit.SECONDS);*/
            //   
            ObjectsTranscoder objTranscoder =  new ObjectsTranscoder();
            byte[] result1 = objTranscoder.serialize(ticket);
//          Ticket userA_userA = objTranscoder.deserialize(result1); 
            handle.set(ticket.getId().getBytes(), result1, getTimeout(ticket));
            logger.info("---------------------------CoreRdisTicketRegistry { add ticket } -----------------------------" + ticket.getId());
        } catch (final Exception e) {
            logger.error("Failed adding {}", ticket, e);
        }
    }

    @Override
    public Ticket getTicket(String ticketId) {
         Ticket tic =null;
         try {

                /*final Ticket t = (Ticket) this.reidsTemplate.opsForValue().get(ticketId);*/
                String defaultvalue = "";
                byte[] result = this.handle.get(ticketId.getBytes(), defaultvalue.getBytes());
                if ("".equals(result)) {
                    return null;
                } 
                //   
                ObjectsTranscoder objTranscoder =  new ObjectsTranscoder();
                tic = objTranscoder.deserialize(result); 
                if (tic != null) {
                    logger.debug("Ticket [{}] found in registry.", ticketId);
                   /* return getProxiedTicketInstance(tic);*/
                }
                logger.info("---------------------------CoreRdisTicketRegistry { GET ticket } -----------------------------" + ticketId);
            } catch (final Exception e) {
                logger.error("Failed fetching {} ", ticketId, e);
            }
            return tic;
    }

    @Override
    public boolean deleteTicket(String ticketId) {
         logger.debug("Deleting ticket {}", ticketId);
            try {

                  /*this.reidsTemplate.delete(ticketId);*/
                 this.handle.del(ticketId);
                 logger.info("---------------------------CoreRdisTicketRegistry { DELETE ticket } -----------------------------" + ticketId);
                 return true;
            } catch (final Exception e) {
                logger.error("Failed deleting {}", ticketId, e);
            }
            return false;
    }

    @Override
    public Collection 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);*/
            this.handle.del(ticket.getId());
            //   
            ObjectsTranscoder objTranscoder =  new ObjectsTranscoder();
            byte[] result1 = objTranscoder.serialize(ticket);
            handle.set(ticket.getId(), result1.toString(), getTimeout(ticket));
            logger.info("---------------------------CoreRdisTicketRegistry { UPDATE ticket } -----------------------------" + ticket.getId());
        } 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");
    }
}

シーケンス化
/**
 * 
 */
package org.jasig.cas.ticket.registry.util.serialize;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

import org.apache.log4j.Logger;
/**
 * @author lumz
 *
 */
public class ObjectsTranscoder<M extends Serializable> extends SerializeTranscoder {
    protected static Logger logger = Logger.getLogger(SerializeTranscoder.class);
    /* (non-Javadoc)
     * @see org.jasig.cas.ticket.registry.util.serialize.SerializeTranscoder#serialize(java.lang.Object)
     */
    @SuppressWarnings("unchecked")
      @Override
      public byte[] serialize(Object value) {
        if (value == null) {  
          throw new NullPointerException("Can't serialize null");  
        }  
        byte[] result = null;  
        ByteArrayOutputStream bos = null;  
        ObjectOutputStream os = null;  
        try {  
          bos = new ByteArrayOutputStream();  
          os = new ObjectOutputStream(bos);
          M m = (M) value;
          os.writeObject(m);  
          os.close();  
          bos.close();  
          result = bos.toByteArray();  
        } catch (IOException e) {  
          throw new IllegalArgumentException("Non-serializable object", e);  
        } finally {  
          close(os);  
          close(bos);  
        }  
        return result;  
      }

    /* (non-Javadoc)
     * @see org.jasig.cas.ticket.registry.util.serialize.SerializeTranscoder#deserialize(byte[])
     */
    @SuppressWarnings("unchecked")
      @Override
      public M deserialize(byte[] in) {
        M result = null;  
        ByteArrayInputStream bis = null;  
        ObjectInputStream is = null;  
        try {  
          if (in != null) {  
            bis = new ByteArrayInputStream(in);  
            is = new ObjectInputStream(bis);  
            result = (M) is.readObject();  
            is.close();  
            bis.close();  
          }  
        } catch (IOException e) {  
            logger.error(String.format("Caught IOException decoding %d bytes of data",  
              in == null ? 0 : in.length) + e);  
        } catch (ClassNotFoundException e) {  
            logger.error(String.format("Caught CNFE decoding %d bytes of data",  
              in == null ? 0 : in.length) + e);  
        } finally {  
          close(is);  
          close(bis);  
        }  
        return result;  
      }

}

RedisTools.java
“` /** * */ package org.jasig.cas.ticket.registry.util;
import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set;
import redis.clients.jedis.JedisCluster; import redis.clients.jedis.ScanParams; import redis.clients.jedis.ScanResult; import redis.clients.jedis.Tuple;
/** * @author lumz 2016-7-12 10:13:17 * */ public class RedisTools { private JedisCluster jedisCluster;
    public RedisTools(JedisCluster jedisCluster) {
        super();
        this.jedisCluster = jedisCluster;
    }

    // ----------------------- base handle -------------------------

    /**
     *   KEY    
     *
     * @param key
     * @return
     */
    public boolean del(String key) {
        jedisCluster.del(key);
        return true;
    }

    /**
     *   Key    
     *
     * @param key
     * @return
     */
    public boolean exist(String key) {
        return jedisCluster.exists(key);
    }

    /**
     *   key+domain    
     *
     * @param domain   
     * @param key      
     * @return
     */

    public boolean existsHSet(String domain, String key) {
        return jedisCluster.hexists(key, domain);
    }

    /**
     *     hset
     *
     * @param match field    
     * @return
     */
    public List> scanHSet(String key, String match) {
        int cursor = 0;
        ScanParams scanParams = new ScanParams();
        scanParams.match(match);
        ScanResult> scanResult;
        List> list = new ArrayList>();
        do {
            scanResult = jedisCluster.hscan(key, String.valueOf(cursor));// .hscan(,
            // scanParams);
            list.addAll(scanResult.getResult());
            cursor = Integer.parseInt(scanResult.getStringCursor());
        } while (cursor > 0);
        return list;
    }

    /**
     *    domain             value 
     *
     * @param domain
     * @return
     */
    public List hvals(String domain) {
        return jedisCluster.hvals(domain);
    }

    /**
     *    domain             key 
     *
     * @param domain
     * @return
     */
    public Set hkeys(String domain) {
        return jedisCluster.hkeys(domain);
    }

    /**
     *    domain      key   
     *
     * @param domain
     * @return
     */
    public long lenHset(String domain) {
        return jedisCluster.hlen(domain);
    }

    /**
     *     Key   Value,      
     *
     * @param key
     * @param value
     * @param second
     * @return
     */
    public boolean set(String key, String value, int second) {
        jedisCluster.setex(key, second, value);
        return true;
    }

    /**
     *     Key   Value,      
     *
     * @param key
     * @param value
     * @param second
     * @return
     */
    public boolean set(byte[] key, byte[] value, int second) {
        jedisCluster.setex(key, second, value);
        return true;
    }
    /**
     *     Key   Value
     *
     * @param key
     * @param value
     * @return
     */
    public boolean set(String key, String value) {
        jedisCluster.set(key, value);
        return true;
    }

    /**
     *     Key   Value
     *
     * @param key
     * @param value
     * @return
     */
    public boolean append(String key, String value) {
        jedisCluster.append(key, value);
        return true;
    }

    /**
     *   Key   Value
     *
     * @param key
     * @param defaultValue
     * @return
     */
    public String get(String key, String defaultValue) {
        String value = jedisCluster.get(key);
        if (null != value && !"".equals(value)) {
            return value;
        } else {
            return defaultValue;
        }
    }
    /**
     *   Key   Value
     *
     * @param key
     * @param defaultValue
     * @return
     */
    public byte[] get(byte[] key, byte[] defaultValue) {
        byte[] value = jedisCluster.get(key);
        if (null != value && !"".equals(value)) {
            return value;
        } else {
            return defaultValue;
        }
    }

    /**
     *    key
     *
     * @param key
     * @param newKey
     * @return
     */
    public boolean rename(String key, String newKey) {
        jedisCluster.rename(key, newKey);
        return true;
    }

    /**
     *   +1
     *
     * @param key
     * @return
     */
    public long incr(String key) {
        return jedisCluster.incr(key);
    }

    /**
     *   -1
     *
     * @param key
     * @return
     */
    public long decr(String key) {
        return jedisCluster.decr(key);
    }

    /**
     *       
     *
     * @param key
     * @param seconds
     */
    public void expire(String key, int seconds) {
        jedisCluster.expire(key, seconds);
    }

    // ----------------------- hSet handle -------------------------

    /**
     *   HashSet  
     *
     * @param domain   
     * @param key      
     * @param value  Json String or String value
     * @return
     */

    public boolean setHSet(String key, String domain, String value) {
        jedisCluster.hset(key, domain, value);
        return true;
    }

    /**
     *   HashSet  
     *
     * @param domain   
     * @param key      
     * @return Json String or String value
     */
    public String getHSet(String domain, String key) {
        return jedisCluster.hget(key, domain);
    }

    /**
     *                 
     *
     * @param key   
     * @return
     */
    public Map getHGetAll(String key) {
        return jedisCluster.hgetAll(key);
    }

    /**
     *   HashSet  
     *
     * @param domain   
     * @param key      
     * @return       
     */

    public long delHSet(String domain, String key) {
        return jedisCluster.hdel(key, domain);
    }

    /**
     *   HashSet     domains
     *
     * @param domain   
     * @param key      
     * @return       
     */

    public long delHSet(String key, String... domain) {
        return jedisCluster.hdel(key, domain);
    }

    // ----------------------- sortedSet handle -------------------------

    /**
     *       
     *
     * @param key
     * @param score
     * @param value
     * @return
     */
    public boolean setSortedSet(String key, long score, String value) {
        jedisCluster.zadd(key, score, value);
        return true;
    }

    /**
     *       
     *
     * @param key
     * @param startScore
     * @param endScore
     * @param orderByDesc
     * @return
     */
    public Set getSoredSet(String key, long startScore, long endScore, boolean orderByDesc) {
        if (orderByDesc) {
            return jedisCluster.zrevrangeByScore(key, endScore, startScore);
        } else {
            return jedisCluster.zrangeByScore(key, startScore, endScore);
        }
    }

    /**
     *       
     *
     * @param key
     * @param startScore
     * @param endScore
     * @param count
     * @param offset
     * @param orderByDesc
     * @return
     */
    public Set getSoredSet(String key, long startScore, long endScore, int offset, int count,
            boolean orderByDesc) {
        if (orderByDesc) {
            return jedisCluster.zrevrangeByScore(key, endScore, startScore, offset, count);
        } else {
            return jedisCluster.zrangeByScore(key, startScore, endScore, offset, count);
        }
    }

    /**
     *       
     *
     * @param key
     * @param startScore
     * @param endScore
     * @return
     */
    public long countSoredSet(String key, long startScore, long endScore) {
        Long count = jedisCluster.zcount(key, startScore, endScore);
        return count == null ? 0L : count;
    }

    /**
     *       
     *
     * @param key
     * @return
     */
    public long countSoredSet(String key) {
        Long count = jedisCluster.zcard(key);
        return count == null ? 0L : count;
    }

    /**
     *       
     *
     * @param key
     * @param value
     * @return
     */
    public boolean delSortedSet(String key, String value) {
        long count = jedisCluster.zrem(key, value);
        return count > 0;
    }

    /**
     *       
     *
     * @param key
     * @param start
     * @param end
     * @return
     */
    public boolean delRankSortedSet(String key, long start, long end) {
        long count = jedisCluster.zremrangeByRank(key, start, end);
        return count > 0;
    }

    /**
     *         
     *
     * @param key
     * @return
     */
    public boolean delSortedSet(String key, long minScore, long maxScore) {
        long count = jedisCluster.zremrangeByScore(key, minScore, maxScore);
        return count > 0;
    }

    /**
     *          N 
     *
     * @param key
     * @param topN
     * @return
     */
    public Set zrevrangeWithScores(String key, int topN) {
        return jedisCluster.zrevrangeWithScores(key, 0, topN);
    }

    /**
     *                
     *
     * @param key
     * @param start
     * @param end
     * @return
     */
    public Set zrevrangeWithScores(String key, long start, long end) {
        return jedisCluster.zrevrangeWithScores(key, start, end);
    }

    // ----------------------- List handle -------------------------

    /**
     *   lpush  
     *                 
     *
     * @param key
     * @param value
     */
    public void lpush(String key, String... value) {
        jedisCluster.lpush(key, value);
    }

    /**
     *   rpush  
     *                (   )
     *
     * @param key
     * @param value
     */
    public void rpush(String key, String... value) {
        jedisCluster.rpush(key, value);
    }

    /**
     *     
     *
     * @param key
     */
    public long llen(String key) {
        return jedisCluster.llen(key);
    }

    /**
     *   start stop    
     *
     * @param key
     * @param start
     * @param stop
     * @return
     */
    public List lrange(String key, int start, int stop) {
        return jedisCluster.lrange(key, start, stop);
    }

    /**
     *     
     *
     * @param key
     * @param count count > 0 :           ,    value      ,    count 。 count < 0 :
     *                        ,    value      ,    count     。 count = 0 :        
     *              value     。
     * @param value
     * @return
     */
    public long lrem(String key, int count, String value) {
        return jedisCluster.lrem(key, count, value);
    }

    /**
     *     
     *
     * @param key
     * @param start
     * @param end
     */
    public void ltrim(String key, int start, int end) {
        jedisCluster.ltrim(key, start, end);
    }

    /**
     *                 ,                
     *
     * @param key
     * @param member
     * @return
     */
    public Long sadd(String key, String... member) {
        return jedisCluster.sadd(key, member);
    }

    /**
     *     
     *
     * @param key
     * @param member
     * @return
     */
    public Long srem(String key, String... member) {
        return jedisCluster.srem(key, member);
    }

    /**
     *   set    
     *
     * @param key
     * @return
     */
    public Set smembers(String key) {
        return jedisCluster.smembers(key);
    }

    /**
     *   member       key   
     *
     * @param key
     * @param member
     * @return
     */
    public boolean sismember(String key, String member) {
        return jedisCluster.sismember(key, member);
    }

    // ----------------------- mSet handle -------------------------
    public String setMSet(String key, Map hash) {
        return jedisCluster.hmset(key, hash);
    }

}
“`SerializeTranscoder package org.jasig.cas.ticket.registry.util.serialize;
import java.io.Closeable; import org.apache.log4j.Logger;
/** * @author lumz * * @date 2016-7-12 10:44:07 */ public abstract class SerializeTranscoder {
  protected static Logger logger = Logger.getLogger(SerializeTranscoder.class);

  public abstract byte[] serialize(Object value);

  public abstract Object deserialize(byte[] in);

  public void close(Closeable closeable) {
    if (closeable != null) {
      try {
        closeable.close();
      } catch (Exception e) {
         logger.info("Unable to close " + closeable, e); 
      }
    }
  }

}
参考資料
【1】Tomcat redis session manager【2】CAS Ticket redisベースのクラスタの実装