PHP 多进程开发中常用的PCNTL常用的函数
PHP进程控制函数库(PCNTL),使php能在类unix系统中实现跟c一样的创建子进程、使用exec函数执行程序、处理信号等功能。 PCNTL使用ticks来作为信号处理机制(signal handle callback mechanism),可以最小程度地降低处理异步事件时的负载。Tick 是一个在代码段中解释器每执行N条低级语句就会发生的事件,这个代码段需要通过declare来指定。php多进程开发中常用的PCNTL常用的函数列表如下:
1. pcntl_alarm ( int $seconds )
设置一个$seconds秒后发送SIGALRM信号的计数器
2. pcntl_signal ( int $signo , callback $handler [, bool $restart_syscalls ] )
为$signo设置一个处理该信号的回调函数。下面是一个隔5秒发送一个SIGALRM信号,并由signal_handler函数获取,然后打印一个“Caught SIGALRM”的例子:
3. pcntl_exec ( string $path [, array $args [, array $envs ]] )
在当前的进程空间中执行指定程序,类似于c中的exec族函数。所谓当前空间,即载入指定程序的代码覆盖掉当前进程的空间,执行完该程序进程即结束。
4. pcntl_fork ( void )
为当前进程创建一个子进程,并且先运行父进程,返回的是子进程的PID,肯定大于零。在父进程的代码中可以用 pcntl_wait(&$status)暂停父进程知道他的子进程有返回值。注意:父进程的阻塞同时会阻塞子进程。但是父进程的结束不影响子进程的运行。
父进程运行完了会接着运行子进程,这时子进程会从执行pcntl_fork()的那条语句开始执行(包括此函数),但是此时它返回的是零(代表这是一个子进程)。在子进程的代码块中最好有exit语句,即执行完子进程后立即就结束。否则它会又重头开始执行这个脚本的某些部分。
5. pcntl_wait ( int &$status [, int $options ] )
阻塞当前进程,只到当前进程的一个子进程退出或者收到一个结束当前进程的信号。使用$status返回子进程的状态码,并可以指定第二个参数来说明是否以阻塞状态调用:
阻塞方式调用的,函数返回值为子进程的pid,如果没有子进程返回值为-1;
非阻塞方式调用,函数还可以在有子进程在运行但没有结束的子进程时返回0。
6. pcntl_waitpid ( int $pid , int &$status [, int $options ] )
功能同pcntl_wait,区别为waitpid为等待指定pid的子进程。当pid为-1时pcntl_waitpid与pcntl_wait 一样。在pcntl_wait和pcntl_waitpid两个函数中的$status中存了子进程的状态信息,这个参数可以用于 pcntl_wifexited、pcntl_wifstopped、pcntl_wifsignaled、pcntl_wexitstatus、 pcntl_wtermsig、pcntl_wstopsig、pcntl_waitpid这些函数。
7. pcntl_getpriority ([ int $pid [, int $process_identifier ]] )
取得进程的优先级,即nice值,默认为0,在我的测试环境的linux中(CentOS release 5.2 (Final)),优先级为-20到19,-20为优先级最高,19为最低。(手册中为-20到20)。
8. pcntl_setpriority ( int $priority [, int $pid [, int $process_identifier ]] )
设置进程的优先级。
9. posix_kill
可以给进程发送信号
- pcntl_singal
用来设置信号的回调函数
11.posix_setsid
用来脱离执行进程,自己生成管理进程以及处理进程。
PHP 信号处理
PHP5.3.0起支持pcntl_signal系列进程控制函数可以对信号进行安装、分发等操作。
信号处理函数
pcntl_signal():安装信号;pcntl_signal_dispatch():分发信号;pcntl_sigwaitinfo():等待信号;
信号类别
SIGTERM:信号触发命令:kill pid、kill -15 pid 、kill -SIGTERM等;SIGINT:程序终止(interrupt)信号,通常由ctrl+c触发;SIGKILL:触发命令:kill -9 pid;SIGHUP:挂断信号,通常父进程终止后向子进程组发送该信号;SIGALRM:定时器信号;
简单案例
// 安装信号
echo "开始安装信号...\n";
pcntl_signal(SIGHUP, function($signal) {
echo "信号被调用!\n";
});
// 发出信号
echo "发出信号...\n";
posix_kill(posix_getpid(), SIGHUP);
// 分发信号
echo "开始分发信号...\n";
pcntl_signal_dispatch();
echo "完成\n";
/*
开始安装信号...
发出信号...
开始分发信号...
信号被调用
完成
*/
复杂点案例
class Listener
{
public function __construct()
{
pcntl_signal(SIGTERM, array($this, "stop"));
pcntl_signal(SIGINT, array($this, "stop"));
pcntl_signal(SIGHUP, array($this, "sighup"));
pcntl_signal(SIGALRM, array($this, "alarm"), true);
set_error_handler(array($this, "errorHandler"));
}
public function errorHandler($errno, $errstr, $errfile, $errline)
{
if (!(error_reporting() & $errno)) {
// This error code is not included in error_reporting
return;
}
switch ($errno) {
case E_WARNING:
throw new \Exception("PHP WARNING: [$errno] $errstr $errfile Line:$errline");
return true;
case E_NOTICE:
throw new \Exception("PHP NOTICE: [$errno] $errstr $errfile Line:$errline");
return true;
default:
break;
}
return false;
}
abstract function stop($signo);
}
PHP函数file_get_contents()使用 https 协议时报错:SSL operation failed
场景:
file_get_contents() 函数是用于将文件的内容读入到一个字符串中,是读取文件内容常用的函数之一。
但是有时在服务器上使用file_get_contents() 函数请求https 协议的url文件时会报错误,无法正确读取文件内容,
查看log日志,日志内容类似如下:
PHP Warning: file_get_contents(): Failed to enable crypto in ......
PHP Warning: file_get_contents......: failedream: operation failed in ......
PHP Warning: file_get_contents(): SSL operatwith code 1. OpenSSL Error messages:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verin ......
原因:
服务器未正确配置好https证书
解决方法:(三种解决方法)
方法一:
下载https证书到服务器
服务器 下载这个证书,http://curl.haxx.se/ca/cacert.pem
php.ini 配置
openssl.cafile = "/etc/ssl/certs/cacert.pem"//你实际下载证书的路径
重启 php 即可
方法二:
使用cURL 函数处理 https 的参数,获取文件内容
<?php
function getSSLPage($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSLVERSION,3);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
var_dump(getSSLPage("https://xxx.xxx.xxx"));

https://stackoverflow.com/questions/14078182/openssl-file-get-contents-failed-to-enable-crypto
方法三:
使file_get_contents( 函数跳过https验证
$stream_opts = [
"ssl" => [
"verify_peer"=>false,
"verify_peer_name"=>false,
]
];
$response = file_get_contents("https://xxx.xxx.xxx",false, stream_context_create($stream_opts));
开发中建议使用cURL 函数替代file_get_contents()函数。
MongoDB 提供哪些管理和监控工具?
MongoDB 提供哪些管理和监控工具?
MongoDB 提供一系列的管理和监控工具,用于简化数据库的运维和性能监控。以下是 MongoDB 的一些主要管理和监控工具:
MongoDB Atlas: MongoDB Atlas 是 MongoDB 提供的云托管服务,它提供了一个易于使用的界面,允许用户在云中轻松部署、管理和监控 MongoDB 集群。MongoDB Atlas 还包括自动缩放、备份和安全性功能。MongoDB Compass: MongoDB Compass 是一个图形用户界面 (GUI) 工具,用于探索、分析和可视化 MongoDB 数据。它提供了直观的方式来执行查询、理解数据库结构,并支持地理空间数据的可视化。mongodump 和 mongorestore: 这两个命令用于备份和恢复 MongoDB 数据库。mongodump 用于创建数据库备份,而 mongorestore 用于将备份文件还原到 MongoDB。mongoimport 和 mongoexport: 这两个命令用于导入和导出 MongoDB 数据。mongoimport 用于将数据从文件导入到 MongoDB,而 mongoexport 用于将数据导出为 JSON 或 CSV 文件。
5. MongoDB Ops Manager: MongoDB Ops Manager 是一个全面的管理工具,用于监控、备份、自动缩放和安全性管理。Ops Manager 还提供了性能和故障排除工具,用于分析和改进 MongoDB 部署。
mongostat 和 mongotop: mongostat 用于实时监控 MongoDB 实例的性能统计信息,包括连接、查询、更新等活动。mongotop 用于实时监控 MongoDB 实例中的每个集合的读写性能。MongoDB Cloud Manager: MongoDB Cloud Manager 是 MongoDB 提供的云服务,用于集中管理和监控 MongoDB 部署。它提供实时性能监控、自动化备份和警报功能。mongod 和 mongos 日志: MongoDB 主要的服务进程 mongod 和路由进程 mongos 生成详细的日志文件,这些日志对于故障排除和性能分析非常有用。MMS(MongoDB Management Service): MMS 提供了对 MongoDB 部署的监控和管理,包括性能图表、慢查询分析、报警设置等。MongoDB Shell: MongoDB 提供了交互式的 JavaScript shell,允许用户通过命令行界面执行数据库操作和查询,用于管理和监控数据库。
如何在 MongoDB 中实现身份验证?
如何在 MongoDB 中实现身份验证?
在 MongoDB 中,可以通过设置身份验证来增加数据库的安全性。MongoDB 提供了多种身份验证方法,包括内置用户和角色管理系统、LDAP、Kerberos 等。以下是使用内置用户和角色管理系统进行身份验证的一般步骤:
启用身份验证: 在 MongoDB 配置文件中启用身份验证。编辑 MongoDB 的配置文件(通常是 mongod.conf),添加以下配置项:
authorization: enabled
这将启用身份验证机制。
- 重启
MongoDB 服务: 在修改配置文件后,重启 MongoDB 服务以使配置生效。 创建管理员用户: 连接到 MongoDB 服务器,并使用管理员权限创建一个管理员用户。启动 mongo shell 并连接到 MongoDB,然后执行以下命令:
use admin
db.createUser({
user: "adminUser",
pwd: "adminPassword",
roles: ["userAdminAnyDatabase", "dbAdminAnyDatabase", "readWriteAnyDatabase"]
})
这将创建一个名为 adminUser 的管理员用户,并授予管理权限。
重新连接并使用身份验证: 使用新创建的管理员用户重新连接到 MongoDB,并启用身份验证。
mongo -u adminUser -p
在连接时,输入管理员用户的密码。
- 创建应用程序用户: 为你的应用程序创建一个专用的数据库和用户。在连接到
MongoDB 的 mongo shell 后,执行以下命令:
use yourDatabase
db.createUser({
user: "yourAppUser",
pwd: "yourAppPassword",
roles: ["readWrite"]
})
这将创建一个名为 yourAppUser 的应用程序用户,并授予读写权限。
连接并使用应用程序用户: 使用新创建的应用程序用户连接到 MongoDB。
mongo -u yourAppUser -p --authenticationDatabase yourDatabase
在连接时,输入应用程序用户的密码。
通过执行上述步骤,你可以成功地在 MongoDB 中启用身份验证,并设置不同权限的用户以用于不同的操作。这提高了
MongoDB 数据库的安全性,确保只有经过身份验证的用户才能访问数据库。
什么是角色和权限?如何配置它们?
在 MongoDB 中,角色(Roles)和权限(Privileges)是用于管理数据库访问和操作的重要概念。
角色(Roles): 角色是 MongoDB 中定义的一组权限集合。每个角色代表一组特定的数据库权限,可以授予用户或用户组。MongoDB 包含一些内置角色,如读取权限、写入权限、数据库管理员权限等。
权限(Privileges): 权限是指用户或用户组对数据库和集合的操作权限。权限控制了用户对数据库的 CRUD 操作(创建、读取、更新、删除)以及其他操作的能力。
配置角色和权限:
创建角色: 使用 db.createRole() 命令在 MongoDB 中创建角色。指定角色的名称、角色包含的权限以及其他相关选项。
db.createRole({
role: "customRole",
privileges: [
{ resource: { db: "yourDatabase", collection: "" }, actions: ["find", "insert", "update"] }
],
roles: []
})
在上面的示例中,创建了一个名为 customRole 的自定义角色,具有对 yourDatabase 数据库的查找、插入和更新操作的权限。
创建用户并分配角色: 使用 db.createUser() 命令在 MongoDB 中创建用户,并将角色分配给用户。
db.createUser({
user: "yourUser",
pwd: "yourPassword",
roles: ["customRole"]
})
在上面的示例中,创建了一个名为 yourUser 的用户,并分配了 customRole 角色。
内置角色: MongoDB 提供了一些内置的常用角色,例如 read、readWrite、dbAdmin、userAdmin 等。可以通过将这些角色分配给用户来快速配置权限。
db.createUser({
user: "anotherUser",
pwd: "anotherPassword",
roles: ["readWrite", "dbAdmin"]
})
查看用户及其权限: 使用 db.getUser() 命令查看用户及其分配的角色和权限。
db.getUser("yourUser")
更新用户权限: 使用 db.grantRolesToUser() 和 db.revokeRolesFromUser() 命令来更新用户的权限。
db.grantRolesToUser("yourUser", ["readWrite"])
上面的命令将向 yourUser 用户授予 readWrite 角色。
通过配置角色和权限,你可以细粒度地控制用户对 MongoDB 数据库的访问和操作。这对于确保安全性和按需授予访问权限非常有用。