Class ‘GuzzleHttp\Psr7\Utils’ not found

composer require guzzlehttp/psr7:^1.6.1 guzzlehttp/promises:^1.3.1

发表在 php, 框架 | 留下评论

go fmt.Printf 格式化占位符详解

%v 输出结构体 {10 30}

%+v 输出结构体显示字段名 {one:10 tow:30}

%#v 输出结构体源代码片段 main.Point{one:10, tow:30}

%T 输出值的类型 main.Point

%t 输出格式化布尔值 true

%d`输出标准的十进制格式化 100

%b`输出标准的二进制格式化 99 对应 1100011

%c`输出定整数的对应字符 99 对应 c

%x`输出十六进制编码 99 对应 63

%f`输出十进制格式化 99 对应 63

%e`输出科学技科学记数法表示形式 123400000.0 对应 1.234000e+08

%E`输出科学技科学记数法表示形式 123400000.0 对应 1.234000e+08

%s 进行基本的字符串输出 “\”string\”” 对应 “string”

%q 源代码中那样带有双引号的输出 “\”string\”” 对应 “\”string\””

%p 输出一个指针的值 &jgt 对应 0xc00004a090

% 后面使用数字来控制输出宽度 默认结果使用右对齐并且通过空格来填充空白部分

%2.2f 指定浮点型的输出宽度 1.2 对应 1.20

%*2.2f 指定浮点型的输出宽度对齐,使用 `-` 标志 1.2 对应 *1.20

发表在 go | 留下评论

抽奖算法之1

抽奖逻辑:有10个奖品,每个奖品的概率不一样,设计一种算法至少抽中其中的一个
算法讲解:10个奖品,每个奖品的概率是一个范围,把所有的范围都加到一起作为整体x,然后随机1 ~ x数字n,n落到哪个区间内,就中了哪个奖品

$奖品概率 = [10,35,50,....];
$x = array_sum($奖品概率);
$n = mt_rand();
foreach($奖品概率  as $k => $item){
   if($n < $item){
      return $k;
   }

   $n -= $item;
}
发表在 php, php函数集, php小程序 | 留下评论

yii2 db buildQuery 时 禁止转译 字符串

https://www.yiichina.com/doc/api/2.0/yii-db-expression

$expression = new Expression('NOW()');
$now = (new \yii\db\Query)->select($expression)->scalar();  // SELECT NOW();
echo $now;
发表在 php, yii2, 框架 | 留下评论

Redis 变慢解决常用办法

1. 获取 Redis 实例在当前环境下的基线性能。
./redis-cli –intrinsic-latency 120 该命令会打印 120 秒内监测到的最大延迟

2. 是否用了慢查询命令?如果是的话,就使用其他命令替代慢查询命令,或者把聚合计算命令放在客户端做。
a. 用其他高效命令代替。比如说,如果你需要返回一个 SET 中的所有成员时,不要使用 SMEMBERS 命令,而是要使用 SSCAN 多次迭代返回,避免一次返回大量数据,造成线程阻塞
b. 当你需要执行排序、交集、并集操作时,可以在客户端完成,而不要用 SORT、SUNION、SINTER 这些命令,以免拖慢 Redis 实例。

3. 是否对过期 key 设置了相同的过期时间?对于批量删除的 key,可以在每个 key 的过期时间上加一个随机数,避免同时删除。

4. 是否存在 bigkey? 对于 bigkey 的删除操作,如果你的 Redis 是 4.0 及以上的版本,可以直接利用异步线程机制减少主线程阻塞;如果是 Redis 4.0 以前的版本,可以使用 SCAN 命令迭代删除;对于 bigkey 的集合查询和聚合操作,可以使用 SCAN 命令在客户端完成。

5. Redis AOF 配置级别是什么?业务层面是否的确需要这一可靠性级别?如果我们需要高性能,同时也允许数据丢失,可以将配置项 no-appendfsync-on-rewrite 设置为 yes,避免 AOF 重写和 fsync 竞争磁盘 IO 资源,导致 Redis 延迟增加。当然, 如果既需要高性能又需要高可靠性,最好使用高速固态盘作为 AOF 日志的写入盘。

6. Redis 实例的内存使用是否过大?发生 swap 了吗?如果是的话,就增加机器内存,或者是使用 Redis 集群,分摊单机 Redis 的键值对数量和内存压力。同时,要避免出现 Redis 和其他内存需求大的应用共享机器的情况。

7. 在 Redis 实例的运行环境中,是否启用了透明大页机制?如果是的话,直接关闭内存大页机制就行了。

8. 是否运行了 Redis 主从集群?如果是的话,把主库实例的数据量大小控制在 2~4GB,以免主从复制时,从库因加载大的 RDB 文件而阻塞。

9. 是否使用了多核 CPU 或 NUMA 架构的机器运行 Redis 实例?使用多核 CPU 时,可以给 Redis 实例绑定物理核;使用 NUMA 架构时,注意把 Redis 实例和网络中断处理程序运行在同一个 CPU Socket 上。

10. 仔细检查下有没有恼人的“邻居”,具体点说,就是 Redis 所在的机器上有没有一些其他占内存、磁盘 IO 和网络 IO 的程序,比如说数据库程序或者数据采集程序。如果有的话,我建议你将这些程序迁移到其他机器上运行。

另外参考

发表在 redis | 留下评论

php 数组实现简单队列

<?php
class Que {
  //队列最大值
  protected $m = 10;
  //头指针
  protected $h = 0;
  //尾脂针
  protected $t = 0;
  //是否安全
  protected $isSave = false;

  function __construct($isSave = false)
  {
      $this->isSave = $isSave;
      $this->arr = array_fill(0, $this->m, null);
  }

  /**
   * $n >= -100
   * 满返回-999
   * 不满返回入队列后队列元素的数目
   * 
   */

  function in($n){
      if($this->isSave){
        static::lock('in');
      }

      if($n < -100){
        throw new \Exception("数据异常", 1);
      }
      
      if( !$this->canIn() ){
        return -999;
      }


      $this->t = $this->newInOffset();
      $this->arr[$this->t] = $n;

      return $this->getLength();
  }

  /**
   * 空返回-999
   * 非空返回出队列的值
   */
  function out(){
    if($this->isSave){
      static::lock('out');
    }

    if(!$this->canOut()){
        return -999;
    }
    
    $n = $this->arr[$this->h];
    unset($this->arr[$this->h]);
    $this->arr[$this->h] = null;
    $this->h = $this->newOutOffest();
    return $n;
  }

  /**
   *获取数组长度
   */
  function getLength(){
    if($this->isEmpty()) return 0;
    if($this->t < $this->h){
      $l = $this->m - $this->h + $this->t;
    }else{
      $l = $this->t - $this->h;
    }
    return $l + 1;
  }

  /**
   * 判断数组是否为空数组
   */
  function isEmpty(){
    return $this->h == $this->t && is_null($this->arr[$this->h]);
  }

  /**
   *获取入队后的尾指诊偏移量
   */
  function newInOffset(){
      if( $this->isEmpty() ){//是否是空队列
          return $this->t;
      }

      return ($this->t + 1) % $this->m;
  }

  /**
   *判断出队后头指诊的偏移量
   */
  function newOutOffest(){
    if(!$this->isEmpty() && $this->h == $this->t){
        return $this->h;
    }

    return ($this->h + 1) % $this->m;
  }

  /**
   *能否入队
   */
  function canIn(){
    return is_null($this->arr[$this->newInOffset()]);
  }

  /**
   *能否出队
   */
  function canOut(){
    return !is_null($this->arr[$this->h]);
  }

  /**
   *获取队列内容
   */
  function getQueList(){
    return $this->arr;
  }

  /**
   *加锁
   */
  public static function lock($name, $ex = 60)
  {
      if ($res = Redis::setnx($name, '1', 'NX')) {
          Redis::expire($name, $ex);

          register_shutdown_function(function () use ($name) {
              Que::unlock($name);
          });
      } else {
          throw new \Exception('执行中,请稍等');
      }
  }

  /**
   * 解锁
   */
  public static function unlock($name)
  {
      Redis::del($name);
  }
}

/**
$q = new Que;
for($i = 0; $i < 20; $i++){
    $r = $q->in($i);
    var_dump($r);
    if($i % 3 == 0){
      var_dump("out : ".$q->out());
    }
}

for($i = 0; $i < 20; $i++){
  var_dump("out : ".$q->out());
}
**/


发表在 php, php函数集, php小程序, 基础 | 留下评论

dyld: Library not loaded: /usr/local/opt/readline/lib/libreadline.7.dylib 解决方案

dyld: Library not loaded: /usr/local/opt/readline/lib/libreadline.7.dylib
解决方案

ln -s /usr/local/opt/readline/lib/libreadline.dylib /usr/local/opt/readline/lib/libreadline.7.dylib

发表在 MAC | 留下评论

docker 设置时区

ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

发表在 docker | 留下评论

简单易用分布式锁

class PublicFunc{
    public static function lock($name, $ex = 60)
    {
        $val = uniqid();
        if ($redis->set($name, $val, 'NX', 'EX', $ex)) {
            register_shutdown_function(function () use ($name, $val) {
                PublicFunction::unlock($name, $val);
            });
        } else {
            throw new \Exception('执行中,请稍等');
        }
    }

    public static function unlock($name)
    {//释放锁需要先判断是否是自己持有的锁,如果是则释放,否则不释放,多不操作要求原子操作,所以需要lua脚本
        static $releaseLuaScript = <<<LUA
if redis.call("GET",KEYS[1])==ARGV[1] then
    return redis.call("DEL",KEYS[1])
else
    return 0
end
LUA;
        return $redis->eval($releaseLuaScript, 1, $name, $val);
    }
}
发表在 php, php 优化, php函数集 | 留下评论

nginx 504 Gateway Time-out

方向代理增加超时时间
location ~ /api {
proxy_pass http://127.0.0.1:8081;
proxy_read_timeout 3600;//反向代理读取超时时间,默认60秒
}

发表在 nginx | 留下评论