jwj 发布的文章

默认情况下,宝塔的 WEB 软件记录日志时,不会按日期将日志储存到不同的文件里,长时间的日志都记录到一个文件里,很不方便查阅和管理。

一、安装 logrotate

大多 Linux 系统一般都自带 logrotate,如果刚好你的系统没有自带,可以在github下载源代码进行编译安装。

或者直接尝试用命令进行安装,例如:

  • 红帽系统(Red Hat):yum install logrotatednf install logrotate
  • 乌班图(Ubuntu):sudo apt-get install logrotateapt install logrotate

二、原理

其实“切割”二字并不对,具体我们来简单说说个人理解的工作原理。
1.logrotate 执行时,会对符合配置里设定的条件的文件进行处理。
2.然后重命名日志文件,并创建新的日志文件。
3.执行其它操作,如:压缩文件。

三、配置

新建并编辑配置文件

sudo vim /etc/logrotate.d/btweblogs

配置内容

/www/wwwlogs/*.log  {
    # 间隔时间:daily=每天/weekly=每周/monthly=每月/yearly=每年
    daily
    # 保留份数,超过该数量的旧日志自动删除
    rotate 14
    # 忽略错误,如:文件不存在
    missingok
    # 使用日期格式重命名文件
    dateext
    # 对分离出来的文件进行压缩
    compress
    # 不压缩本次分离出来的文件
    delaycompress
    # 忽略空文件(即不分离空的文件)
    notifempty
    # 多个文件分离后只执行一次脚本
    sharedscripts
    # 文件分离后执行的脚本
    postrotate
        # 通知Nginx和Apache程序重载
        # Nginx
    [ -e /www/server/nginx/logs/nginx.pid ] && kill -USR1 `cat /www/server/nginx/logs/nginx.pid`
        # Apache
    [ -e /www/server/apache/logs/httpd.pid ] && kill -USR1 `cat /www/server/apache/logs/httpd.pid`
    endscript
}

四、结束

logrotate 除了可以分离压缩文件,还可以将分离出来的文件通过邮件发送到指定邮箱,具体方法可以查阅 logrotate 的手册

宝塔本身也有日志切割功能,如果没有压缩之类的需求,可以使用宝塔的功能。

为进一步减轻生育医疗费用报销“跑腿”“垫资”负担,市医疗保障局印发了《关于开展职工生育医疗费用直接结算工作的通知》(韶医保〔2022〕23号),从今年5月1日起,生育医疗费用均可在医院收费窗口“一站式”直接报销,不需要垫资和返回报销。此外,同步开通了职工生育保险异地就医产生的生育医疗费用联网直接报销。

信息参考:

6月13日去产检时,听到的消息是产前检查的总费用最高报销2500元。当时心想,这也太少了吧?
于是查找相关资料,找到了上方的两条信息。信息中提到:

产前检查发生的核准医疗费用按项目结算,最高支付限额为2500元

到这里就很疑惑了,一边说总费用最高2500,一边说按项目最高2500,事实是什么?于是致电韶关市医保局(0751-8733130),得到了准确的结果,也是失望的结果。

按照工作人员的解答,总结如下:

  1. 符合报销条件的产前检查总费用,最高能报销2500元。而不是按照每项或每次检查最高报2500;
  2. 5月1日前分娩的,按旧政策报销费用。5月1日起分娩的,按新政策。
  3. 生育津贴仍然按照以前的方式进行领取,即不变。

我目前的情况是卡在孕中期实施的新政策,如果后续的检查费报销满2500元了,那就不能再报了。
如果后续的检查费报不满,可以拿没报的费用的发票去医保局或相关医保窗口去进行报销。

不过说实在的,这2500的额度真低,目前我老婆才中期,产前检查的费用就花了一万多了。


对于新政策的报销,这里要提醒各位宝爸宝妈。

需要先在粤省事里办理生育登记(粤省事里直接搜生育登记就能找到),没什么特殊情况的话,我们只需要电子证照就行,免去了线下跑的时间。如果申请通过,但电子证迟迟下不了,可以致电辖区计生办,让他们签发。

《生育登记》代替了以前的《准生证》
所需材料:夫妻双方的身份证

《生育登记》的电子证照下来后,还需要在产科护士台哪里进行登记。

所需材料:准妈妈的身份证或社保卡、生育登记证明

后面待续...

think-queue 是 ThinkPHP 下的一款任务队列支持组件,这次使用主要用于在项目里承担消息发送及相关操作事件的回调操作。

安装

目前 ThinkPHP 基本都是使用 composer 来管理组件包,所以安装也是使用 composer 进行。

composer require topthink/think-queue

配置

安装好之后,会在 conifg 目录下生成一个 queue.php 配置文件。
目前支持三种队列数据储存方式:

方式说明
sync同步执行,有新队列任务则通过 ThinkPHP 的事件 Event 来直接触发执行
database数据库存储,新队列任务数据存储到数据库,队列执行程序再从数据库中读取任务数据
redisRedis 存储,新队列任务数据存储到 Redis,队列执行程序再从 Redis 中读取任务数据
<?php
return [
    // 默认连接
    'default'     => 'sync',
    // 连接配置
    'connections' => [
        // 同步执行
        'sync'     => [
            // 连接方式
            'type' => 'sync',
        ],
        // 数据库
        'database' => [
            'type'       => 'database',
            // 队列名
            'queue'      => 'default',
            // 表名
            'table'      => 'jobs',
            // 数据连接配置(database.connections)
            'connection' => null,
        ],
        // Redis
        'redis'    => [
            'type'       => 'redis',
            'queue'      => 'default',
            // 服务器IP
            'host'       => '127.0.0.1',
            // 服务器端口
            'port'       => 6379,
            // 认证密码
            'password'   => '',
            // 数据库
            'select'     => 0,
            // 超时时间(0代表不限制)
            'timeout'    => 0,
            // 持久化
            'persistent' => false,
        ],
    ],
    // 失败队列任务记录
    'failed'      => [
        // 记录方式:none=不记录,database=记录在数据库
        'type'  => 'none',
        // 数据库表名
        'table' => 'failed_jobs',
    ],
];

数据库初始化

使用脚本

如果是选择数据库作为队列任务数据储存方式,那边需要创建对应的表。
think-queue 是使用 think-migration 来创建数据库表的,所以需要先安装 think-migration

composer require topthink/think-migration

然后再使用这三条命令来完成表创建

php think queue:table
php think queue:failed-table
php think migrate:run 

image23c55974503ff17b.png

初始化完毕之后,删除 think-migration,因为后续使用用不上了。

composer remove topthink/think-migration

同时,清理残余文件和表。删除项目下的 database 目录,删除数据库中的 migrations 表。

自行创建表

当然,think-migration 也是直接写入表,只是能兼容多种数据库类型。
如果你是用 MySQL,且懒得用命令执行数据库初始化的话,可以直接使用下面的语句来创建表。

CREATE TABLE `jobs` (
  `id` int NOT NULL AUTO_INCREMENT,
  `queue` varchar(255) NOT NULL,
  `payload` longtext NOT NULL,
  `attempts` tinyint unsigned NOT NULL,
  `reserve_time` int unsigned DEFAULT NULL,
  `available_time` int unsigned NOT NULL,
  `create_time` int unsigned NOT NULL,
  PRIMARY KEY (`id`),
  KEY `queue` (`queue`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
CREATE TABLE `failed_jobs` (
  `id` int NOT NULL AUTO_INCREMENT,
  `connection` text NOT NULL,
  `queue` text NOT NULL,
  `payload` longtext NOT NULL,
  `exception` longtext NOT NULL,
  `fail_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;

创建任务类

任务类不需继承任何类,如果这个类只有一个任务,那么就只需要提供一个 fire 方法就可以了,如果有多个小任务,就写多个方法,下面发布任务的时候会有区别。
每个方法会传入 $job$data参数。还有个可选的任务失败执行的方法 failed 传入的参数为 $data

简单的邮件发送任务类:

<?php

namespace app\job;

use think\queue\Job;

/**
 * 发送邮件通知
 */
class Mail
{
    /**
     * 默认任务
     * @param Job   $job  当前任务
     * @param mixed $data 任务数据
     */
    public function fire(Job $job, $data)
    {
        // 发送邮件
        $ret = mail($data['to'], $data['subject'], $data['message']);

        // 发送成功,删除当前任务。如果不删除,会重新执行任务!!!
        if (true === $ret) {
            $job->delete();
            return;
        }

        // 如果重试发送超过3次都没成功,那就记录错误一条日志
        if ($job->attempts() > 3) {
            error_log('邮件发送失败');
            return;
        }
        
        // 当然,如果测试时间不想因为失败而导致删除任务,可以重新发布任务
        $job->release(5);
    }

    /**
     * 任务1
     * @param Job   $job  当前任务
     * @param mixed $data 任务数据
     */
    public function one(Job $job, $data)
    {
    }

    /**
     * 任务失败
     * @param array $data 任务数据
     * @param \Exception $e 异常
     */
    public function failed($data, $e)
    {
        // 可以在这里记录失败日志
    }
}

发布任务

$job = \app\job\Mail::class;
$data = [
    'to' => '86849180@qq.com', 
    'subject' => '测试邮件',
    'message' => '门前,大桥下,游来一群鸭~~'
];
// 方式一:推送任务到队列,并立即执行
\think\facade\Queue::push($job, $data = '');

// 方式二:推送任务到队列,5 秒后执行
\think\facade\Queue::later(5, $job, $data);

// 方式三:推送任务1到队列,并立即执行
\think\facade\Queue::push($job . '@one', $data);

监听和执行任务

在终端执行

php think queue:work

调试完毕后,可以使用 Supervisor 来保持队列的进程常驻。
参考配置:

[program:queue-work]
command=php think queue:work
directory=/www/wwwroot/wsdzhwl/
user=www
priority=999
numprocs=1

可能遇到的问题

1.The migration class name "CreateJobsTable" already exists

这是之前运行过 php think queue:table,需要删除下 database/migrations

[InvalidArgumentException]
The migration class name "CreateJobsTable" already exists

16539773981.png
image.png

结语

到此结束,有什么不对的地方,欢迎评论交流。


最后的最后,还有一个福利。开发者们,欢迎您加入腾云先锋(TDP)反馈交流群,群内有丰富的活动可收获积分和成长值,兑换惊喜福利。加入方式:https://cloud.tencent.com/developer/article/1855195

我们是腾云先锋(TDP)团队,是腾讯云GTS官方组建并运营的技术开发者群体。里有最专业的开发者&客户,能与产品人员亲密接触,专有的问题&需求反馈渠道,有一群志同道合的兄弟姐妹,期待您的加入!

在 Excel 中,stdevp 是计算样本总体标准偏差的函数,它反映了相对于平均值的离散程度。但在 PHP 里是没有该函数的,要计算标准偏差时,只能自己进行写算法,十分不便。于是查询相关资料和公式,总结出了以下代码。

- 阅读剩余部分 -

为了方便给多台服务器提供文件访问能力和CDN加速能力,我选择了使用COS来储存文件。但官方提供的开机自动挂载方案感觉不大稳定,自己研究cosfs工具的使用,并配合systemctl来实现开机自动挂载。

相比官方提供的/etc/fstab挂载方案,使用systemctl来管理cosfs进程个人感觉会更稳定,因为systemctl提供了自动重启功能,即cosfs进程挂了会自动启动。

使用/etc/fstab挂载方案,如果文件修改过于频繁,挂载会掉。
两者的性能没具体测试过,但应该不会相差太大。

安装 cosfs

这里我用的是 Ubuntu 20.04,如果你的是其它系统,可以参考官方文档进行安装。

下载包

wget https://github.com/tencentyun/cosfs/releases/download/v1.0.19/cosfs_1.0.19-ubuntu20.04_amd64.deb

安装包

sudo dpkg -i cosfs_1.0.19-ubuntu20.04_amd64.deb

编辑密钥文件

sudo nano /etc/passwd-cosfs

密钥文件内容

<BucketName-APPID>:<SecretId>:<SecretKey>
<BucketName-APPID>为存储桶名称格式。
<SecretId><SecretKey> 为密钥信息,您可前往访问管理控制台的 云 API 密钥管理 中查看和创建。

修改密钥文件权限

sudo chmod 640 /etc/passwd-cosfs
sudo chown www:www /etc/passwd-cosfs
因为我挂载 cos 是给网站使用的,所以我都是用 www 用户来挂载。后面的 chown 都是这个用途

创建挂载目录

因为挂载cos时,需要被挂载的目录存在,所以我们先提前创建

sudo mkdir -p /mnt/cosfs
sudo chown www:www /mnt/cosfs

创建缓存目录

sudo mkdir -p /var/cache/cosfs
sudo chown www:www /var/cache/cosfs

编辑fuse.conf

编辑fuse配置,以允许其它用户访问挂载的文件

sudo nano /etc/fuse.conf

找到user_allow_other,如果被注释则取消注释,如果没有该配置,则新增一行配置。

user_allow_other
不设置的话,其它用户会访问不了挂载的目录
fusermount: option allow_other only allowed if 'user_allow_other' is set in /etc/fuse.conf

设置systemctl服务

编辑服务文件

sudo nano /etc/systemd/system/cosfs.service
[Unit]
Description=cosfs Service
After=network.target

[Service]
Type=simple
User=www
Group=www
Restart=on-failure
RestartSec=5s
ExecStart=cosfs -f cos-1251274180 /mnt/cosfs -ourl=http://cos.ap-guangzhou.myqcloud.com -odbglevel=info -oallow_other -ouse_cache=/var/cache/cosfs

[Install]
WantedBy=multi-user.target
cos-1251274180 为储存桶名称
/mnt/cosfs 为本地挂载目录
-ourl 为访问域名。请参见 地域和访问域名
-ogid 用户组ID
-ouid 用户ID
-ouse_cache 缓存目录

常用挂载选项

-omultipart_size=[size]
用来指定分块上传时单个分块的大小(单位: MB),默认是10MB。 由于分块上传对单个文件块的数目有最大限制(10000块),所以对于超出100GB(10MB * 10000)大小的文件,需要根据具体情况调整该参数。

-oallow_other
如果要允许其他用户访问挂载文件夹,可以在运行 COSFS 的时候指定该参数。

-odel_cache
默认情况下,COSFS 工具为了优化性能,在 umount 后,不会清除本地的缓存数据。 如果需要在 COSFS 退出时,自动清除缓存,可以在挂载时加入该选项。

-onoxattr
禁用 getattr/setxattr 功能,在1.0.9之前版本的 COSFS 不支持设置和获取扩展属性,如果在挂载时使用了 use_xattr 选项,可能会导致 mv 文件到 Bucket 失败。

-opasswd_file=[path]
该选项可以指定 COSFS 密钥文件的所在路径,该选项设定的密钥文件需要设置权限为600。

-odbglevel=[dbg|info|warn|err|crit]
设置 COSFS 日志记录级别,可选 info、dbg、warn、err 和 crit。生产环境中建议设置为 info,调试时可以设置为 dbg。如果您的系统日志,未定期清理且由于访问量很大,生成大量日志,您可以设置为 err 或者 crit。

-oumask=[perm]
该选项可以去除给定类型用户,对挂载目录内文件的操作权限。例如,-oumask=755,对应挂载目录的权限变为022。

-ouid=[uid]
该选项允许用户 id 为 [uid] 的用户不受挂载目录中文件权限位的限制,可以访问挂载目录中的所有文件。
获取用户 uid 可以使用 id 命令,格式id -u username。例如执行id -u user_00,可获取到用户 user_00 的 uid。

-oensure_diskfree=[size]
COSFS 工具为提升性能,默认使用系统盘存放上传、下载的临时缓存,文件关闭后会释放空间。在并发打开的文件数较多或者读写大文件的时候,COSFS 工具会尽量多的使用硬盘来提高性能,默认只保留 100MB 硬盘可用空间给其他程序使用,可以通过选项 oensure_diskfree=[size] 设置 COSFS 工具保留可用硬盘空间的大小,单位为 MB。例如-oensure_diskfree=1024,COSFS 工具会保留1024MB剩余空间。

启动和安装服务

此时,我们尝试下启动服务

sudo systemctl start cosfs

然后查看服务状态

sudo systemctl status cosfs

如果Active的状态是 active (running) ,则代表服务运行正常。
参考运行状态:

cosfs.service - cosfs Service
     Loaded: loaded (/etc/systemd/system/cosfs.service; disabled; vendor preset: enabled)
     Active: active (running) since Thu 2022-02-17 17:36:59 CST; 20s ago
   Main PID: 9689 (cosfs)
      Tasks: 3 (limit: 2328)
     Memory: 2.8M
     CGroup: /system.slice/cosfs.service
             └─9689 /usr/local/bin/cosfs -f cos-1251274180 /mnt/cosfs -ourl=http://cos.ap-guangzhou.myqcloud.com -odbglevel=info -ogid=1002 -ouid=1002 -ouse_cache=/tmp/cosfs

Feb 17 17:36:59 VM-8-16-ubuntu systemd[1]: cosfs.service: Scheduled restart job, restart counter is at 37.
Feb 17 17:36:59 VM-8-16-ubuntu systemd[1]: Stopped cosfs Service.
Feb 17 17:36:59 VM-8-16-ubuntu systemd[1]: Started cosfs Service.
Feb 17 17:36:59 VM-8-16-ubuntu s3fs[9689]: [tid:9689]s3fs.cpp:main(5001): init v1.0.19(commit:unknown) with OpenSSL

那我们就可以直接启用服务了,那么服务就会开机时自动启动。

sudo systemctl enable cosfs

如果状态不正常,请看后面的调试服务

链接文件

需要挂载cos中的某个文件或目录到网站中的话,我们可以使用软链接来进行。
如:挂载cos中的files目录到网站目录中/www/wwwroot/default,则可以使用以下命令

sudo ln -s /mnt/cosfs/files /www/wwwroot/default/files
sudo chown -h www:www /www/wwwroot/default/files

调试服务

如果服务不能正常运行,可以使用命令查看服务运行日志,再根据日志信息去调整配置和服务。

journalctl -f -u cosfs.service

如果修改了服务,需要重新加载服务然后重启服务才会生效

sudo systemctl daemon-reload
sudo systemctl restart cosfs

cosfs 工具帮助

cosfs -h
用法: cosfs BUCKET:[PATH] MOUNTPOINT [OPTION]...

挂载腾讯云 COS 储存桶作为文件系统.

   cosfs 和 FUSE/mount 的常规选项:
      -o opt[,opt...]
      -o opt [-o opt] ...

cosfs 选项:

   大多数 cosfs 选项以"opt"的形式给出:

             <option_name>=<option_value>

   default_acl (默认="public-read")
     - 应用所有写入cos对象时的默认acl

   retries (默认="2")
      -  cos 事务失败时的重试次数

   use_cache (默认="" 即禁用缓存)
      - 用于本地文件缓存的本地文件夹

   del_cache (删除本地文件缓存)
      - cosfs启动和退出时删除本地文件缓存

   storage_class (默认="standard")
      - 使用指定的存储类存储对象.  可能的值:
        standard, standard_ia, 和 reduced_redundancy.

   public_bucket (默认="" 即禁用)
      - 设置为 1 时,匿名挂载公共存储桶

   passwd_file (默认="")
      - 指定要使用的 cosfs 密码文件

   connect_timeout (默认="300" 秒)
      - 连接等待超时时间

   readwrite_timeout (默认="60" 秒)
      - 读写等待超时时间

   max_stat_cache_size (默认="1000" 个 (约 4MB))
      - 文件元数据的缓存空间可缓存多少个文件的元数据

   stat_cache_expire (默认不过期)
      - 指定文件元数据缓存的过期时间(秒)

   enable_noobj_cache (默认禁用)
      - enable cache entries for the object which does not exist.
      cosfs always has to check whether file(or sub directory) exists 
      under object(path) when cosfs does some command, since cosfs has 
      recognized a directory which does not exist and has files or 
      sub directories under itself. It increases ListBucket request 
      and makes performance bad.
      You can specify this option for performance, cosfs memorizes 
      in stat cache that the object(file or directory) does not exist.

   no_check_certificate
      - server certificate won't be checked against the available 
      certificate authorities.

   nodnscache (禁用DNS缓存)
      - cosfs is always using dns cache, this option make dns cache disable.

   nosscache (禁用SSL会话缓存)
      - cosfs is always using ssl session cache, this option make ssl 
      session cache disable.

   multireq_max (默认="20")
      - maximum number of parallel request for listing objects.

   parallel_count (默认="5")
      - number of parallel request for uploading big objects.
      cosfs uploads large object(over 20MB) by multipart post request, 
      and sends parallel requests.
      This option limits parallel request count which cosfs requests 
      at once. It is necessary to set this value depending on a CPU 
      and a network band.

   multipart_size (默认="10")
      - part size, in MB, for each multipart request.

   ensure_diskfree (默认与 multipart_size 的值相同)
      - sets MB to ensure disk free space. cosfs makes file for
        downloading, uploading and caching files. If the disk free
        space is smaller than this value, cosfs do not use diskspace
        as possible in exchange for the performance.

   singlepart_copy_limit (默认="5120")
      - maximum size, in MB, of a single-part copy before trying 
      multipart copy.

   url (默认="")
      - sets the url to use to access tencentyun cos

   default_permission (默认=777)
      - when the file do not have permission meta, cosfs will use this 
      defalut value.

   endpoint (默认="")
      - sets the endpoint to use on signature version 4
      If the cosfs could not connect to the region specified
      by this option, cosfs could not run. But if you do not specify this
      option, and if you can not connect with the default region, cosfs
      will retry to automatically connect to the other region. So cosfs
      can know the correct region name, because cosfs can find it in an
      error from the COS server.

   mp_umask (默认为 "0000")
      - sets umask for the mount point directory.
      If allow_other option is not set, cosfs allows access to the mount
      point only to the owner. In the opposite case cosfs allows access
      to all users as the default. But if you set the allow_other with
      this option, you can control the permissions of the
      mount point by this option like umask.

   nomultipart (禁用分段上传)

   enable_content_md5 (默认禁用)
      - ensure data integrity during writes with MD5 hash.


   nocopyapi (for other incomplete compatibility object storage)
        For a distributed object storage which is compatibility COS
        API without PUT(copy api).
        If you set this option, cosfs do not use PUT with 
        "x-cos-copy-source"(copy api). Because traffic is increased
        2-3 times by this option, we do not recommend this.

   norenameapi (for other incomplete compatibility object storage)
        For a distributed object storage which is compatibility COS
        API without PUT(copy api).
        This option is a subset of nocopyapi option. The nocopyapi
        option does not use copy-api for all command(ex. chmod, chown,
        touch, mv, etc), but this option does not use copy-api for
        only rename command(ex. mv). If this option is specified with
        nocopyapi, then cosfs ignores it.

   use_path_request_style (use legacy API calling style)
        Enble compatibility with OSS-like APIs which do not support
        the virtual-host request style, by using the older path request
        style.

   dbglevel (默认="crit")
        Set the debug message level. set value as crit(critical), err
        (error), warn(warning), info(information) to debug level.
        default debug level is critical. If cosfs run with "-d" option,
        the debug level is set information. When cosfs catch the signal
        SIGUSR2, the debug level is bumpup.

   curldbg - put curl debug message
        Put the debug message from libcurl when this option is specified.

FUSE/mount 选项:

   Most of the generic mount options described in 'man mount' are
   supported (ro, rw, suid, nosuid, dev, nodev, exec, noexec, atime,
   noatime, sync async, dirsync).  Filesystems are mounted with
   '-onodev,nosuid' by default, which can only be overridden by a
   privileged user.
   
   There are many FUSE specific mount options that can be specified.
   e.g. allow_other  See the FUSE's README for the full set.

其它选项:

 -h, --help        输出帮助信息.
     --version     输出版本信息.
 -d  --debug       开启系统日志的调试消息。 指定 -d 两次会启用 FUSE 调试消息到 STDOUT。
 -f                FUSE 前台选项 - 不要作为守护程序运行
 -s                FUSE 单线程选项(禁用多线程操作)

参考链接