背景

为了更好的说明几种算法,我们举个例子,下文就这个例子分别几种算法实现。

  • 如何限制每分钟访问 /api/books 接口不能超过 120 次 ?

我们先定义一个接口:

1
2
3
4
interface RateLimiter
{
public function access();
}

固定时间窗口算法

固定时间窗口算法又叫计数器算法,逻辑就是对固定时间段内的访问次数进行计数,如果计数结果超过次数限制,则拒绝访问。

固定时间窗口算法的劣势就在于其只关心时间段内的总访问次数,而忽略了瞬间集中请求的问题,换而言之,这种统计方法的粒度太粗了,然而我们无法保证请求在时间段内的分布是平均的。

举个例子,如果 A 用户访问接口的时间分布如下:

时间段 访问次数
00:00 ~ 00:30 20
00:30 ~ 01:00 100
01:00 ~ 01:30 100
01:30 ~ 02:00 20

显然在第一分钟,我们有 120 次请求,第二分钟也是 120 次请求,但是 00:30 ~ 01:30 这一分钟时间内,显然是请求书超过 120 次的,所以,这种情况虽然实现了需求,但是很勉强,粒度不够细。

阅读全文 »

简介

在命令行中是没有 redis pipeline 功能的,但 redis 是支持 pipeline 的,而且在各个语言版的 client 中都有相应的实现。

简单概括 redis pipeline 的功能就是将单次请求变为批量请求。

由于网络开销延迟,就算 redis server 端有很强的处理能力,也会由于收到的 client 消息少,而造成吞吐量小。当 client 使用 pipelining 发送命令时,redis server 会将请求放到队列中(使用内存),执行完毕后一次性发送结果。

Pipeline 在某些场景下非常有用,比如有多个 command 需要被“及时的”提交,而且他们对相应结果没有互相依赖,对结果响应也无需立即获得,那么 pipeline 就可以充当这种“批处理”的工具;而且在一定程度上,可以较大的提升性能,性能提升的原因主要是 TCP 连接中减少了“交互往返”的时间。

管道(pipeline)可以一次性发送多条命令并在执行完后一次性将结果返回,pipeline 通过减少客户端与 redis 的通信次数来实现降低往返延时时间,而且 Pipeline 实现的原理是队列,而队列的原理是时先进先出,这样就保证数据的顺序性。 Pipeline 的默认的同步的个数为 53 个,也就是说 arges 中累加到 53 条数据时会把数据提交。

需要注意到是用 pipeline 方式打包命令发送,redis 必须在处理完所有命令前先缓存起所有命令的处理结果。打包的命令越多,缓存消耗内存也越多。所以并不是打包的命令越多越好。具体多少合适需要根据具体情况测试。

适用场景

有些系统可能对可靠性要求很高,每次操作都需要立马知道这次操作是否成功,是否数据已经写进 redis 了,那这种场景就不适合。

还有的系统,可能是批量的将数据写入 redis,允许一定比例的写入失败,那么这种场景就可以使用了,比如 10000 条一下进入 redis,可能失败了 2 条无所谓,后期有补偿机制就行了,比如短信群发这种场景,如果一下群发 10000 条,按照第一种模式去实现,那这个请求过来,要很久才能给客户端响应,这个延迟就太长了,如果客户端请求设置了超时时间 5 秒,那肯定就抛出异常了,而且本身群发短信要求实时性也没那么高,这时候用 pipeline 最好了。

概述

概念: 可以一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其它命令插入,不许加塞。

Redis 部分支持事务,不支持的是:强一致性

能干嘛: 一个队列中,一次性、顺序性、排他性的执行一系列命令

常用命令:

  • MULTI:开启一个事务,MULTI 执行之后,客户端可以继续向服务器发送任意多条命令,这些命令不会立即被执行,而是被放到一个队列中。
  • EXEC:执行队列中所有的命令
  • DISCARD:清空事务队列,并放弃执行事务
  • UNWATCH:取消 WATCH 命令对所有 key 的监视
  • WATCH key1 key2 ... :监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。

使用

正常执行:

阅读全文 »

Version

Hexo 5.2.0
NexT 8.0.1

这几天将博客主题从 NexT-7.7.0 升级到了 8.0.1,在重新安装插件的时候顺便记录了本博客当前使用的插件

鼠标点击特效

下面是四个比较常用的鼠标点击特效脚本,我们可以把它们放置在 source/js/cursor/ 目录下:

  • 礼花特效代码:
阅读全文 »

Hexo 升级比较简单,老方法 npm-checknpm-upgradenpm-update 一键三连。按以下顺序逐步执行完成后,Hexo 版本及系统插件均会升级到最新。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//以下指令均在Hexo目录下操作,先定位到Hexo目录
//查看当前版本,判断是否需要升级
> hexo version

//全局升级hexo-cli
> npm i hexo-cli -g

//再次查看版本,看hexo-cli是否升级成功
> hexo version

//安装npm-check,若已安装可以跳过
> npm install -g npm-check

//检查系统插件是否需要升级
> npm-check

//安装npm-upgrade,若已安装可以跳过
> npm install -g npm-upgrade

//更新package.json
> npm-upgrade

//更新全局插件
> npm update -g

//更新系统插件
> npm update --save

//再次查看版本,判断是否升级成功
> hexo version

如果 1G 内存要装 MySQL 5.7,这篇文章也是适用的。

宝塔 6.9.8

宝塔面板在编译安装 MySQL 8.0 时,要求 4个核心的 CPU,8G 内存,实在是太高了,小站长的服务器一般都不会有如此高的配置。这时候,我们要使用 MySQL 8.0,可以选择极速安装,或者,如果一定要自己编译的话,可以使用命令行来跳过配置检测。不过,MySQL 编译过程中,需要 5G 以上的内存,以及 9G 以上的数据盘空间。如果我们的内存实在不够,可以创建 swap 虚拟内存。

在宝塔面板里的 Linux 工具箱(如果没有可以去软件商店里面安装) 修改 Swap/虚拟内存,输入 0,然后手动设置 swap 到系统盘:

1
2
3
4
5
6
fallocate -l 4G /swap
chown root:root /swap
chmod 0600 /swap
mkswap /swap
swapon /swap
echo '/swap swap swap defaults 0 0' >> /etc/fstab

查看一下 swap 是否开启成功:

1
2
3
4
swapon -s

Filename Type Size Used Priority
/swap file 4194300 9480 -2

现在内存有 5933M,应该够了,我们还要检查一下,/www 所在的磁盘够不够,建议剩余空间不小于 10G。如果不够,把不需要的文件删一下,或者扩容磁盘,这里不赘述。

阅读全文 »

前置说明

本文以从 https://pkg.phpcomposer.com 镜像切换到 https://packagist.laravel-china.org 为例子来讲解。请自行修改命令行中对应的链接。

问题说明

Composer 在安装时会在 composer.lock 文件中写入扩展包下载地址,如:

一些年代久远的项目中使用了 https://pkg.phpcomposer.com/ 的中文加速镜像,然后最近因为其镜像访问出了故障:

阅读全文 »

composer 配置项

具体的每个配置项细节请参考 Composer 官网

配置列表

ID 配置项 说明
1 name 包的名称,它包括供应商名称和项目名称,使用 / 分隔。
2 description 包描述
3 version 版本
4 type 安装类型
5 keywords 关键字
6 homepage 项目主页
7 time 版本发布时间
8 license 许可协议
9 authors 作者
10 support 支持,获取项目支持的向相关信息对象。
11 require 自动加载的包
12 require-dev 在DEV下自动加载的包
13 conflict 此列表中的包与当前包的这个版本冲突。它们将不允许同时被安装
14 suggest 建议安装的包,它们增强或能够与当前包良好的工作。这些只是信息,并显示在依赖包安装完成之后,给你的用户一个建议,他们可以添加更多的包。
15 autoload 自动加载,分别有四种加载机制 psr-4 psr-0 classmap file
16 include-path 保留传统,不建议使用
17 target-dir 定义当前包安装的目标文件夹
18 minimum-stability 安装包的时候通过稳定性过滤包的默认行为, dev alpha beta RC stable 可选
19 prefer-stable 安装包的时候优先使用更稳定的包版本, "prefer-stable": true
20 repositories 使用自定义的包资源库。默认情况下 composer 只使用 packagist 作为包的资源库。通过指定资源库,你可以从其他地方获取资源包。
21 config 配置参数,eg:process-timeout vendor-dir
22 scripts Composer 允许你在安装过程中的各个阶段挂接脚本。
23 extra 任意的,供 scripts 使用的额外数据。
24 bin 该属性用于标注一组应被视为二进制脚本的文件,他们会被软链接到(config 对象中的)bin-dir 属性所标注的目录,以供其他依赖包调用。
25 archive 这些选项在创建包存档时使用。
阅读全文 »

Composer 是 PHP 的一个依赖管理工具。 如果你是一名 PHP 开发人员,那么你很可能每天都在使用它并且频繁的运行命令 require, install 和 update。也许你并没有意识到, 我们可以使用一些其他的 Composer 命令,来更加轻松的使用它。

它有许多的命令可以使用,但今天我将分享我使用的并且每天都有帮助的 6 个命令。

show

先说下 show 命令。它允许您查看项目的所有已安装包(包括依赖项),以及查看相关包的说明。所有这些信息都可以在Composer锁文件(composer.lock)中找到, 但是使用 show 命令相对来说是一种更简单、更方便的一种查看包信息的方法。

要列出所有已安装的包及其版本号和说明,只需使用 show:

1
composer show

有时候把这些信息用依赖关系树的形式查看会更容易理解, 可以通过 --tree or -t 参数:

1
composer show -t
阅读全文 »

Version

git version 2.21.0

新增 submodule

1
2
# git submodule add https://github.com/theme-next/hexo-theme-next.git themes/next/
git submodule add <url> <folder>

如果出现 xxx already exists in the index 的提示,则给根据Issue with adding common code as git submodule: “already exists in the index” 里面的回答,执行 git rm -f --cached <folder> 后,在执行 git submodule add

如果这个仓库先前没有用过 submodule,那么 Git 会在目录下建立一个叫做 .gitmodules 的文件,这里记录了 remote repo 的 URL 和这个 submodule 在此目录的路径。执行此命令后 submodule 和 .gitmodules 会自动 staged,这个时候可以 commit 和 push。

更新 submodule

必须到个人的目录底下执行 git pull 去拉取 upstream 的代码,可是这样会比较安全;若要一次全部更新所有的 submodule,可以用 foreach 命令:

1
git submodule foreach --recursive git pull origin master

删除 submodule

本以为会有像是 git submodule rm 这样的命令,结果竟然没有,必须辛苦的一个一个手动移除,不知道不实现这个命令的考量是什么,希望未来的版本能把它加上去。

阅读全文 »
0%