public static void main(String[] args) {
//连接本地的 Redis 服务
Jedis jedis = new Jedis("localhost")
System.out.println("Connection to server sucessfully")
//存储数据到列表中
jedis.lpush("tutorial-list", "Redis")
jedis.lpush("tutorial-list", "Mongodb")
jedis.lpush("tutorial-list", "Mysql")
// 获取存储的数据并输出
List<String> list = jedis.lrange("tutorial-list", 0 ,5)
for(int i=0 i<list.size() i++) {
System.out.println("Stored string in redis:: "+list.get(i))
}
}
}
我介绍一下Redis分布式锁吧:
一、定义redis实现分布式锁的接口
[java] view plain copy print?package com.iol.common.util.concurrent.locks
import java.io.Serializable
/**
* Description: 定义redis实现分布式锁的算法<br />
* This program is protected by copyright IOL_SMALL_TAIL.<br />
* Program Name: IOL_SMALL_TAIL<br />
* Date: 2015年11月8日
*
* @author 王鑫
* @version 1.0
*/
public interface IRedisLockArithmetic extends Serializable {
/**
* 加锁算法<br />
* @param key
* @return
*/
public boolean lock(String key)
/**
* 解锁算法<br />
* @param key
* @return
*/
public boolean unLock(String key)
}
二、redis分布式锁基础算法实现
[java] view plain copy print?package com.iol.common.util.concurrent.locks.arithmetic
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import com.iol.common.util.concurrent.locks.IRedisComponent
import com.iol.common.util.concurrent.locks.IRedisLockArithmetic
/**
* Description: redis分布式锁基础算法实现<br />
* This program is protected by copyright IOL_SMALL_TAIL.<br />
* Program Name: IOL_SMALL_TAIL<br />
* Date: 2015年11月9日
*
* @author 王鑫
* @version 1.0
*/
public class RedisLockBaseArithmetic implements IRedisLockArithmetic {
/**
*serialVersionUID
*/
private static final long serialVersionUID = -8333946071502606883L
private Logger logger = LoggerFactory.getLogger(RedisLockBaseArithmetic.class)
/**
* redis操作方法
*/
private IRedisComponent redisComp
/**
* 超时时间,以毫秒为单位<br />
* 默认为5分钟
*/
private long overtime = 5 * 60 * 1000L
/**
* 休眠时长,以毫秒为单位<br />
* 默认为100毫秒
*/
private long sleeptime = 100L
/**
* 当前时间
*/
private long currentLockTime
/**
* @param redisComp the redisComp to set
*/
public void setRedisComp(IRedisComponent redisComp) {
this.redisComp = redisComp
}
/**
* @param overtime the overtime to set
*/
public void setOvertime(long overtime) {
this.overtime = overtime
}
/**
* @param sleeptime the sleeptime to set
*/
public void setSleeptime(long sleeptime) {
this.sleeptime = sleeptime
}
/* (non-Javadoc)
* @see com.iol.common.util.concurrent.locks.IRedisLockArithmetic#lock(java.lang.String, java.lang.Long)
*/
@Override
public boolean lock(String key) {
while(true) {
// 当前加锁时间
currentLockTime = System.currentTimeMillis()
if(redisComp.setIfAbsent(key, currentLockTime)) {
// 获取锁成功
logger.debug("直接获取锁{key: {}, currentLockTime: {}}", key, currentLockTime)
return true
} else {
//其他线程占用了锁
logger.debug("检测到锁被占用{key: {}, currentLockTime: {}}", key, currentLockTime)
Long otherLockTime = redisComp.get(key)
if(otherLockTime == null) {
// 其他系统释放了锁
// 立刻重新尝试加锁
logger.debug("检测到锁被释放{key: {}, currentLockTime: {}}", key, currentLockTime)
continue
} else {
if(currentLockTime - otherLockTime >= overtime) {
//锁超时
//尝试更新锁
logger.debug("检测到锁超时{key: {}, currentLockTime: {}, otherLockTime: {}}", key, currentLockTime, otherLockTime)
Long otherLockTime2 = redisComp.getAndSet(key, currentLockTime)
if(otherLockTime2 == null || otherLockTime.equals(otherLockTime2)) {
logger.debug("获取到超时锁{key: {}, currentLockTime: {}, otherLockTime: {}, otherLockTime2: {}}", key, currentLockTime, otherLockTime, otherLockTime2)
return true
} else {
sleep()
//重新尝试加锁
logger.debug("重新尝试加锁{key: {}, currentLockTime: {}}", key, currentLockTime)
continue
}
} else {
//锁未超时
sleep()
//重新尝试加锁
logger.debug("重新尝试加锁{key: {}, currentLockTime: {}}", key, currentLockTime)
continue
}
}
}
}
}
/* (non-Javadoc)
* @see com.iol.common.util.concurrent.locks.IRedisLockArithmetic#unLock(java.lang.String)
*/
@Override
public boolean unLock(String key) {
logger.debug("解锁{key: {}}", key)
redisComp.delete(key)
return true
}
/**
* 休眠<br />
* @param sleeptime
*/
private void sleep() {
try {
Thread.sleep(sleeptime)
} catch (InterruptedException e) {
throw new LockException("线程异常中断", e)
}
}
}
创建一个redis docker容器首先,我们先为redis创建一个Dockerfile
FROMubuntu:12.10
RUN apt-get update
RUN apt-get -y install redis-server
EXPOSE 6379
ENTRYPOINT ["/usr/bin/redis-server"]
现在你需要通过Dockerfile创建一个镜像,将替换成你自己的名字。
sudo docker build -t /redis .
运行服务
使用我们刚才创建的redis镜像
使用 -d 运行这个服务分离模式,让容器在后台运行。
重要的是我们没有开放容器端口,相反,我们将使用一个容器来连接redis容器数据库
sudo docker run -name redis -d /redis
创建你的web应用容器
现在我们可以创建我们的应用程序容器,我们使用-link参数来创建一个连接redis容器,我们使用别名db,这将会在redis容器和redis实例容器中创建一个安全的通信隧道
sudo docker run -link redis:db -i -t ubuntu:12.10 /bin/bash
进入我们刚才创建的容器,我们需要安装redis的redis-cli的二进制包来测试连接
apt-get update
apt-get -y install redis-server
service redis-server stop
现在我们可以测试连接,首先我么要先查看下web应用程序容器的环境变量,我们可以用我们的ip和端口来连接redis容器
env
. . .
DB_NAME=/violet_wolf/db
DB_PORT_6379_TCP_PORT=6379
DB_PORT=tcp://172.17.0.33:6379
DB_PORT_6379_TCP=tcp://172.17.0.33:6379
DB_PORT_6379_TCP_ADDR=172.17.0.33
DB_PORT_6379_TCP_PROTO=tcp
我们可以看到我们有一个DB为前缀的环境变量列表,DB来自指定别名连接我们的现在的容器,让我们使用DB_PORT_6379_TCP_ADDR变量连接到Redis容器。
redis-cli -h $DB_PORT_6379_TCP_ADDR
redis 172.17.0.33:6379>
redis 172.17.0.33:6379>set docker awesome
OK
redis 172.17.0.33:6379>get docker
"awesome"
redis 172.17.0.33:6379>exit
我们可以很容易的使用这个或者其他环境变量在我们的web应用程序容器上连接到redis容器