文章851
标签121
分类10

Swoole http 服务 Error: Too many open files[24]

错误日志:

[2018-10-25 15:53:46 #18031.8]  ERROR   swServer_master_onAccept (ERROR 502): accept() failed. Error: Too many open files[24]
$ lsof

php       18031    dev 2228u     sock                0,6      0t0 22568618 can't identify protocol
php       18031    dev 2229u     sock                0,6      0t0 22568628 can't identify protocol
php       18031    dev 2230u     sock                0,6      0t0 22568639 can't identify protocol

strace -p 18031

accept4(3, 0x7ffead354820, [116], SOCK_CLOEXEC|SOCK_NONBLOCK) = -1 EMFILE (Too many open files)

通用解决方案 ulimit -n 调整参数

出现bug 的原因也是sock文件开启过多

问题环境介绍:

阿里云连接 AWS 数据库ip端口映射地址 (非常慢)
数据库连接或调用抛出异常就会重连, 弱网环境死循环.
服务启动大概2-4小时候文件开启数达到上限.....
修改代码重启至今未出现相同场景

先监控把 以后有问题本文会持续更新


问题已找到

[2018-11-02 15:21:48 #17293.8]  ERROR   swServer_master_onAccept (ERROR 502): accept() failed. Error: Too many open files[24]
因为业务需要将用户固定worker_id, 使用 dispatch_func 参数 在调度线程下
dispatch_func return -1 导致问题出现, -1 表示 master/manage 进程 , 阿里云环境存在无响应头的请求包

经过测试 在 Server Start 和 Manage Start 启动时 打印worker_id 返回的都是 -1

Linux 查看服务下进程内存占用情况

在 Linux 系统中,监控进程的内存占用情况对于系统管理员和开发者来说是至关重要的。了解哪些服务或进程消耗了大量内存,可以帮助我们优化性能和排查问题。本文将介绍几种常用的方法来查看服务下的进程内存占用情况。

1. 使用 ps 命令

ps 是一个常用的命令,可以用来查看当前系统中运行的进程及其状态。要查看特定服务下的进程和内存占用情况,可以使用以下命令:

ps aux --sort=-%mem | grep <service_name>
  • aux: 显示所有用户的进程,包括其他用户的。
  • --sort=-%mem: 按照内存占用排序,- 表示降序。
  • grep <service_name>: 过滤出特定服务的进程。

示例

ps aux --sort=-%mem | grep nginx

2. 使用 top 命令

top 命令提供了一个动态更新的实时视图,显示系统中进程的 CPU 和内存占用情况。启动 top 后,可以按 M 键按照内存占用排序。

启动 top

top

过滤特定服务

top 界面中,按下 Shift + L(或在某些版本中是 f)键,然后输入服务的名称进行过滤。

示例图

+--------------------------------------------------+
|    top - 14:15:19 up  1 day,  5:35,  2 users     |
+--------------------------------------------------+
| Tasks: 210 total,   1 running, 209 sleeping      |
| %Cpu(s):  3.5 us,  1.2 sy,  0.0 ni, 95.3 id      |
| KiB Mem :  16384000 total,  12345678 free        |
| KiB Swap:  10240000 total,   1024000 free        |
+--------------------------------------------------+
|  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM TIME+ COMMAND  |
| 1234 www-data  20   0  1234567  45678  12345 S   0.0  0.3  0:01.23 nginx   |
| 5678 www-data  20   0  2345678  56789  23456 S   0.0  0.4  0:02.34 nginx   |
+--------------------------------------------------+

3. 使用 htop 命令

htoptop 的增强版,提供了更友好的界面和更多功能。可以使用箭头键浏览进程列表,并按 F6 键选择排序方式。

安装 htop

如果你的系统没有安装 htop,可以通过以下命令安装:

sudo apt install htop   # Ubuntu/Debian 系统
sudo yum install htop   # CentOS/RHEL 系统

启动 htop

htop

过滤特定服务

htop 界面中,可以按 F3 键输入服务名称进行搜索。

示例图

+--------------------------------------------------+
|  PID USER      TIME    VIRT    RES    SHR S %CPU %MEM COMMAND  |
|  1234 www-data  0:01.23 1234567  45678  12345 S  0.0  0.3 nginx   |
|  5678 www-data  0:02.34 2345678  56789  23456 S  0.0  0.4 nginx   |
+--------------------------------------------------+

4. 使用 pmap 命令

pmap 命令可以显示进程的内存占用情况,可以用来查看特定进程的内存分布。

使用示例

首先,使用 ps 命令找到进程 ID(PID),然后使用 pmap

pmap <PID>

示例

pmap 1234

输出示例

1234:   nginx
0000000000400000   4K r-x-- nginx
0000000000600000   4K rw--- nginx
...

结论

监控进程的内存占用情况是系统维护和优化的重要部分。通过 pstophtoppmap 等工具,你可以轻松查看特定服务下的进程内存占用情况,帮助你及时发现和解决性能问题。

PHP Xdebug 调试代码

在 PHP 开发中,调试是一个非常重要的环节。Xdebug 是一个强大的 PHP 扩展,提供了丰富的调试功能,可以帮助开发者快速定位问题。本文将介绍如何安装和配置 Xdebug,以及如何使用它进行代码调试。

什么是 Xdebug?

Xdebug 是一个开源的 PHP 扩展,主要用于:

  • 调试:通过提供堆栈跟踪、函数调用跟踪等功能,帮助开发者分析代码执行过程。
  • 性能分析:提供代码覆盖率信息,帮助开发者优化代码。
  • 错误跟踪:提供详细的错误和异常信息,便于快速定位问题。

安装 Xdebug

1. 检查 PHP 版本

在安装 Xdebug 之前,首先需要确认你的 PHP 版本。可以使用以下命令查看:

php -v

2. 安装 Xdebug

根据你的 PHP 版本和操作系统,选择合适的安装方式。通常可以通过 pecl 命令安装:

pecl install xdebug

如果使用的是 Windows,可以下载适合你 PHP 版本的 DLL 文件,并将其放入 PHP 的扩展目录中。

3. 配置 php.ini

安装完成后,需要在 php.ini 中配置 Xdebug。找到 php.ini 文件,添加以下配置:

[xdebug]
zend_extension="path_to_xdebug.so"  ; Linux
; zend_extension="path_to_xdebug.dll" ; Windows

; Xdebug 配置
xdebug.remote_enable=1
xdebug.remote_host=127.0.0.1
xdebug.remote_port=9000
xdebug.remote_autostart=1
  • zend_extension: 指定 Xdebug 扩展的路径。
  • remote_enable: 启用远程调试。
  • remote_host: 指定调试客户端的 IP 地址。
  • remote_port: 指定调试端口,默认是 9000。

4. 重启 Web 服务器

在修改 php.ini 后,重启你的 Web 服务器(如 Apache 或 Nginx)以使配置生效。

使用 Xdebug 进行调试

1. 配置 IDE

大多数现代 IDE(如 PHPStorm、Visual Studio Code)都支持 Xdebug。以下是 PHPStorm 的配置方法:

  1. 打开 PHPStorm,进入 Preferences(或 Settings)。
  2. 找到 PHP -> Debug,确保 Xdebug 端口与 php.ini 中的配置一致(通常是 9000)。
  3. 配置 Servers,设置你的项目路径和 URL。

2. 设置断点

在 PHPStorm 中,可以在代码行的左侧点击以设置断点。断点是调试的关键,它允许我们在特定位置暂停代码执行,以便检查变量和执行流程。

3. 启动调试会话

在浏览器中,可以使用以下方式启动调试会话:

  • 使用 GET 参数: 在 URL 中添加 ?XDEBUG_SESSION_START=1
  • 使用浏览器扩展: 安装 Xdebug Helper 浏览器扩展(适用于 Chrome 和 Firefox),方便快捷地启动调试会话。

4. 调试代码

当请求被发送到服务器并触及断点时,Xdebug 会暂停执行。在 IDE 中,你可以:

  • 查看变量: 检查当前作用域中的变量值。
  • 单步执行: 逐行执行代码,观察执行过程。
  • 查看堆栈: 查看当前调用堆栈,了解代码执行路径。

调试过程中示意图

+---------------------+
|      用户请求      |
+---------------------+
          |
          v
+---------------------+
|      Web 服务器     |
|    (触发断点)      |
+---------------------+
          |
          v
+---------------------+
|    调试客户端       |
|  (如 PHPStorm)     |
+---------------------+
          |
          v
+---------------------+
|   检查变量/执行    |
|   单步调试/查看堆栈 |
+---------------------+

注意事项

  1. 性能影响: Xdebug 会增加应用的执行时间,因此建议在开发环境中使用,在生产环境中禁用。
  2. 配置检查: 确保 php.ini 中的配置正确,尤其是远程调试的设置。
  3. 使用 HTTPS: 如果你的应用在 HTTPS 下运行,确保 Xdebug 也能正确处理 HTTPS 请求。

总结

Xdebug 是 PHP 开发中的强大工具,能够显著提高调试效率。通过正确的安装和配置,可以在代码中设置断点,查看变量值,并逐步执行代码,从而快速定位问题。

通俗易懂的 CPU 流水线

在计算机科学中,CPU 流水线(Pipeline)是一种提高指令处理效率的技术。它通过将指令执行过程分成多个阶段,使得不同指令可以在同一时间内并行处理。本文将通俗易懂地解释 CPU 流水线的工作原理,并通过图示帮助理解。

什么是 CPU 流水线?

CPU 流水线可以类比于工厂的生产流水线。就像在工厂中,多个工人在不同的工作站上并行工作,加快了生产速度,CPU 流水线允许 CPU 同时处理多条指令的不同阶段,从而提高执行效率。

流水线的基本阶段

典型的 CPU 流水线分为以下几个阶段:

  1. 取指(Fetch, IF): 从内存中获取指令。
  2. 译码(Decode, ID): 解析指令,确定操作数和执行方式。
  3. 执行(Execute, EX): 执行指令,进行算术或逻辑运算。
  4. 访存(Memory Access, MEM): 访问内存(如果需要)。
  5. 写回(Write Back, WB): 将结果写回寄存器。

流水线的工作示例

下面的图示展示了一个简单的 5 阶段 CPU 流水线的工作过程:

时间 -->   
周期 1: IF1
周期 2: ID1   IF2
周期 3: EX1   ID2   IF3
周期 4: MEM1  EX2   ID3   IF4
周期 5: WB1   MEM2  EX3   ID4
周期 6:       WB2   MEM3  EX4
周期 7:             WB3   MEM4
周期 8:                   WB4
  • IF1: 第一条指令被取出。
  • ID1: 第一条指令被译码,同时第二条指令被取出。
  • EX1: 第一条指令执行,第二条指令译码,第三条指令取出。

通过流水线,CPU 在处理指令时可以实现重叠,提高了指令的执行效率。

流水线的优点

  1. 提高吞吐量: 流水线允许多个指令在不同阶段并行处理,从而增加单位时间内处理的指令数量。
  2. 减少延迟: 尽管单条指令的执行时间没有减少,但通过流水线处理,CPU 能够更快地开始执行新指令。

流水线的挑战

尽管流水线技术提高了效率,但也面临一些挑战:

  1. 数据冒险: 如果一条指令依赖于前一条指令的结果,可能会导致错误。
  2. 控制冒险: 条件分支指令可能导致流水线中的指令需要重新调整。
  3. 结构冒险: 硬件资源冲突,例如多个指令同时需要访问内存。

解决方案

为了解决上述问题,现代 CPU 采用了多种技术,例如:

  • 数据前推: 通过将结果提前传递给依赖的指令,减少数据冒险的影响。
  • 分支预测: 预测条件分支的结果,提前加载可能执行的指令。
  • 超标量架构: 在同一时钟周期内执行多条指令,进一步提高性能。

总结

CPU 流水线是一种重要的技术,通过将指令的执行过程分成多个阶段,实现了高效的并行处理。尽管面临一些挑战,但现代 CPU 通过各种技术克服了这些问题,使得流水线技术成为提升计算机性能的核心方法之一。

Swoole CPU 亲和性配置 `open_cpu_affinity`

open_cpu_affinity

启用CPU亲和性设置。在多核的硬件平台中,启用此特性会将swoole的reactor线程/worker进程绑定到固定的一个核上。可以避免进程/线程的运行时在多个核之间互相切换,提高CPU Cache的命中率。

使用taskset命令查看进程的CPU亲和设置:

taskset -p 进程ID
pid 24666's current affinity mask: f
pid 24901's current affinity mask: 8

mask是一个掩码数字,按bit计算每bit对应一个CPU核,如果某一位为0表示绑定此核,进程会被调度到此CPU上,为0表示进程不会被调度到此CPU。

示例中pid为24666的进程mask = f 表示未绑定到CPU,操作系统会将此进程调度到任意一个CPU核上。
pid为24901的进程mask = 8,8转为二进制是 1000,表示此进程绑定在第4个CPU核上。

仅推荐在全异步非阻塞的Server程序中启用
">