GO——6分布式锁分布式id___自己使用redis实现,(官方),,分布式id,,go协程,,gin框架,,

分布式锁分布式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 上启动服务
}

 

posted @ 2024-04-10 08:36  拆尼斯、帕丁顿  阅读(49)  评论(0)    收藏  举报