Swoft

MYSQL慢查询和日志

我是研究僧i 提交于 2020-08-09 05:21:50
一、简介 开启慢查询日志,可以让MySQL记录下查询超过指定时间的语句,通过定位分析性能的瓶颈,才能更好的优化数据库系统的性能。 二、参数说明 slow_query_log 慢查询开启状态 slow_query_log_file 慢查询日志存放的位置(这个目录需要MySQL的运行帐号的可写权限,一般设置为MySQL的数据存放目录) long_query_time 查询超过多少秒才记录 三、设置步骤 1.查看慢查询相关参数 mysql> show variables like 'slow_query%'; +---------------------------+----------------------------------+ | Variable_name | Value | +---------------------------+----------------------------------+ | slow_query_log | OFF | | slow_query_log_file | /mysql/data/localhost-slow.log | +---------------------------+----------------------------------+ mysql> show variables like 'long_query

Redis实现分布式锁与任务队列的思路

落花浮王杯 提交于 2020-08-06 09:22:43
一、正文 大家都知道在天猫、京东、苏宁等等电商网站上有很多秒杀活动,例如在某一个时刻抢购一个原价1999现在秒杀价只要999的手机时,会迎来一个用户请求的高峰期,会有几十万几百万的并发量,来抢这个手机,在高并发的情形下会对数据库服务器或者是文件服务器应用服务器造成巨大的压力,严重时说不定就宕机了。 另一个问题是,秒杀的东西都是有量的,例如一款手机只有10台的量秒杀,那么,在高并发的情况下,成千上万条数据更新数据库(例如10台的量被人抢一台就会在数据集某些记录下 减1),那次这个时候的先后顺序是很乱的,很容易出现10台的量,抢到的人就不止10个这种严重的问题。那么,以后所说的问题我们该如何去解决呢? 接下来我所分享的技术就可以拿来处理以上的问题: 分布式锁 和 任务队列。 二、实现思路 1.Redis实现分布式锁思路 思路很简单,主要用到的redis函数是setnx(),这个应该是实现分布式锁最主要的函数。首先是将某一任务标识名(这里用Lock:order作为标识名的例子)作为键存到redis里,并为其设个过期时间,如果是还有Lock:order请求过来,先是通过setnx()看看是否能将Lock:order插入到redis里,可以的话就返回true,不可以就返回false。当然,在我的代码里会比这个思路复杂一些,我会在分析代码时进一步说明。 2.Redis实现任务队列

php+redis消息队列实现抢购功能

三世轮回 提交于 2020-08-05 16:45:07
实现功能: 1. 基于redis队列,防止高并发的超卖 2. 基于mysql的事务加排它锁,防止高并发的超卖 基于redis队列工作流程: 1. 管理员根据goods表中的库存,创建redis商品库存队列 2. 客户端访问秒杀API 3. web服务器先从redis的商品库存队列中查询剩余库存重点内容 4. redis队列中有剩余,则在mysql中创建订单,去库存,抢购成功 5. redis队列中没有剩余,则提示库存不足,抢购失败重点内容 基于mysql事务和排它锁工作流程: 1. 开启事务 2. 查询库存,并显示的设置写锁(排他锁):SELECT * FROM goods WHERE id = 1 FOR UPDATE 3. 生成订单 4. 去库存,隐示的设置写锁(排他锁):UPDATE goods SET counts = counts – 1 WHERE id = 1 5. commit,释放锁 注意:第二步步可以设置共享锁,不然有可能会造成死锁。 代码: <?php /********************************************** * 抢购模块 * * @author liubin * @date 2018-02-10 * * ab -n 1000 -c 100 http://192.168.16.73/Seckill/buy.php * */

Laravel模型事件的实现原理详解

旧巷老猫 提交于 2020-07-28 03:59:16
模型事件在 Laravel 的世界中,你对 Eloquent 大多数操作都会或多或少的触发一些模型事件,下面这篇文章主要给大家介绍了关于Laravel模型事件的实现原理,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴。 前言 Laravel的ORM模型在一些特定的情况下,会触发一系列的事件,目前支持的事件有这些:creating, created, updating, updated, saving, saved, deleting, deleted, restoring, restored,那么在底层是如何实现这个功能的呢? 下面话不多说了,来一起看看详细的介绍吧。 一.如何使用模型事件 先来看看如何使用模型事件,文档里面写了两种方法,实际上总共有三种方式可以定义一个模型事件,这里以saved事件来做例子,其他事件都一样。 1.events属性 直接上代码: class User extends Authenticatable { use Notifiable; protected $events = [ 'saved' => UserSaved::class, ]; } 这个比较难以理解,而且文档并没有详细说明,刚开始以为saved被触发后会调用UserSaved里面的handle方法,实际上并不是。这个数组只是对事件做的一个映射

mysql 悲观锁与乐观锁的详解

空扰寡人 提交于 2020-07-27 15:02:01
悲观锁与乐观锁是人们定义出来的概念,你可以理解为一种思想,是处理并发资源的常用手段。 不要把他们与mysql中提供的锁机制(表锁,行锁,排他锁,共享锁)混为一谈。 一、悲观锁 顾名思义,就是对于数据的处理持悲观态度,总认为会发生并发冲突,获取和修改数据时,别人会修改数据。所以在整个数据处理过程中,需要将数据锁定。 悲观锁的实现,通常依靠数据库提供的锁机制实现,比如mysql的排他锁,select .... for update来实现悲观锁。 例子:商品秒杀过程中,库存数量的减少,避免出现超卖的情况。 CREATE TABLE `tb_goods_stock` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID', `goods_id` bigint(20) unsigned DEFAULT '0' COMMENT '商品ID', `nums` int(11) unsigned DEFAULT '0' COMMENT '商品库存数量', `create_time` datetime DEFAULT NULL COMMENT '创建时间', `modify_time` datetime DEFAULT NULL COMMENT '更新时间', PRIMARY KEY (`id`), UNIQUE KEY

学习swoft的第二天_注解

两盒软妹~` 提交于 2020-07-26 09:13:04
承接上文 第一天的时候,开启ws服务之后 php bin/swoft ws:start 可以通过ip加端口的方式进行访问 这是我们访问到的页面 我们知道要想学习一个新的框架,首先要知道的就是它的路由是怎么写的 文档上说,swoft框架使用的是注解,而不像laravel或者tp那样定义路由 先看一下 我们访问的首页是哪一个控制器中的哪一个方法 这个就是我们访问到的控制器和方法,因为我们是访问的http服务,所以在http服务里面找,根据经验在home控制器中(猜) 我们可以测试一下 然后再请求一次 记得重启服务 这看起来像是一个错误,是说我们应该返回一个http的相应,却返回了一个整型,暂且不管结果,总之,这个方法就是首页访问到的方法 注解 然后我们看一下注解 注解路由应该是Java中最常用到的,对于纯php开发可能了解的不多 文档中说的比较简单 首先就是要引入 use Swoft\Http\Server\Annotation\Mapping\Controller; use Swoft\Http\Server\Annotation\Mapping\RequestMapping; 然后标注控制器 又叫类注解 需要在所有类注释后面    /* * * Class Home * * @Controller(prefix="home") */ 方法注解 位置在方法描述之后 其他注释之前 /*

学习swoft的第二天_注解

99封情书 提交于 2020-07-26 08:43:46
承接上文 第一天的时候,开启ws服务之后 php bin/swoft ws:start 可以通过ip加端口的方式进行访问 这是我们访问到的页面 我们知道要想学习一个新的框架,首先要知道的就是它的路由是怎么写的 文档上说,swoft框架使用的是注解,而不像laravel或者tp那样定义路由 先看一下 我们访问的首页是哪一个控制器中的哪一个方法 这个就是我们访问到的控制器和方法,因为我们是访问的http服务,所以在http服务里面找,根据经验在home控制器中(猜) 我们可以测试一下 然后再请求一次 记得重启服务 这看起来像是一个错误,是说我们应该返回一个http的相应,却返回了一个整型,暂且不管结果,总之,这个方法就是首页访问到的方法 注解 然后我们看一下注解 注解路由应该是Java中最常用到的,对于纯php开发可能了解的不多 文档中说的比较简单 首先就是要引入 use Swoft\Http\Server\Annotation\Mapping\Controller; use Swoft\Http\Server\Annotation\Mapping\RequestMapping; 然后标注控制器 又叫类注解 需要在所有类注释后面    /* * * Class Home * * @Controller(prefix="home") */ 方法注解 位置在方法描述之后 其他注释之前 /*

RabbitMQ 清除全部队列及消息

£可爱£侵袭症+ 提交于 2020-07-25 14:31:52
前言 安装RabbitMQ后可访问:http://{rabbitmq安装IP}:15672使用(默认的是帐号guest,密码guest。此账号只能在安装RabbitMQ的机器上登录,无法远程访问登录。) 远程访问登录,可以使用自己创建的帐号,给与对应的管理员权限即可。 直接在管理页面删除 访问http://{rabbitmq安装IP}:15672,登录。 点击queues,这里可以看到你创建的所有的Queue, 选中某一个Queue,下方有个Delete Queue删除队列/Purge Message清除消息。 但是这样只能一个队列一个队列的删除,如果队列中的消息过多就会特别慢。 命令行批量删除 首先定位到 rabbitMQ 安装目录的sbin 目录下。打开cmd窗口。 关闭应用的命令为: rabbitmqctl stop_app 清除的命令为: rabbitmqctl reset 重新启动命令为: rabbitmqctl start_app ps 查看所有队列命令: rabbitmqctl list_queues 注意 命令行批量删除相当于重置RabbitMQ,请谨慎操作,配置和队列都会被清除。 操作完成,记得添加远程访问账号。 以上内容希望帮助到大家, 很多PHPer在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提升,对此我整理了一些资料

PHP PDO与mysql的连接单例防止超时情况处理

自作多情 提交于 2020-07-25 05:32:41
这个数据库类主要处理了单例模式下创建数据库对象时,如果有两次较长时间的间隔去执行sql操作,再次处理会出现连接失败的问题,利用一个cache数组存放pdo对象与时间戳,把两次执行之间的时间进行了比较,如果间隔超过了10秒就再次new PDO创建连接,没有超过的情况下会继续使用原来的连接,并且因为每次使用后会使连接续期,cache数组里的时间戳也进行了续期. 每次执行操作都会从cache数组中获取下连接,多次执行不超过10秒的情况下,只会有一个连接 代码中实现读写分离,判断sql语句前面6个字符是select的就查询从库,其余操作查询主库.主库和从库就是分别在配置数组中0和1创建不同的PDO对象连接 代码如下: <?php class SinaPdoAdapter{ const MASTER = 0; const SLAVE = 1; const DEFAULT_CACHE_EXPIRETIME = 10; private static $options = array( PDO::ATTR_AUTOCOMMIT => true, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, //PDO::ATTR_PERSISTENT => true, )

依赖注入与哪些事情无关?

我只是一个虾纸丫 提交于 2020-05-08 18:54:57
任何你使用的现代框架,都可能严重依赖于依赖注入。但是你知道依赖注入代表的真正含义吗?或者换一个更好的角度 - 你知道依赖注入不是什么吗? 依赖容器 虽然每个现代框架都附带依赖容器 — 一个用于构建对象的大盒子 — 但这并不能保证你会按照预期的方式使用依赖注入模式。 容器让依赖项更加容易注入到类中,但是它也可能被滥用。 服务定位器模式 一种滥用服务容器的方式是从容器中拉取对象,而不是注入到当前的上下文中。该模式称之为服务定位器模式,它与依赖注入相反。 class MyController { public function indexAction() { $service = app(Service::class); // … } }    服务定位器模式向容器请求特定的对象。这将导致服务从一个难以测试的点拉取,并且,对于外部而言这就像一个黑匣子:除非你查看全部相关代码,否则你将无法了解 MyController 所依赖的外部类型。 一些框架提倡这种用法,因为在项目开始的时候它将变得简单快捷。一旦在容器中注册了成百上千个类,使用服务定位器模式将会导致混乱。而使用依赖注入将解决该问题。 更多信息,可查看我写的这篇博客: 为什么服务定位器模式是反模式. 依赖共享 接下来是一些更积极的方面:以一种更好的方式使用容器。 当依赖注入被正确使用时,外部上下文 (在许多情况下为容器)