Redis分布式锁实战

Redis分布式锁实战

引言

多服务器部署项目时,多个服务实例同时操作同一资源,会出现并发争抢问题。Redis分布式锁可以保证同一时间只有一个请求执行临界代码,常用于订单扣库存、定时任务防重复执行场景。

实现原理

利用RedisSET key value NX EX命令:NX仅当key不存在才设置,EX设置过期时间。原子命令可以防止锁成功后服务宕机导致死锁。解锁时需要校验锁的值,防止误删除别人的锁。

PHP代码示例

<?php
$redis = new Redis();
$redis->connect('127.0.0.1',6379);
$lockKey = 'order:lock:1001';
$lockVal = uniqid();
// 获取锁,过期10秒
$ok = $redis->set($lockKey,$lockVal,['NX','EX'=>10]);
if($ok){
    try{
        // 临界区业务代码
        echo "获取锁,执行业务";
    }finally{
        // lua脚本原子解锁,判断value一致才删除
        $lua = 'if redis.call("get",KEYS[1]) == ARGV[1] then return redis.call("del",KEYS[1]) else return 0 end';
        $redis->eval($lua,[$lockKey,$lockVal],1);
    }
}else{
    echo "获取锁失败,资源被占用";
}

注意事项

  1. 锁必须设置过期时间,防止程序崩溃死锁;
  2. 解锁必须用Lua脚本,保证判断和删除原子操作;
  3. 业务执行时间不能超过锁过期时间,可增加锁续期逻辑;
  4. 单机Redis存在单点故障,高可用场景用Redis集群或Redlock。

总结

Redis分布式锁简单易用,适合中小型Web项目并发控制。理解原子操作、锁过期、安全解锁三个关键点,避免网上简易版本带来的并发漏洞。


emer 发布于  2026-10-18 07:11 

MySQL索引设计原则

MySQL索引设计原则

引言

MySQL索引相当于书籍目录,快速定位数据,避免全表扫描。不合理的索引不仅无法提升查询速度,还会降低写入性能。索引设计是数据库优化最基础、最高效的手段,建站、接口开发都需要掌握。

索引核心原理

InnoDB引擎索引基于B+树实现,主键索引叶子节点存储完整行数据;二级索引叶子节点存储主键值,查询会触发回表。索引字段越大,占用磁盘越多,内存缓存能存放的索引越少,查询越慢。

索引设计核心原则

  1. 选择性优先:优先给区分度高的字段建索引,如手机号、ID;性别、状态这类只有少量枚举值字段不适合单独建索引。
  2. 联合索引遵循最左匹配原则,字段顺序:等值查询在前,范围查询放后面。
  3. 避免在索引字段做函数运算,where YEAR(create_time)=2026会直接失效索引。
  4. 不要过度建索引,每次新增、更新、删除数据,所有索引都需要同步更新,拖累写入。

示例SQL

-- 联合索引示例,适合 where uid=100 and create_time>xxx
CREATE INDEX idx_uid_ct ON user(uid,create_time);

-- 查看sql是否命中索引
EXPLAIN SELECT * FROM user WHERE uid=100;

常见踩坑

  • 字符串字段不加引号,隐式类型转换,索引失效;
  • 模糊查询%关键词,前置百分号不走索引;
  • 联合索引跳过左侧字段,无法触发索引。

总结

索引不是越多越好,按需创建。建索引前先用explain分析执行计划,优先优化高频查询SQL,控制索引数量,平衡查询与写入性能。


emer 发布于  2026-10-18 07:10 

PHP trait复用代码方案

PHP trait复用代码方案

引言

在PHP面向对象开发中,类只支持单继承,一个子类只能继承一个父类。当多个不同类需要共用一段逻辑,又不想强行继承同一父类时,Trait特性就是最佳解决方案。Trait可以把可复用的方法抽离出来,在多个类中引入,打破单继承限制,广泛用于项目公共方法封装。

Trait基础原理

Trait本质不是类,不能实例化,仅用于封装方法。使用use关键字在类内部引入,引入后,类可以直接调用Trait内定义的方法。

优先级规则:本类方法 > trait方法 > 父类方法。当方法重名时,优先执行当前类定义的代码。

代码示例

<?php
trait LogTrait {
    public function writeLog(string $msg) {
        $log = date('Y-m-d H:i:s') . " : " . $msg . PHP_EOL;
        file_put_contents('./run.log', $log, FILE_APPEND);
    }
}

class UserService {
    use LogTrait;
    public function addUser() {
        $this->writeLog("新增用户数据");
    }
}

$user = new UserService();
$user->addUser();
?>

多Trait冲突处理

一个类可以同时use多个Trait。多个Trait存在同名方法会直接报错,这时使用insteadof指定优先使用哪个Trait的方法,as可以给方法起别名。

trait A{ public function test(){echo "A";}}
trait B{ public function test(){echo "B";}}
class Demo{
    use A,B{
        A::test insteadof B;
        B::test as bTest;
    }
}

适用场景与坑点

✅ 适用场景:多类共用日志、验证码、文件上传等公共逻辑

⚠️ 注意:Trait不能定义静态常量;尽量不要在Trait写大量业务逻辑,只放通用工具方法,避免代码难以维护。

总结

Trait弥补了PHP单继承短板,适合项目中抽取通用能力。合理使用可以减少大量重复代码,但不能滥用,否则会造成代码逻辑分散,增加后期维护成本。


emer 发布于  2026-10-18 07:09 

JavaScript this指向详解常见问题汇总

项目赶进度的时候,this指向详解这类基础问题最容易浪费调试时间。提前掌握本文的内容,可以少走很多弯路。


emer 发布于  2026-10-14 07:10 

JavaScript 全屏API使用最佳实践(附代码示例)

JavaScript的生态非常丰富,但全屏API使用依然是最常用的功能点之一。本文整理了最实用的几种实现方式。


emer 发布于  2026-10-14 07:10 

Java 面向对象三大特性入门教程(附代码示例)

做Java开发这几年,面向对象三大特性是被身边同事问得最多的问题之一。今天把答案整理出来,供大家参考。


emer 发布于  2026-10-14 07:10 

Git alias别名设置常见问题汇总(完整版)

如果你正在学习Git,那么alias别名设置几乎是绕不开的一个环节。本文从原理到实践,带你快速上手。


emer 发布于  2026-10-14 07:10 

Git reflog恢复误操作案例讲解(新手必看)

如果你正在学习Git,那么reflog恢复误操作几乎是绕不开的一个环节。本文从原理到实践,带你快速上手。


emer 发布于  2026-10-14 07:10 

PHP 批量导入CSV数据完整指南(完整版)

最近在项目里又遇到了批量导入CSV数据的典型问题,索性把解决方法整理成这篇文章,希望能帮到遇到同样问题的同学。


emer 发布于  2026-10-14 07:09 

Python 爬虫获取网页标题进阶技巧分享(完整版)

很多初学者在学习Python时,都会遇到爬虫获取网页标题相关的问题。网上的资料零散且质量参差不齐,本文尝试用一篇文章把爬虫获取网页标题讲清楚。


emer 发布于  2026-10-14 07:09 

PHP 字符串反转入门教程(新手必看)

很多初学者在学习PHP时,都会遇到字符串反转相关的问题。网上的资料零散且质量参差不齐,本文尝试用一篇文章把字符串反转讲清楚。


emer 发布于  2026-10-14 07:09 

Java Lambda表达式入门实战详解(新手必看)

熟练掌握Lambda表达式入门,是写好Java代码的基本功。本文循序渐进,从概念到示例一次讲透。


emer 发布于  2026-10-14 07:09 

PHP 批量导入CSV数据最佳实践(2026最新整理)

PHP的生态非常丰富,但批量导入CSV数据依然是最常用的功能点之一。本文整理了最实用的几种实现方式。


emer 发布于  2026-10-14 07:09 

HTML/CSS 响应式布局方案常见问题汇总(完整版)

本文面向HTML/CSS初学者,用通俗的语言讲解响应式布局方案,读完即可动手实践。


emer 发布于  2026-10-14 07:09 

Java 工厂模式入门核心用法解析(附代码示例)

很多初学者在学习Java时,都会遇到工厂模式入门相关的问题。网上的资料零散且质量参差不齐,本文尝试用一篇文章把工厂模式入门讲清楚。


emer 发布于  2026-10-14 07:09 

Java StringBuilder的使用核心用法解析(建议收藏)

最近在项目里又遇到了StringBuilder的使用的典型问题,索性把解决方法整理成这篇文章,希望能帮到遇到同样问题的同学。


emer 发布于  2026-10-14 07:08 

Git cherry-pick挑选提交核心用法解析(附代码示例)

熟练掌握cherry-pick挑选提交,是写好Git代码的基本功。本文循序渐进,从概念到示例一次讲透。


emer 发布于  2026-10-14 07:08 

JavaScript 判断元素进入可视区避坑指南

面试中经常被问到的判断元素进入可视区,你真的掌握了吗?本文结合实例,讲解JavaScript中判断元素进入可视区的正确用法。


emer 发布于  2026-10-14 07:08 

Python 数据写入数据库进阶技巧分享(完整版)

熟练掌握数据写入数据库,是写好Python代码的基本功。本文循序渐进,从概念到示例一次讲透。


emer 发布于  2026-10-14 07:08 

JavaScript 定时器的注意事项案例讲解

很多初学者在学习JavaScript时,都会遇到定时器的注意事项相关的问题。网上的资料零散且质量参差不齐,本文尝试用一篇文章把定时器的注意事项讲清楚。


emer 发布于  2026-10-14 07:08 
'); })();