1.登录和缓存功能实现
package com.redis; import redis.clients.jedis.Jedis; /** * FileName: 登录和缓存 * Author: sujinran * Date: 2018/6/17 15:12 */ public class LoginAndCookie { /** * 检查用户是否登录 * @param conn redis连接 * @param token 令牌 * @return */ public String checkToken(Jedis conn, String token) { //hget散列 return conn.hget("login:", token); } /** * 更新令牌 * @param conn redis连接 * @param token 令牌 * @param user 用户 * @param item 商品 */ public void updateToken(Jedis conn, String token, String user, String item) { //获取当前时间戳 long timestamp = System.currentTimeMillis() / 1000; //令牌和已经登录的用户映射 conn.hset("login:", token, user); //记录令牌最后一次出现的时间 conn.zadd("recent:", timestamp, token); if (item != null) {//传入的商品不是空的 //记录浏览过的商品 conn.zadd("viewed:" + token, timestamp, item); //移除旧的记录,保留最近浏览过的25个商品 conn.zremrangeByRank("viewed:" + token, 0, -26); //Zincrby 命令对有序集合中指定成员的分数加上增量 conn.zincrby("viewed:", -1, item); } } }
更新会话:
package com.util; import redis.clients.jedis.Jedis; import java.util.ArrayList; import java.util.Set; /** * FileName: 更新登录会话 * Author: sujinran * Date: 2018/6/17 19:40 */ public class CleanSessionsThread extends Thread { private Jedis conn; private int limit; private boolean quit; public CleanSessionsThread(int limit) { this.conn = new Jedis("localhost"); this.conn.auth("123456"); this.conn.select(15); this.limit = limit; } public void quit() { quit = true; } public void run() { while (!quit) { //依据登录时间确定在线人数 long size = conn.zcard("recent:"); if (size <= limit) { try { sleep(1000); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); } continue; } long endIndex = Math.min(size - limit, 100); Set<String> tokenSet = conn.zrange("recent:", 0, endIndex - 1); String[] tokens = tokenSet.toArray(new String[tokenSet.size()]); ArrayList<String> sessionKeys = new ArrayList<String>(); for (String token : tokens) { sessionKeys.add("viewed:" + token); } conn.del(sessionKeys.toArray(new String[sessionKeys.size()])); conn.hdel("login:", tokens); conn.zrem("recent:", tokens); } } }
登录和缓存功能测试:
import com.util.CleanSessionsThread; import com.redis.LoginAndCookie; import org.junit.Test; import redis.clients.jedis.Jedis; import java.util.UUID; /** * FileName: 登录和缓存测试 * Author: sujinran * Date: 2018/6/17 19:15 */ public class LoginAndCookieTest { public static void main(String[] args) throws InterruptedException { Jedis conn =new Jedis("127.0.0.1"); conn.auth("123456"); LoginAndCookieTest loginAndCookieTest =new LoginAndCookieTest(); loginAndCookieTest.testLoginCookies(conn); } /** * 登录测试 * * @throws InterruptedException */ public void testLoginCookies(Jedis conn) throws InterruptedException { /* 这里令牌自动生成 UUID.randomUUID().toString():javaJDK提供的一个自动生成主键的方法 */ String token = UUID.randomUUID().toString(); //创建登录和缓存类的对象 LoginAndCookie loginAndCookie = new LoginAndCookie(); /* 使用 LoginAndCookie 中的updateToken()的方法更新令牌 conn:Redis连接,user1:用户,item1:商品 */ loginAndCookie.updateToken(conn, token, "user1", "item1"); System.out.println("我们刚刚登录/更新了令牌:" + token); System.out.println("用户使用: 'user1'"); System.out.println(); System.out.println("当我们查找令牌时会得到什么用户名"); String r = loginAndCookie.checkToken(conn, token); //r是令牌 System.out.println(r); System.out.println(); assert r != null; System.out.println("让我们把cookies的最大数量降到0来清理它们"); System.out.println("我们开始用线程来清理,一会儿再停止"); CleanSessionsThread thread = new CleanSessionsThread(0); thread.start(); Thread.sleep(1000); thread.quit(); Thread.sleep(2000); if (thread.isAlive()) { throw new RuntimeException("线程还存活?!?"); } //Hlen命令用于获取哈希表中字段的数量 long s = conn.hlen("login:"); System.out.println("目前仍可提供的sessions次数如下: " + s); assert s == 0; } }
2.购物车功能实现
package com.redis; import redis.clients.jedis.Jedis; /** * FileName: 购物车实现 * Author: sujinran * Date: 2018/6/17 20:27 */ public class AddToCart { /** * 购物车实现 * @param conn 连接 * @param session 会话 * @param item 商品 * @param count 总数 */ public void addToCart(Jedis conn, String session, String item, int count) { //总数<=0 if (count <= 0) { // 购物车移除指定的商品,HDEL 每次只能删除单个域 conn.hdel("cart:" + session, item); } else { //将指定的商品添加到购物车,Hset 命令用于为哈希表中的字段赋值 conn.hset("cart:" + session, item, String.valueOf(count)); } } }
更新会话:
package com.util; import redis.clients.jedis.Jedis; import java.util.ArrayList; import java.util.Set; /** * FileName: 更新购物车会话 * Author: sujinran * Date: 2018/6/17 20:35 */ public class CleanFullSessionsThread extends Thread { private Jedis conn; private int limit; private boolean quit; public CleanFullSessionsThread(int limit) { this.conn = new Jedis("localhost"); this.conn.auth("123456"); this.conn.select(15); this.limit = limit; } public void quit() { quit = true; } public void run() { while (!quit) { long size = conn.zcard("recent:"); if (size <= limit) { try { sleep(1000); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); } continue; } long endIndex = Math.min(size - limit, 100); Set<String> sessionSet = conn.zrange("recent:", 0, endIndex - 1); String[] sessions = sessionSet.toArray(new String[sessionSet.size()]); ArrayList<String> sessionKeys = new ArrayList<String>(); for (String sess : sessions) { sessionKeys.add("viewed:" + sess); sessionKeys.add("cart:" + sess); } conn.del(sessionKeys.toArray(new String[sessionKeys.size()])); conn.hdel("login:", sessions); conn.zrem("recent:", sessions); } } }
购物车功能测试:
import com.redis.AddToCart; import com.redis.LoginAndCookie; import com.util.CleanFullSessionsThread; import redis.clients.jedis.Jedis; import java.util.Map; import java.util.UUID; /** * FileName: 添加商品到购物车测试 * Author: sujinran * Date: 2018/6/17 20:39 */ public class AddToCartTest { AddToCart addToCart =new AddToCart(); LoginAndCookie loginAndCookie =new LoginAndCookie(); public static void main(String[] args) throws InterruptedException { Jedis conn = new Jedis("127.0.0.1"); conn.auth("123456"); AddToCartTest addToCartTest =new AddToCartTest(); addToCartTest.testShopppingCartCookies(conn); } /** * 添加商品到购物车测试 * @param conn * @throws InterruptedException */ public void testShopppingCartCookies(Jedis conn) throws InterruptedException { /* 这里令牌自动生成 UUID.randomUUID().toString():javaJDK提供的一个自动生成主键的方法 */ String token = UUID.randomUUID().toString(); System.out.println("我们将刷新我们的会话."); loginAndCookie.updateToken(conn, token, "user2", "item2"); System.out.println("并在购物车中添加一个商品"); addToCart.addToCart(conn, token, "item2", 3); Map<String, String> r = conn.hgetAll("cart:" + token); System.out.println("我们的购物车目前有:"); for (Map.Entry<String, String> entry : r.entrySet()) { System.out.println(" " + entry.getKey() + ": " + entry.getValue()); } System.out.println(); assert r.size() >= 1; System.out.println("让我们清理我们的会话和购物车"); CleanFullSessionsThread thread = new CleanFullSessionsThread(0); thread.start(); Thread.sleep(1000); thread.quit(); Thread.sleep(2000); if (thread.isAlive()) { throw new RuntimeException("清理会话线程还存在"); } r = conn.hgetAll("cart:" + token); System.out.println("我们的购物车现在装有:"); for (Map.Entry<String, String> entry : r.entrySet()) { System.out.println(" " + entry.getKey() + ": " + entry.getValue()); } assert r.size() == 0; } }