php-redis源码之长链接、短连接、命令自动检活

源码函数所在文件

为了避免代码影响阅读,以及代码顺序不符合个人的读码习惯,就不贴代码了,都可以通过函数名在下面几个c文件中找到

  • redis.c
  • library.c
  • common.h

几个核心函数

  • redis_connect:用于创建redis对象并建立sock连接。第一个参数INTERNAL_FUNCTION_PARAM_PASSTHRU是宏定义,用来获取函数传入的参数,第二个参数persistent用于区分是否长链接。

  • redis_sock_get:获取sock,检活,第一个参数如果为空的sock对象,则代表用新的连接,并且不需要检活;如果为当前sock对象(getThis函数获取),则需要在hash符号表里查找是否有旧的sock对象。

  • redis_sock_get_instance:根据redis实例的id,返回redis实例中的sock

  • redis_sock_server_open:用于判断socket活跃状态,如果连接已断开调用redis_sock_connect重新连接。

  • redis_sock_create:为redis实例对象创建新的sock连接,申请空间,存储到zend全局空间中

  • redis_sock_disconnect:释放sock连接,如果是长链接从连接池中获取释放,短连接直接释放

  • redis_sock_get_connection_pool:从连接池中获取连接

  • php_stream_pclose:关闭长链接

  • php_stream_close:关闭短连接

  • redis_free_socket:释放sock占用的zend全局空间

几个核心宏定义

  • PHPREDIS_GET_OBJECT:获取redis实例

  • REDIS_THROW_EXCEPTION:抛出异常

  • INTERNAL_FUNCTION_PARAM_PASSTHRU获取参数

pconnect长链接逻辑

调用redis_connect创建长链接经历下面几个步骤(参数persistent为1)

  1. 初始化变量和参数
  2. 条件编译,检测ZTS宏定义,将persistent改为0(我猜是在某些环境下不允许长链接)
  3. 调用zend_parse_method_parameters获取参数,获取失败则返回错误

  4. 如果是短连接,persistent_id(长链接id)定义为NULL,这里由于是长链接,跳过

  5. 检测timeout、read_timeout、retry_interval、port

  6. 调用PHPREDIS_GET_OBJECT宏定义redis对象

  7. 如果该对象的sock已经被创建则调用redis_sock_disconnect断开sock连接,并调用redis_free_socket释放sock(我认为应该是怕多个并发请求创建重复链接)

  8. redis_sock_create创建新的sock持久化连接

  9. 为了保险,调用redis_sock_server_open检查连接状态,如果连接失败调用redis_free_socket释放sock,并返回错误

  10. 返回成功

connect短连接逻辑

    和上面创建长链接步骤一致,只不过persistent参数为0

redis命令操作

  • REDIS_PROCESS_CMD进入执行redis命令

  • 调用redis_sock_get获取当前连接,第一个参数用getThis()函数获取当前redis对象,参数no_throw传0代表redis_sock_get_instance不跳过异常抛出

  • 调用redis_sock_get_instance获取redis实例中的sock连接

  • 调用redis_sock_server_open检测连接状态,断开会自动重连

  • 返回活跃的redis_sock连接

  • 用前面返回的sock连接执行redis命令

  • 返回命令结果

发布了253 篇原创文章 · 获赞 47 · 访问量 18万+

猜你喜欢

转载自blog.csdn.net/why444216978/article/details/104826942
今日推荐