本文讲述php共享内存shmop使用过程中遇到的问题和注意事项
维护某个后台PHP模块,发现有用到共享内存存储一些第三方的静态配置信息,使用共享内存过程中有遇到些问题,汇总在这里
1.shmop共享内存没有判断边界,超出限制会导致截断且未返回错误导致获取信息异常
shmop_write写入的数据,如果超出限制会自动截断而不报错:
看官网示例:
$written = shmop_write($shm_id, $write_d1, 0);
if ($written != strlen($write_d1)) {
echo "failed\n";
} else {
echo "ok\n";
}
结论:官网示例给出要求执行完写入操作后对写入数据进行判断,如果待写入的数据长度和实际数据长度不一致属于异常
2.遇到权限问题,导致写入共享内存失败
服务中遇到共享内存,很少会遇到权限的问题。
常见的权限问题为除了服务以外的监控/提醒脚本在部署的过程中因为权限和服务权限不一样导致权限问题(之前遇到脚本迁移或扩容的过程中因为部署权限问题导致共享内存读写失败的情况)。
因此,共享内存一定要注意权限的设置,shmop_open中有权限相关参数,需根据不同场景来进行设置:
维护某个后台PHP模块,发现有用到共享内存存储一些第三方的静态配置信息,使用共享内存过程中有遇到些问题,汇总在这里
1.shmop共享内存没有判断边界,超出限制会导致截断且未返回错误导致获取信息异常
shmop_write写入的数据,如果超出限制会自动截断而不报错:
看官网示例:
$written = shmop_write($shm_id, $write_d1, 0);
if ($written != strlen($write_d1)) {
echo "failed\n";
} else {
echo "ok\n";
}
结论:官网示例给出要求执行完写入操作后对写入数据进行判断,如果待写入的数据长度和实际数据长度不一致属于异常
2.遇到权限问题,导致写入共享内存失败
服务中遇到共享内存,很少会遇到权限的问题。
常见的权限问题为除了服务以外的监控/提醒脚本在部署的过程中因为权限和服务权限不一样导致权限问题(之前遇到脚本迁移或扩容的过程中因为部署权限问题导致共享内存读写失败的情况)。
因此,共享内存一定要注意权限的设置,shmop_open中有权限相关参数,需根据不同场景来进行设置:
结论:同一机器上需保持读写同一片共享内存的权限一致
3.ftok函数获取系统共享内存唯一编号key_t,虽然pathname和proj不变,key_t也可能会变化,偶尔发现什么数据也没改动共享内存数据为空了
key_t = ftok ( string $pathname
, string $proj
)
ftok获取的健值是由ftok函数的第二个参数的后8位,st_dev的后8位,st_ino的后16位构成的:
char filename[50];
struct stat buf;
int ret;
strcpy( filename, "/home/satellite/" );
ret = stat( filename, &buf );
if( ret )
{
printf( "stat error\n" );
return -1;
}
printf( "the file info: ftok( filename, 0x27 ) = %x, st_ino = %x, st_dev= %x\n", ftok( filename, 0x27 ), buf.st_ino, buf.st_dev );
stat数据结构如下,可通过stat命令查看文件详细信息:
The structure stat contains at least the following members:
dev_t st_dev ID of device containing file
ino_t st_ino file serial number
mode_t st_mode mode of file (see below)
nlink_t st_nlink number of links to the file
uid_t st_uid user ID of file
gid_t st_gid group ID of file
dev_t st_rdev device ID (if file is character or block special)
off_t st_size file size in bytes (if file is a regular file)
time_t st_atime time of last access
time_t st_mtime time of last data modification
time_t st_ctime time of last status change
blksize_t st_blksize a filesystem-specific preferred I/O block size for
this object. In some filesystem types, this may
vary from file to file
blkcnt_t st_blocks number of blocks allocated for this object
可以看出即使pathname和proj 不变,只要文件修改或删除,st_dev st_ino发生变化key_t也有可能发生变化:
可以通过stat -c '%i' filename 查看i节点,
通过stat -c '%d' filename 查看文件设备编号,
这里在获取ID的时候要注意,有时发现什么也没改动,查询共享内存数据无缘无故消失了,可能就是修改或删除filename的文件导致。
结论:只要文件发生变更,哪怕入参不变key_t也可能会变化,如果我们遇到没有变动任何代码,共享内存却为空了,可以通过上述方式排查。
参考资料
https://pubs.opengroup.org/onlinepubs/009695399/basedefs/sys/stat.h.html
https://pubs.opengroup.org/onlinepubs/007908799/xsh/sysstat.h.html
结论:同一机器上需保持读写同一片共享内存的权限一致
3.ftok函数获取系统共享内存唯一编号key_t,虽然pathname和proj不变,key_t也可能会变化,偶尔发现什么数据也没改动共享内存数据为空了
key_t = ftok ( string $pathname
, string $proj
)
ftok获取的健值是由ftok函数的第二个参数的后8位,st_dev的后8位,st_ino的后16位构成的:
char filename[50];
struct stat buf;
int ret;
strcpy( filename, "/home/satellite/" );
ret = stat( filename, &buf );
if( ret )
{
printf( "stat error\n" );
return -1;
}
printf( "the file info: ftok( filename, 0x27 ) = %x, st_ino = %x, st_dev= %x\n", ftok( filename, 0x27 ), buf.st_ino, buf.st_dev );
stat数据结构如下,可通过stat命令查看文件详细信息:
The structure stat contains at least the following members:
dev_t st_dev ID of device containing file
ino_t st_ino file serial number
mode_t st_mode mode of file (see below)
nlink_t st_nlink number of links to the file
uid_t st_uid user ID of file
gid_t st_gid group ID of file
dev_t st_rdev device ID (if file is character or block special)
off_t st_size file size in bytes (if file is a regular file)
time_t st_atime time of last access
time_t st_mtime time of last data modification
time_t st_ctime time of last status change
blksize_t st_blksize a filesystem-specific preferred I/O block size for
this object. In some filesystem types, this may
vary from file to file
blkcnt_t st_blocks number of blocks allocated for this object
可以看出即使pathname和proj 不变,只要文件修改或删除,st_dev st_ino发生变化key_t也有可能发生变化:
可以通过stat -c '%i' filename 查看i节点,
通过stat -c '%d' filename 查看文件设备编号,
这里在获取ID的时候要注意,有时发现什么也没改动,查询共享内存数据无缘无故消失了,可能就是修改或删除filename的文件导致。
结论:只要文件发生变更,哪怕入参不变key_t也可能会变化,如果我们遇到没有变动任何代码,共享内存却为空了,可以通过上述方式排查。
参考资料
https://pubs.opengroup.org/onlinepubs/009695399/basedefs/sys/stat.h.html
https://pubs.opengroup.org/onlinepubs/007908799/xsh/sysstat.h.html
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。