联系方式

咨询热线:400-998-6158

点击此处免费预约试听课程»

常见问题
学习资讯
常见问题

合肥PHP开发工程师培训班哪里有

合肥PHP开发工程师培训班哪里有

学习内容:
一、网页基础
HTML基础知识,CSS样式表,DIV布局,Dreamweaver操作使用等二次开发

二、JS
JS基本语法,JS基于对象,DOM对象模型,JQuery类库,Ajax等火烧云信息

三、PHP初级
环境架构,PHP基本语法,函数、数组、字符串、日期时间、文件、COOKIE、SESSION、图像、数据库等火烧云B/s系统开发

四、PHP*

Smarty模板、Ajax、Eclipse PHP、面向对象、PDO、ADODB、XML、加解密、sokect、Email、SVN、ThinkPHP框架等

我们的品*特质
“以客户为中心”我们坚持以客户为先,深刻理解客户需求并积极匹配客户战略,主动承担责任,不断提升客户体验和满意度,成就客户,实现与客户的长期合作与共赢。
奋斗进取
我们积极进取、集体奋斗、gao效执行,以批判思维持续改进和完善,富于激情地实践对客户的承诺,全力以赴致力于客户的成功。
创新
我们洞察和把握行业趋势,围绕客户需求持续创新,构筑起强大的技术实力,以持平的产品和服务为客户持续创造价值。
开放合作
我们用心聆听内外部建议,主动分享知识和观点,通过广泛合作,构建和谐的产业环境,与整个产业和利益相关人共同创造和分享价值。



Twitter 的 snowflake 在分布式生成 UUID 应用还是蛮广泛的,基于 snowflake 的一些变种的算法网上也有不少。使用 snowflake 生成 UUID 很多都是在分布式场景下使用,我看了下网上有其中有几篇 PHP 实现的都没有考虑到线程安全。现在 PHP 有了 Swoole 的锁和协程的加持,对于我们开发线程安全和高并发模拟还是很方便的,这里用 PHP 结合 Swoole 来学习下实现较简单的 snowflake。

先来看以下 snowflake 的结构:

生成的数值是 64 位,分成 4 个部分:

  • *一个 bit 为符号位,较高位为 0 表示正数
  • 第二部分 41 个 bit 用于记录生成 ID 时候的时间戳,单位为毫秒,所以该部分表示的数值范围为 2^41 - 1(69 年),它是相对于某一时间的偏移量
  • 第三部分的 10 个 bit 表示工作节点的 ID,表示数值范围为 2^10 - 1,相当于支持 1024 个节点
  • 第四部分 12 个 bit 表示每个工作节点没毫秒生成的循环自增 id,较多可以生成 2^12 -1 个 id,超出归零等待下一毫秒重新自增。
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
<?php
 
classSnowflake
{
  constEPOCH = 1543223810238; // 起始时间戳,毫秒
 
  constSEQUENCE_BITS = 12; //序号部分12位
  constSEQUENCE_MAX = -1 ^ (-1 << self::SEQUENCE_BITS);// 序号较大值
 
  constWORKER_BITS = 10;// 节点部分10位
  constWORKER_MAX = -1 ^ (-1 << self::WORKER_BITS);// 节点较大数值
 
  constTIME_SHIFT = self::WORKER_BITS + self::SEQUENCE_BITS;// 时间戳部分左偏移量
  constWORKER_SHIFT = self::SEQUENCE_BITS; // 节点部分左偏移量
 
  protected$timestamp; // 上次ID生成时间戳
  protected$workerId; // 节点ID
  protected$sequence; // 序号
  protected$lock;   // Swoole 互斥锁
 
  publicfunction__construct($workerId)
  {
    if($workerId< 0 ||$workerId> self::WORKER_MAX) {
      trigger_error("Worker ID 超出范围");
      exit(0);
    }
 
    $this->timestamp = 0;
    $this->workerId =$workerId;
    $this->sequence = 0;
    $this->lock =newswoole_lock(SWOOLE_MUTEX);
  }
 
  /**
   * 生成ID
   * @return int
   */
  publicfunctiongetId()
  {
    $this->lock->lock(); // 这里一定要记得加锁
    $now=$this->now();
    if($this->timestamp ==$now) {
      $this->sequence++;
 
      if($this->sequence > self::SEQUENCE_MAX) {
        // 当前毫秒内生成的序号已经超出较大范围,等待下一毫秒重新生成
        while($now<=$this->timestamp) {
          $now=$this->now();
        }
      }
    }else{
      $this->sequence = 0;
    }
 
    $this->timestamp =$now; // 更新ID生时间戳
 
    $id= (($now- self::EPOCH) << self::TIME_SHIFT) | ($this->workerId << self::WORKER_SHIFT) |$this->sequence;
    $this->lock->unlock();//解锁
 
    return$id;
  }
 
  /**
   * 获取当前毫秒
   * @return string
   */
  publicfunctionnow()
  {
    returnsprintf("%.0f", microtime(true) * 1000);
  }
 
}

其实逻辑并不复杂,解释一下代码中的位运算:

1
2
3
-1 ^ (-1 << self::SEQUENCE_BITS)
就是-1的二进制表示为1的补码,其实等同于 :
2**self::SEQUENCE_BITS - 1

较后部分左移后或运算:

1
(($now- self::EPOCH) << self::TIME_SHIFT) | ($this->workerId << self::WORKER_SHIFT) |$this->sequence;

学校联系方式

更多培训课程,学习资讯,课程优惠等学校信息,请进入 合肥IT培训合肥瑶海区php培训合肥庐阳区java培训 网站详细了解,免费咨询电话:400-998-6158

相关课程