def acquire_lock_with_timeout(redis, lockname, acquire_timeout=10, lock_timeout=30): """ 正确地实现基本地加锁, (设置超时时间的锁) setnx 命令天生就适用来实现锁地获取功能,这个命令只会在键不存在地情况下为键设置值, 而锁要做的就是将一个随机生成的128位uuid设置为键的值,并使用这个值来防止锁被其他进程取得。 :param redis: :param lockname: 锁名称 :param acquire_timeout: :return: """ identifire = str(uuid.uuid4()) lockname = 'lock:' + lockname end = time.time() + acquire_timeout # 确保传给EXPIRE的都是整数 lock_timeout = int(math.ceil(lock_timeout)) while time.time() < end: if redis.setnx(lockname, identifire ): # 以锁名称为键,uuid的值为值,redis服务器setnx保证了只能有一个客户端成功设置键的原子性 redis.expire(lockname, lock_timeout) # 设置键的过期时间,过期自动剔除,释放锁 return identifire elif not redis.ttl(lockname): # 当锁未被设置过期时间时,重新设置其过期时间 redis.expire(lockname, lock_timeout) time.sleep(0.001) return None
def acquire_lock(lockname, identifier, wait_time=20, timeout=15): end = time.time() + wait_time while end > time.time(): if CONN.setnx(lockname, identifier): CONN.expire(lockname, timeout) # set expire time return identifier elif not redis.ttl(lockname): # 当锁未被设置过期时间时,重新设置其过期时间 redis.expire(lockname, timeout) time.sleep( 0.001) # wait until the lock expired or release by some thread return False
def _f(*args, **kwargs): # TODO: this could be used as a DoS attack by filling up # redis. Maybe add global rate limiting? k = "rl:%s_%s" % (f.__name__, request.remote_addr) if not redis.exists(k) or not redis.ttl(k): redis.delete(k) redis.setex(k, 1, 60) return f(*args, **kwargs) if int(redis.get(k)) > per_minute: return "Too many requests per minute!", 429 redis.incr(k) return f(*args, **kwargs)
def acquire_lock(redis, lockname, acquire_timeout=10, lock_timeout=30): identifire = str(uuid.uuid4()) lockname = 'lock:' + lockname end = time.time() + acquire_timeout # 确保传给EXPIRE的都是整数 lock_timeout = int(math.ceil(lock_timeout)) while time.time() < end: if redis.set( lockname, identifire, ex=lock_timeout, nx=True): # 以锁名称为键,uuid的值为值,redis服务器setnx保证了只能有一个客户端成功设置键的原子性 # redis.expire(lockname, lock_timeout) # 设置键的过期时间,过期自动剔除,释放锁 return identifire elif not redis.ttl(lockname): # 当锁未被设置过期时间时,重新设置其过期时间 redis.expire(lockname, lock_timeout) time.sleep(0.001) return None
def acquire_lock_with_timeout2(redis, lockname, acquire_timeout=10, lock_timeout=30): """ 正确地实现基本地加锁, (设置超时时间的锁) setnx 命令天生就适用来实现锁地获取功能,这个命令只会在键不存在地情况下为键设置值, 而锁要做的就是将一个随机生成的128位uuid设置为键的值,并使用这个值来防止锁被其他进程取得。 set(name, value, ex=None, px=None, nx=False, xx=False) ex,过期时间(秒) px,过期时间(毫秒) nx,如果设置为True,则只有name不存在时,当前set操作才执行,同setnx(name, value) xx,如果设置为True,则只有name存在时,当前set操作才执行''' setex(name, value, time) #设置过期时间(秒) psetex(name, time_ms, value) #设置过期时间(豪秒) :param redis: :param lockname: 锁名称 :param acquire_timeout: :return: """ identifire = str(uuid.uuid4()) lockname = 'lock:' + lockname end = time.time() + acquire_timeout # 确保传给EXPIRE的都是整数 lock_timeout = int(math.ceil(lock_timeout)) while time.time() < end: if redis.set( lockname, identifire, ex=lock_timeout, nx=True): # 以锁名称为键,uuid的值为值,redis服务器setnx保证了只能有一个客户端成功设置键的原子性 # redis.expire(lockname, lock_timeout) # 设置键的过期时间,过期自动剔除,释放锁 return identifire elif not redis.ttl(lockname): # 当锁未被设置过期时间时,重新设置其过期时间 redis.expire(lockname, lock_timeout) time.sleep(0.001) return None
def api_limit_checker(redis, sid, ip, api_path): """ Api 访问限制器 """ ip_access_table = USER_API_ACCESS_TABLE % (ip) pipe = redis.pipeline() if redis.exists(ip_access_table): if not redis.ttl(ip_access_table): """ 防止系统没删掉 """ redis.delete(ip_access_table) pipe.hincrby(ip_access_table, api_path, 1) pipe.expire(ip_access_table, USER_API_EXPIRE) elif convert_util.to_int(redis.hget(ip_access_table, api_path)) > 200: """ 异常的请求 """ return False else: """ 记录API访问次数 """ pipe.hincrby(ip_access_table, api_path, 1) else: pipe.hset(ip_access_table, api_path, 1) pipe.expire(ip_access_table, USER_API_EXPIRE) return pipe.execute()
# print 'hello' # print str(10*24*3600) print '1' redis = getRedisConn() print '2' # redis.delete('试试中文') # redis.set('试试中文','不试') # print redis.get('试试中文') # sessionPool = RedisSessionStore(redis_connection=redis) # session = Session(session_store = sessionPool, sessionid = 'baojianpin',logined=True) # session['test'] = 'goodmorning' # session['hello'] = 'word' # # print session['good'] print redis.hget('session:baojianpin', 'data') print redis.ttl("session:baojianpin") pass # ''' # 使用dict实现的简单sessionStore # 使用方式 # ''' # class SessionStore(object): # # def __init__(self): # self.db = getRedisConn2() # self.session_poll = self.db # # self.session_last = {} #'session的最后访问时间 # # t = threading.Thread(target=self.__remove_dead_session) #定时对sessionStore中没用的session进行删除 # # t.setDaemon(True)
import redis import ast redis = redis.StrictRedis(host='localhost', port=6379, db=0) key = "28499950-7085-11e4-9890-7071bcbc887a" talk = ast.literal_eval(redis.get(key)) talk['t'] = talk['t'].replace('"', "'") exp = redis.ttl(key) redis.delete(key) redis.setnx(key, talk)
import redis ''' 假设该商品有1000份 goods_num = 1000 开抢之前设定好一个1000个元素的 redis set集合 goods_set(每个元素为商品id(goods_id)) sadd goods_set [1 ,2 ,3 ,4 .. 1000] uid = 1 ''' # 限制频繁请求 check_act = redis.incr('check_act'+uid) if check_act>1: redis.ttl('check_act'+uid, 1) return '请求过于频繁,请稍后再试' # 查询该用户是否抢购成功过 check = redis.incr('check_'+uid) if check and check>=1: return '你已经抢购过了' goods_id= redis.spop(goods_set) if goods_id: # 抢购成功 ''' business 抢购成功业务处理 '''
# print 'hello' # print str(10*24*3600) print '1' redis = getRedisConn() print '2' # redis.delete('试试中文') # redis.set('试试中文','不试') # print redis.get('试试中文') # sessionPool = RedisSessionStore(redis_connection=redis) # session = Session(session_store = sessionPool, sessionid = 'baojianpin',logined=True) # session['test'] = 'goodmorning' # session['hello'] = 'word' # # print session['good'] print redis.hget('session:baojianpin','data') print redis.ttl("session:baojianpin") pass # ''' # 使用dict实现的简单sessionStore # 使用方式 # ''' # class SessionStore(object): # # def __init__(self): # self.db = getRedisConn2() # self.session_poll = self.db # # self.session_last = {} #'session的最后访问时间 # # t = threading.Thread(target=self.__remove_dead_session) #定时对sessionStore中没用的session进行删除 # # t.setDaemon(True)
def get_ttl(key): return redis.ttl(key)