分布式锁分布式id
# 锁的作用:保证多线程并发情况下,数据的安全 -互斥锁 -递归锁 只能保证同一个进程下的线程 # django项目---》部署在多台机器上---》下单场景---》悲观锁--》同一时刻,必须获得锁才能进入下单流程,释放锁--》别人才能进入下单流程 -用mysql的表锁---》行锁 -分布式锁的一种方案 # 在分布式系统重,保证并发情况下的数据安全 # 分布式锁的实现方案 -mysql行锁表锁 -zookeeper(不聊) -redis实现 -redis官方 -实现起来比较简单--》公司自己写
自己使用redis实现(redis实现分布式锁的原理)
# 连接redis # 保证性能 # 保证不出死锁 import redis from threading import Thread import time import uuid redis_client = redis.Redis(host="localhost", port=6379, db=10) # 获取一个锁 # lock_name:锁定名称 # acquire_time: 客户端等待获取锁的时间 # time_out: 锁的超时时间 def acquire_lock(lock_name, acquire_time=10, time_out=10): """获取一个分布式锁""" identifier = str(uuid.uuid4()) end = time.time() + acquire_time lock = "string:lock:" + lock_name while time.time() < end: if redis_client.setnx(lock, identifier): # 给锁设置超时时间, 防止进程崩溃导致其他进程无法获取锁 redis_client.expire(lock, time_out) return identifier elif not redis_client.ttl(lock): redis_client.expire(lock, time_out) time.sleep(0.001) return False # 释放一个锁 def release_lock(lock_name, identifier): """通用的锁释放函数""" lock = "string:lock:" + lock_name pip = redis_client.pipeline(True) while True: try: pip.watch(lock) lock_value = redis_client.get(lock) if not lock_value: return True if lock_value.decode() == identifier: pip.multi() pip.delete(lock) pip.execute() return True pip.unwatch() break except redis.excetions.WacthcError: pass return False def seckill(i): identifier = acquire_lock('resource') print("第%s个线程执行秒杀"%i) release_lock('resource', identifier) for i in range(50): t = Thread(target=seckill,args=[i,]) t.start()
官方
#redlock 实现 pip install redlock-py dlm = Redlock([{"host": "localhost", "port": 6379, "db": 0}, ]) 要获得锁的地方 my_lock = dlm.lock("my_resource_name",1000) 要释放锁的地方 dlm.unlock(my_lock) ---------------------------------------- from redlock import Redlock lock=Redlock([{"host": "localhost", "port": 6379, "db": 0}, ]) def task(): my_lock=lock.lock("my_resource_name",1000) # 你的代码 # 下单---》操作好多数据 # 释放锁 lock.unlock(my_lock)
分布式id
# 下单场景订单号 任务id号 # 在不同机器上,生成永不重复的 id号-->效率尽量高,尽量有规律递增 # 可以的方案 1 uuid 规律递增,不会重复 2 mysql 自增 --》容易被猜到,存在漏洞,效率不高 3 redis 自增 ---》时间戳+机器id号+redis自增数字 4 雪花算法 5 美团 leaf算法
go 协程
# 进程 # 线程 ------不能开启进程和线程---- ---实现并发,go中有并发方案--》goroutine--》go协程 # 协程: 协程+线程池解决方案--》内部实现
gin框架
# 配置代理 # 下载 go get -u github.com/gin-gonic/gin
package main import ( "github.com/gin-gonic/gin" "net/http" ) func ping(c *gin.Context) { c.JSON(200, gin.H{ "message": "pong", }) } func index(c *gin.Context) { c.HTML(http.StatusOK, "index.html", gin.H{ "title": "lqz", }) } func demo(c *gin.Context) { var name = "彭于晏" c.String(http.StatusOK, "Hello %s", name) } func main() { r := gin.Default() r.LoadHTMLGlob("templates/*") r.GET("/ping", ping) r.GET("/index", index) r.GET("/demo", demo) r.Run("0.0.0.0:8000") // 监听并在 0.0.0.0:8000 上启动服务 }
标签:协程,name,lock,redis,time,gin,id,分布式 From: https://www.cnblogs.com/wzh366/p/18125290