zonghay

zonghay 查看完整档案

北京编辑哈尔滨工程大学  |  信息安全 编辑TAL  |  研发 编辑填写个人主网站
编辑
_ | |__ _ _ __ _ | '_ \| | | |/ _` | | |_) | |_| | (_| | |_.__/ \__,_|\__, | |___/ 该用户太懒什么也没留下

个人动态

zonghay 收藏了文章 · 11月23日

Swoole 如何使用 Xdebug 进行单步调试

在 PHP-FPM 中使用 Xdebug 的人应该不少,而在 Swoole 中使用 Xdebug 的人还是很少的,原因是 Swoole 扩展明确说明了和 Xdebug 扩展冲突

不过好在我们社区成员给力,提供了一个 Sdebug ,在此我们应该感谢 @mabu233@huanghantao 进行了兼容,让 Xdebug 可用于 Swoole 环境进行断点、调试

之前在 Swoole 文档中补充了 Sdebug 的安装,同样的 Sdebug 的 README 也进行了修改介绍如何安装,不过都是简单说明如何成功加载扩展,没有详细说明配置

先说一下如何安装 Sdebug

为了避免 Swoole 的检测 Xdebug 警告,所以扩展注册的名称是 Sdebug
git clone git@github.com:swoole/sdebug.git -b sdebug_2_9 --depth=1
cd sdebug
phpize
./configure
make clean
make
make install

步骤很简单,就是 clone 源码,进入目录然后编译

如果你的 PHP 是通用安装,没有修改默认位置等等,也可以直接运行目录下的脚本:

./rebuild.sh

如果你的 phpize 不是默认路径的话,请使用绝对路径;同样的 php-config 需要使用--with-php-config=加上你的绝对路径
编译成功后需要在 php.ini 加载扩展

zend_extension=xdebug.so
编译完成后生成的 so 文件名还是 xdebug

查看是否加载成功

php --ri sdebug

别走,还没完,还需要一些其他的配置,不然你去断点会发现不起作用
我们还需要在 php.ini 中加入这几个配置项

xdebug.remote_enable=1
xdebug.remote_autostart=1
xdebug.remote_host=localhost
xdebug.remote_port=8000
xdebug.idekey="xdebug"

一个配置难倒英雄汉,很多人在使用 Sdebug 的时候就会遇到需要这样问题,不起作用,就吐槽不好用,实际上是你的姿势不对,配置项没加或者加错了

需要配合 PhpStorm 的话,还需要设置一下 PhpStorm 的配置

Preferences | Languages & Frameworks | PHP | Debug

1 是为了我们不加断点的时候,自动给第一行断点

2 是修改配置的remote_port端口

Preferences | Languages & Frameworks | PHP | Servers
添加一个服务

紧接着在右上角这里添加一个调试,选择 PHP Remote Debug

server 选择我们刚才创建的 server,IDE key 就填我们 php.ini 中配置的xdebug

然后我们来试验一波,看看好不好使

先来一个简单的 TCP Server

//创建Server对象,监听 127.0.0.1:9501 端口
$server = new SwooleServer('127.0.0.1', 9501);
//监听连接进入事件
$server->on('Connect', function ($server, $fd) {
 echo "Client: Connect.n";});
//监听数据接收事件
$server->on('Receive', function ($server, $fd, $from_id, $data) {
 var_dump($data);
 $server->send($fd, "Server: " . $data);
});
//监听连接关闭事件
$server->on('Close', function ($server, $fd) {
 echo "Client: Close.n";});
//启动服务器
$server->start();

点击右上角的绿色虫子进入 Debug 状态,启动我们的服务,会发现自动断在了第 4 行创建 Server 对象的地方

然后下一步下一步...

start 之后我们使用 telnet 进行连接,发送一个消息,断点就进入到 Connect 这里,然后我们再下一步,终端才会输出Connect

紧接着我们会到 var_dump 的地方,就可以看到 $data 的值是11111rn

然后来一个 HTTP Server

$http = new SwooleHttpServer('0.0.0.0', 9501);
$http->on('request', function ($request, $response) {
 var_dump($request->server);
 $response->header("Content-Type", "text/html; charset=utf-8");
 $response->end("<h1>Hello Swoole. #".rand(1000, 9999)."</h1>");
});
$http->start();

这里需要在访问时加上一个XDEBUG_SESSION_START参数或者在 Cookie 中添加也可以

浏览器访问http://127.0.0.1:9501/?XDEBUG_SESSION_START=xdebug

也是可以断点调试的

框架的使用也是同理的,至于其他的什么和 docker 一起使用等等自己研究吧...

这里放一张调试 Hyperf 的截图

还有一个 Tips,把右上角的电话图标选择为上图那样,会在命令行启动服务时自动调起 Debug 服务

原文发布于Swoole问答,转载请注明出处。

Swoole官方公众号

查看原文

zonghay 发布了文章 · 11月18日

[北京] 学而思网校招聘PHP实习生

好未来集团学而思网校招聘PHP实习生。简历发送至 zhangyong1@tal.com

岗位要求:
1.本科以上学历,计算机专业优先;
2.掌握PHP语言
3.掌握Mysql,Ngnix、Linux使用
4.了解如何使用git管理代码
5.了解Swoole、Hyperf优先

岗位职责:
参与部门核心平台研发

工作地点:北京昌平区回龙观东大街

联系方式:
发送简历至邮箱 zhangyong1@tal.com
标题格式 姓名-学校

查看原文

赞 0 收藏 0 评论 0

zonghay 赞了文章 · 8月11日

Swoole 协程屏障(CoroutineBarrier)的使用

在最新版本的 Swoole Library 中底层提供了一个更便捷的协程并发管理工具:Coroutine\Barrier 协程屏障,或者叫协程栅栏。基于 PHP 引用计数和 Coroutine API 实现。相比于Coroutine\WaitGroupCoroutine\Barrier使用更简单一些,只需通过参数传递或者闭包的use语法,引入子协程函数上即可。

使用实例

use Swoole\Coroutine\Barrier;
use Swoole\Coroutine\System;
use function Swoole\Coroutine\run;
use Swoole\Coroutine;

run(function () {
    $barrier = Barrier::make();

    $count = 0;
    $N = 4;

    foreach (range(1, $N) as $i) {
        Coroutine::create(function () use ($barrier, &$count) {
            System::sleep(0.5);
            $count++;
        });
    }

    Barrier::wait($barrier);
    
    assert($count == $N);
});

执行流程

  • 先使用Barrier::make()创建了一个新的协程屏障
  • 在子协程用使用use语法传递屏障,增加引用计数
  • 在需要等待的位置加入Barrier::wait($barrier),这时会自动挂起当前协程,等待引用该协程屏障的子协程退出
  • 子协程退出时会减少$barrier对象的引用计数,直到为0
  • 当所有子协程完成了任务处理并退出时,$barrier对象引用计数为0,在$barrier对象析构函数中底层会自动恢复挂起的协程,从Barrier::wait($barrier)函数中返回

Coroutine\Barrier 是一个比 WaitGroupChannel 更易用的并发控制器,大幅提升了 PHP 并发编程的用户体验。

查看原文

赞 28 收藏 3 评论 6

zonghay 赞了文章 · 7月1日

PHP 完全面向对象风格的 Array 和 String 编程

PHP 语言中操作字符串和数组一般使用 str_*array_* 的系列函数,这些函数由于历史原因,命名和参数顺序风格不统一,广为开发者诟病,PHP 语言标准库中暂未提供 OO 风格的 ArrayString 类库,开发者使用起来不是很便利,在 Swoole 中我们提供了一 swoole_arrayswoole_string 对字符串和数组操作进行了面向对象封装,可以使用完全面向对象风格进行 ArrayString 编程。

使用方法

  • Swoole 项目:可直接使用
  • Swoole 项目,使用 composer require swoole/library 引入

绝大部分方法提供了链式风格支持,可以一路使用 -> 编写逻辑。底层类库使用了 declare(strict_types=1) 强类型,使用 phpstorm 工具时,可以实现完全自动提示和自动完成。

微信截图_20200621154143.png

创建数组

$array1 = swoole_array(['hello', 'world']);
$array2 = swoole_array(['hello' => 1, 'world' => 2]);
$array3 = swoole_array_list('hello', 'world', 'swoole', 'php');

创建字符串

// Bytes 字符串
$string1 = swoole_string('hello world, php java, swoole');
// 宽字符串
$string2 = swoole_mbstring('我是中国人');
// 返回 5
$string2->length(); 

获取元素

// 获取
$value1 = $array1->get(0);
$value2 = $array2->get('hello');

// 数组的第一个元素
$first = $array->first();
// 数组的最后一个元素
$last = $array->last();

增加/设置

// 设置
$array1->set(0, 'swoole');
$array2->set('world', 9);
// 在末尾追加
$array1->pushBack('java');
// 在头部插入
$array1->pushFront('go');
// 在中间 offset 2 插入
$array1->insert(2, 'rust');

连续追加

$array1->append('rust')->append('c++')->append('swift', 'kotlin');
$array2->set('rust', 99)->set('c++', 88)->set('kotlin', 77);

删除

// 按 key 删除
$array1->delete(0);
$array2->delete('worker');
// 按 value 删除
$array1->remove('hello');

包含

使用contains()方法可以判断数组或字符串中是否包含某个元素。

$array1->contains('java');
$string1->contains('php');

使用startsWith()endsWith()方法判断字符串开头和结尾是否为指定的值。

$str = swoole_string('php and swoole');

$str->startsWith('php'); //true
$str->startsWith('java'); //false
$str->endsWith('swoole'); //true
$str->endsWith('golang'); //false

搜索

// 查找数组中是否有某个值,存在则返回其 key
$key = $array1->search('java');

结合使用

StringArray可以结合使用。

$s = '11, 33, 22, 44,12,32,55,23,19,23';

$data = swoole_string($s)
    ->split(',')
    ->each(fn(&$item) => $item = intval($item))
    /* < 7.4 : function (&$item){ $item = intval($item);} */
    ->sort()
    ->unique()
    ->join('-')
    ->contains('-44-');

var_dump($data);
  • 首先构建了一个字符串对象
  • 使用split按照,分割为数组
  • 遍历并应用$fn函数将元素转换为整数
  • 排序
  • 去重
  • 将数组元素使用-组合成为字符串
  • 判断字符串对象中是否包含-44-

类型推断

swoole_array对象元素操作时,底层会自动判断它的类型,如果为数组或字符串,底层会递归封装。

$array = swoole_array_list(['hello' => 'swoole']);
$array->get(0)->get('hello')->contains('swoole');

性能测试

底层实现其实就是基于str_array_相关函数进行面向对象封装,没有过多性能损耗,仅为一次method调用开销。我们编写了严格的单测覆盖到每个API,保证其可靠性。

性能方面,使用String::contains()执行100万次,与直接运行 php strpos差距不大。

swoole_string: 0.059892892837524s, php_string: 0.033510208129883s

源代码

如果您对此项目感兴趣,可以参与到我们的开发工作中,期待您的 Pull Request

查看原文

赞 31 收藏 6 评论 3

zonghay 发布了文章 · 6月2日

Hyperf/Crontab 组件源码解析

前置阅读:Hyperf/Crontab使用文档
前置阅读:Hyperf/Process自定义进程使用文档
前置阅读:Hyperf事件机制

写在开头

之前做项目用到了Hyperf/Crontab组件来进行秒级的数据清洗,最近又在做定时任务的拆分,于是就打算过一遍组件源码加深理解,顺便构思一下如何在此基础上搭建Hyperf/Crontab的任务调度功能。Crontab本质上是一个随Server启动的自定义进程,所以接下来我们将从启动和执行两个阶段来进行介绍。

定时器的启动

由于Crontab是一个随着Server启动的进程,分析他的生命周期肯定会设计到框架的启动。但本文不是主要介绍Hyperf框架启动源码的,所以我们会简单的过一下涉及到自定义进程启动的框架启动代码。
当我们使用命令 php bin/hyperf.php start 启动hyperf时

$application = $container->get(\Hyperf\Contract\ApplicationInterface::class);

在入口文件 hyperf.php 框架会实例化一个 HyperfFrameworkApplicationFactory 实例,同时会扫描一遍所有带 @Command 注解或者定义了 commands 配置的地方,实例化一个SymfonyComponentConsoleApplication对象 (这是一个Symfony的Consoul命令类用于定义命令触发执行的任务) 。将所有被定义为command的对象类注册到$application对象中,最后在入口文件执行

$application->run();

执行所有的Command命令,其中包括 HyperfServerCommandStartServer 服务Server启动类。在这个类里面定义了如果接收到的命令参数包含 start 那么就会执行他的逻辑,即根据 config/autoload/server.php 的配置实例化HyperfServerServer类,在这个过程中会触发BeforeMainServerStart事件,到这里我们即将进入自定义进程启动的核心阶段。

$serverProcesses = $serverConfig['processes'] ?? [];
        $processes = $this->config->get('processes', []);
        $annotationProcesses = $this->getAnnotationProcesses();
        // Retrieve the processes have been registered.
        $processes = array_merge($serverProcesses, $processes, ProcessManager::all(), array_keys($annotationProcesses));
        foreach ($processes as $process) {
            ...
            if ($instance instanceof ProcessInterface) {
                $instance->isEnable() && $instance->bind($server);
            }
        }

BootProcessListener监听到BeforeMainServerStart事件的触发会拿到所有 @Process 和 定义在processes配置文件的进程类,执行他们的 isEnablebind 方法。

定时器的执行

在上面我们对自定义进程是如何随框架启动的进行了简单的介绍,接下来我们对本文的主角Crontab自定义进程进行解析。
Hyperf文档介绍在使用Crontab之前需要在 config/autoload/processes.php 内注册一下 HyperfCrontabProcessCrontabDispatcherProcess 自定义进程。那么我们就直接来看一下这个process类里面做了什么事情。
如果你对 Hyperf/Process 组件使用熟悉的话会知道,一个process类主要执行的逻辑都在 handle() 方法
内。

public function handle(): void
    {
        $this->event->dispatch(new CrontabDispatcherStarted());
        while (true) {
            $this->sleep();
            $crontabs = $this->scheduler->schedule();
            while (! $crontabs->isEmpty()) {
                $crontab = $crontabs->dequeue();
                $this->strategy->dispatch($crontab);
            }
        }
    }

在handle内首先触发来一个 CrontabDispatcherStarted 事件,目前这个事件无人监听。接下来就是一段时间的协程阻塞,阻塞时间第一次为距离下一次整分钟的秒数,其余的都是60s。关于为什么要使用 SwooleCoroutine::sleep 而不是直接 sleep() ,是因为自定义进程默认是一个协程的Server。
接下来

$crontabs = $this->scheduler->schedule();

返回一个当前这一分钟该执行的SplQueue队列,队列中的是Crontab对象

object(Hyperf\Crontab\Crontab)#46164 (10) {
  ["name":protected]=>
  string(4) "Foo4"
  ["type":protected]=>
  string(8) "callback"
  ["rule":protected]=>
  string(11) "* * * * * *"
  ["singleton":protected]=>
  bool(false)
  ["mutexPool":protected]=>
  string(7) "default"
  ["mutexExpires":protected]=>
  int(3600)
  ["onOneServer":protected]=>
  bool(true)
  ["callback":protected]=>
  array(2) {
[DEBUG] Event Hyperf\Framework\Event\OnPipeMessage handled by Hyperf\Crontab\Listener\OnPipeMessageListener listener.
    [0]=>
    string(16) "App\Task\FooTask"
    [1]=>
    string(7) "execute"
  }
  ["memo":protected]=>
  NULL
  ["executeTime":protected]=>
  object(Carbon\Carbon)#46106 (3) {
    ["date"]=>
    string(26) "2020-06-02 14:15:57.000000"
    ["timezone_type"]=>
    int(3)
    ["timezone"]=>
    string(13) "Asia/Shanghai"
  }
}

这个对象中记录了我们目前比较关注的两个关键信息:

  1. 执行callback
  2. 执行时间

关于这个crontab对象是如何生成的,这个我们在后面会介绍到。
在我们拿到crontab对象后,我们会把对象发送给在 config/autoload/dependencies.php 定义好的 StrategyInterface 的实现类来进行dispatch,默认指定的是Worker 进程执行策略。

$server = $this->serverFactory->getServer()->getServer();
        if ($server instanceof Server && $crontab->getExecuteTime() instanceof Carbon) {
            $workerId = $this->getNextWorkerId($server);
            $server->sendMessage(new PipeMessage(
                'callback',
                [Executor::class, 'execute'],
                $crontab
            ), $workerId);
        }

除Coroutine策略外的dispatch方法是相同的,都是进程间轮训的向WorkID通过 sendMessage 发送 PipeMessage 对象,同时 sendMessage 方法会触发 OnPipeMessage 事件。该事件被 OnPipeMessageListener 监听,会根据 PipeMessage 执行对应的callback函数,即 Executor->execute' 。在该方法中会根据corntab对象的属性定义 SwooleTimer::after ,根据corontab的executeTime属性定义多少秒后执行callback。

$callback && Timer::after($diff > 0 ? $diff * 1000 : 1, $callback);

这样基本就完成了我们一个秒级定时任务的执行。

现在我们回到上面那个关于crontab对象是什么时候生成的问题。我们说过Cornrab本质上就是一个自定义进程,那根据Hyperf/Process的使用说明,所有的自定义进程都继承了 HyperfProcessAbstractProcess ,这个类在启动SwooleProcess时会触发 BeforeProcessHandle 事件,在这个事件中会扫描所有的crontab配置和注解,将这些注解进行解析生成crontab对象,存储在crontabs属性中。

public function register(Crontab $crontab): bool
    {
        if (! $this->isValidCrontab($crontab)) {
            return false;
        }
        $this->crontabs[$crontab->getName()] = $crontab;
        return true;
    }

以上大致就是一个crontab定时任务的执行流程,当然里面还有很多执行细节和Contab个性化的定义参数由于篇幅有限我们还没来得及介绍,感兴趣的同学可以私下进行阅读,下面我也附上来Hyperf/Crontab的整体执行流程类之间的关系图,方便大家对照着阅读源码。

Hyperf_crontab.jpg

写在最后

Hyperf 是基于 Swoole 4.4+ 实现的高性能、高灵活性的 PHP 协程框架,内置协程服务器及大量常用的组件,性能较传统基于 PHP-FPM 的框架有质的提升,提供超高性能的同时,也保持着极其灵活的可扩展性,标准组件均基于 PSR 标准 实现,基于强大的依赖注入设计,保证了绝大部分组件或类都是 可替换可复用 的。

框架组件库除了常见的协程版的 MySQL 客户端、Redis 客户端,还为您准备了协程版的 Eloquent ORM、WebSocket 服务端及客户端、JSON RPC 服务端及客户端、GRPC 服务端及客户端、Zipkin/Jaeger (OpenTracing) 客户端、Guzzle HTTP 客户端、Elasticsearch 客户端、Consul 客户端、ETCD 客户端、AMQP 组件、Apollo 配置中心、阿里云 ACM 应用配置管理、ETCD 配置中心、基于令牌桶算法的限流器、通用连接池、熔断器、Swagger 文档生成、Swoole Tracker、Blade 和 Smarty 视图引擎、Snowflake 全局ID生成器 等组件,省去了自己实现对应协程版本的麻烦。

Hyperf 还提供了 基于 PSR-11 的依赖注入容器、注解、AOP 面向切面编程、基于 PSR-15 的中间件、自定义进程、基于 PSR-14 的事件管理器、Redis/RabbitMQ 消息队列、自动模型缓存、基于 PSR-16 的缓存、Crontab 秒级定时任务、Translation 国际化、Validation 验证器 等非常便捷的功能,满足丰富的技术场景和业务场景,开箱即用。

查看原文

赞 1 收藏 0 评论 0

zonghay 关注了用户 · 5月18日

huangzhhui @huangzhhui

Creator of Hyperf

关注 543

zonghay 关注了标签 · 5月18日

hyperf

Hyperf 官网:https://www.hyperf.io/
项目文档:https://doc.hyperf.io/
项目 Github:https://github.com/hyperf-clo...

介绍

Hyperf 是基于 Swoole 4.3+ 实现的高性能、高灵活性的 PHP 协程框架,内置协程服务器及大量常用的组件,性能较传统基于 PHP-FPM 的框架有质的提升,提供超高性能的同时,也保持着极其灵活的可扩展性,标准组件均均基于 PSR 标准 实现,基于强大的依赖注入设计,保证了绝大部分组件或类都是 可替换可复用 的。

框架组件库除了常见的协程版的 MySQL 客户端Redis 客户端,还为您准备了协程版的 Eloquent ORMJSON RPC 服务的及客户端GRPC 服务端及客户端Zipkin (OpenTracing) 客户端Guzzle HTTP 客户端Elasticsearch 客户端Consul 客户端ETCD 客户端AMQP 组件Apollo 配置中心阿里云 ACM 应用配置管理基于令牌桶算法的限流器通用连接池熔断器Swagger 文档生成 等组件,省去了自己实现对应协程版本的麻烦,Hyperf 还提供了 依赖注入注解AOP 面向切面编程中间件自定义进程事件管理器Redis/RabbitMQ 消息队列自动模型缓存 等非常便捷的功能,满足丰富的技术场景和业务场景,开箱即用。

框架初衷

尽管现在基于 PHP 语言开发的框架处于一个百花争鸣的时代,但仍旧未能看到一个优雅的设计与超高性能的共存的完美框架,亦没有看到一个真正为 PHP 微服务铺路的框架,此为 Hyperf 及其团队成员的初衷,我们将持续投入并为此付出努力,也欢迎你加入我们参与开源建设。

设计理念

Hyperspeed + Flexibility = Hyperf,从名字上我们就将 超高速灵活性 作为 Hyperf 的基因。

  • 对于超高速,我们基于 Swoole 协程并在框架设计上进行大量的优化以确保超高性能的输出。
  • 对于灵活性,我们基于 Hyperf 强大的依赖注入组件,组件均基于 PSR 标准 的契约和由 Hyperf 定义的契约实现,达到框架内的绝大部分的组件或类都是可替换的。

基于以上的特点,Hyperf 将存在丰富的可能性,如实现 Web 服务,网关服务,分布式中间件,微服务架构,游戏服务器,物联网(IOT)等。

关注 64

zonghay 关注了专栏 · 1月9日

Swoole

PHP的协程框架

关注 5880

zonghay 关注了用户 · 2019-12-29

LNMPR源码研究 @php7internal

一群热爱代码的人 研究Nginx PHP Redis Memcache Beanstalk 等源码 以及一群热爱前端的人
希望交流的朋友请加微信 289007301 注明:思否 拉到交流群

《PHP7底层设计与源码分析》勘误https://segmentfault.com/a/11...

《Redis5命令设计与源码分析》https://item.jd.com/12566383....

景罗 陈雷 李乐 黄桃 施洪宝 季伟滨 闫昌 李志 王坤 肖涛 谭淼 张仕华 方波 周生政 熊浩含 张晶晶(女) 李长林 朱栋 张晶晶(男) 陈朝飞 巨振声 杨晓伟 闫小坤 韩鹏 夏达 周睿 李仲伟 张根红 景罗 欧阳 孙伟 李德 twosee

关注 4310

zonghay 收藏了文章 · 2019-12-29

【每日学习记录】使用录像设备记录每天的学习

在这里使用学而思网校的录像设备,记录每天学习的内容

2019-12-29 ~ 2019-12-31

swool 源码-PHP生命周期 by 申振

2019-12-22 ~ 2019-12-26

待补充

2019-12-15 ~ 2019-12-19

12-17

Swoole原理 by 韩天峰

12-15

Swoole原理 by 韩天峰

2019-12-09 ~ 2019-12-13

待补充

2019-12-02 ~ 2019-12-06

12-06

精品课和先锋平台业务分享 by 黄桃 内部资料

12-05

Docker by 潘森

12-04

Fend框架 by 长龙
讲座业务分享 by 志泽 内部资料

12-03

进程 线程 协程 by 李乐

12-02

商城缓存实现 by 俊峰 内部资料

2019-11-25 ~ 2019-11-29

11-29

tw消息处理流程 by 刘志强

11-28

tw消息流转过程- by 张金

11-27

tw消息处理过程

11-25

twemproxy 内存管理机制

2019-11-18 ~ 2019-11-22

11-22

队列结构体TAILQ_QUEUE及发送接收流程解析 - by 景罗

11-20

tw - 施洪宝

11-19

EOF问题和Redis链接 by 潘森

11-18

tw by 田志泽

2019-11-11 ~ 2019-11-15

11-14

tw事件 by 李乐

11-13

tw数据结构mbuf by 赵俊峰

11-12

tw消息发送和接收 by 刘志强

11-11

tw部署和resp协议分析 by 黄桃

2019-11-04 ~ 2019-11-09

11-08

一致性hash by 张金

11-07

twemproxy事件--by 闫昌

11-06

twemproxy(nutcracker)源码 by 景罗

11-05

TwemProxy by 施洪宝

2019-10-28 ~ 2019-11-01

11-01

TwemProxy原理 by 张明&林枝宏
三天内部分享

2019-10-21 ~ 2019-10-25

10-25

Nginx-fpm通信 by 李乐

10-24

Nginx-fastcgi模块 by 李乐

10-22

Nginx串讲 by 李乐

10-21

Nginx数据结构-字符串 by 闫昌

2019-10-14 ~ 2019-10-18

10-17

Nginx HTTP by 李乐

10-15

Nginx进程间通信 by 李乐

10-14

Nginx结构 by 李乐

2019-10-09 ~ 2019-10-12

10-12

listen&server_name by 田志泽

10-11

Nginx配置文件 by 田志泽

10-09

Nginx过滤模块 by 陈雷

2019-09-23 ~ 2019-09-27

09-27

Redis事件模型 by 李乐

09-25

list/pack by 施洪宝

09-24

Redis stream by 施洪宝

09-23

Redis stream by 施洪宝

2019-09-16 ~ 2019-09-20

09-20

请求超过qps的结果及解决方法 by 施洪宝

09-19

mmap by 张怡

09-18

stl 容器 by 施洪宝

09-17

stl by 施洪宝

09-16

面向对象 by 施洪宝

2019-09-09 ~ 2019-09-13

09-12

信号量 by 张怡

09-11

nginx time by 闫昌

09-10

nginx进程同步 by 李乐

09-09

nginx进程间通信 by 李乐

2019-09-02 ~ 2019-09-06

09-03

nginx signal by 张怡

09-02

nginx ssl by 张金

2019-08-26 ~ 2019-08-30

08-30

nginx内部变量 by 尹振刚

08-29

nginx pool by 张文勇

08-28

nginx signal by 李乐

08-27

nginx 进程管理 by 李乐

08-26

nginx proxy by 陈雷

2019-08-19 ~ 2019-08-23

08-22

nginx proxy by 申振

08-21

nginx upstream by 申振

08-20

nginx by 闫昌

2019-08-12 ~ 2019-08-16

08-15

nginx 限流 by 刘志强

08-14

nginx event by 闫昌

08-13

nginx epoll by 闫昌

08-12

负载均衡 by 黄桃

2019-08-05 ~ 2019-08-09

08-08

nginx事件 by 闫昌

08-06

nginx事件 by 闫昌

08-05

nginx事件 by 闫昌

2019-07-29 ~ 2019-08-02

08-02

nginx upstream by 申振

08-01

redis部署 by 黄桃

07-31

nginx upstream by 申振

07-30

nginx http 11阶段 by 潘森

07-29

nginx http 11阶段 by 潘森

2019-07-22 ~ 2019-07-26

07-26

nginx缓存 by 申振

07-25

nginx负载均衡 by 申振

07-24

网关架构 by 张报

07-23

nginx负载均衡 by 申振

07-22

讲座重构 by 景罗

2019-07-15 ~ 2019-07-19

07-18

nginx http 执行 by 潘森

07-17

nginx http 执行 by 潘森

07-16

nginx http 执行 by 潘森

07-15

nginx fastcgi by 赵俊峰

2019-07-08 ~ 2019-07-12

07-12

红黑树 by 景罗

07-11

红黑树 by 景罗

07-10

nginx http配置三叉树 by 田志泽

07-09

nginx-新建http模块 by 马运运

07-08

nginx配置 by 田志泽

2019-07-01 ~ 2019-07-05

07-05

nginx by 田志泽

07-04

nginx by 田志泽

07-03

nginx by 李乐

07-02

nginx by 田志泽

07-01

nginx http module by 田志泽

2019-06-24 ~ 2019-06-28

06-28

linux文件系统 by 施洪宝

06-27

nginx by 闫昌

06-26

nginx module by 李乐

06-25

nginx http 11阶段 by 李乐

06-24

nginx http by 李乐

2019-06-17 ~ 2019-06-21

06-19

nginx by 李乐

06-18

[nginx by 李乐]][1]

06-17

nginx by 李乐

2019-06-10 ~ 2019-06-14

06-14

epoll by 李乐

06-13

nginx config by 马运运

06-12

nginx by 李乐

06-11

nginx by 李乐

06-10

nginx by 李乐

2019-06-03 ~ 2019-06-06

06-06

【Redis源码】redis 集群 by 闫昌

06-05

【Redis源码】redis sentinel by 闫昌

06-04

【Redis源码】redis 主从复制 by 李乐

06-03

【Redis源码】redis rdb by 施洪宝

2019-05-27 ~ 2019-05-31

05-31

【Redis源码】redis aof by 施洪宝

05-30

swoole server by 韩天峰

05-29

cakePHP分享 by 潘森

05-28

【Redis源码】by 闫昌

05-27

【Redis源码】by 闫昌

2019-05-20 ~ 2019-05-25

05-24

前端性能优化 by 李佳晓

05-23

没录上,因为操作失误

05-22

没录上,因为操作失误

05-21

slim框架学习 by 赵俊峰

05-20

【Redis源码】List命令 by 李乐

2019-05-13 ~ 2019-05-17

05-17

【Redis源码】Hash命令 by 施洪宝

05-16

【Redis源码】命令执行分析3 by 闫昌

05-15

【Redis源码】命令执行分析2 by 闫昌

05-14

公司搬家暂停一天

05-13

【redis源码】命令执行分析1 by 闫昌

2019-05-05 ~ 2019-05-10

05-10

使用boost做代码段的切换 by 李乐

clipboard.png

05-09

http1.1 2.0的基本原理2 by 陈雷

05-08

http1.1 2.0的基本原理1 by 杨志晓

05-07

协程切换 by 李乐

05-06

【Redis源码】命令的生命周期 by 李乐

05-05

【Redis源码】命令的生命周期 by 李乐

2019-04-28 ~ 2019-04-29

04-28

【Redis源码】命令的生命周期 by 李乐

2019-04-22 ~ 2019-04-26

04-26

malloc的实现 by 马运运

04-25

PHP生命周期 by 申振

04-24

协程初步讨论 by 王澍

04-23

【Redis源码】dict by 李乐

04-22

【Redis源码】dict by 施洪宝

2019-04-15 ~ 2019-04-19

04-19

【Redis源码】dict by 施洪宝

04-18

【Redis源码】ziplist by 李乐 intset by 施洪宝

04-17

【Redis源码】ziplist by 李乐

04-16

【Redis源码】Skiplist by 闫昌

04-15

【Redis源码】SDS by 陈雷

2019-04-08 ~ 2019-04-12

04-12

C栈和PHP递归压栈的过程 by 陈雷 李乐 王澍

04-11

内存管理复习 by 李乐

04-10

fastcgi协议2 by 施洪宝

04-09

fastcgi协议1 by 施洪宝

04-08

include语法 by 陈雷

2019-04-01 ~ 2019-04-04

04-04

while语法 by 陈雷

04-03

对象 by 景罗

04-02

垃圾回收2 by 欧阳

04-01

垃圾回收 by 欧阳

2019-03-25 ~ 2019-03-29

03-29

Zend虚拟机2 by 陈雷

03-28

Zend虚拟机1 by 陈雷

03-27

pass_two函数详解 by 陈雷

03-26

宏定义 by 景罗

03-25

AST遍历 by 陈雷

2019-03-18 ~ 2019-03-22

03-22

AST的遍历 by 陈雷

03-21

AST by 陈雷

03-20

词法分析 by 陈雷

03-19

垃圾回收 by 欧阳

03-18

复习前面的内容 by 陈雷

2019-03-11 ~ 2019-03-15

03-11

内存管理三 by 陈雷

03-12

基本变量 by 陈雷

03-13

字符串 by 景罗

03-15

基本变量 by 欧阳

2019-03-07 ~ 2019-03-08

03-07

内存管理一 by 陈雷

03-08

内存管理二 by 陈雷

查看原文

认证与成就

  • 获得 1 次点赞
  • 获得 1 枚徽章 获得 0 枚金徽章, 获得 0 枚银徽章, 获得 1 枚铜徽章

擅长技能
编辑

(゚∀゚ )
暂时没有

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2019-09-19
个人主页被 317 人浏览