Postwoman是一款开源的 Postman 替代品

介绍

Postwoman是一款开源的 Postman 替代品:

  • 轻盈,可直接在线访问;
  • 简约,采用简约的 UI 设计精心打造;
  • 支持 GET, HEAD, POST, PUT, DELETE, OPTIONS, PATCH 方法;
  • 支持验证;
  • 实时,发送请求即可获取响应。

体验demo:postwoman.io

 Github

https://github.com/liyasthomas/postwoman
1584940378-5696-59de05539e1adfdb42d989f-720w

 功能

先来看看它支持的功能列表:

  • 💚 开源
  • 🔥 运行在浏览器端
  • 🚀 支持多平台、多设备
  • 📱 支持PWA
  • 🔌 WebSocket 测试
  • 🌈 定制化
  • ⏰ 历史记录
  • 📁 集合
  • 🌐 代理
  • 📜 请求前脚本和环境变量
  • 🐳 Docker

使用

git clone https://github.com/liyasthomas/postwoman.git
npm install
npm run dev

//打开浏览器即可
//或者,使用docker-compose:

#pull
docker pull liyasthomas/postwoman
#run
docker run -p 3000:3000 liyasthomas/postwoman:latest
#build
docker build -t postwoman:latest

# 界面截图

几个常用的快捷键:

发送请求:ctrl+G

保存到收藏夹:ctrl+S

复制请求链接:ctrl+K

重置请求链接:ctrl+L

PHP实现zip压缩的代码

直接上代码

/**
 * Class xZip
 *
 * $xZip = new xZip;
 * $xZip->zip(null, 'D:/www/log/index.php', 'D:/www/log/index.zip');
 * $xZip->zipAll(array('D:/www/log/index.php','D:/www/log/lottery.sql'),  'D:/www/log/index_all.zip');
 *
 */
class xZip
{
    public function __construct()
    {
    }


    /**
     * add multi file to ZIP file
     * @param array $source will be add to ZIP file list.
     * @param null $destination ZIP file path
     * @return null $destination
     * @throws Exception
     */
    public function zipAll($source = array(), $destination = null, $originPath = '')
    {
        if ($destination == null) {
            throw new Exception('param $destination must be not null.');
        }
        if (count($source) == 0) {
            throw new Exception('must be added one file.');
        }
        $zip = new ZipArchive;
        @mkdir($this->getParentPath($destination), 0777, true);
        $res = $zip->open($destination, ZipArchive::CREATE);
        if ($res != true) {
            throw new Exception('open zip(' . $destination . ') file error[' . $res . '].');
        }
        foreach ($source as $path) {
            $zip->addFile($path, iconv('UTF-8', 'GB2312', str_replace($originPath, NULL, $path)));
        }
        $zip->close();
        return $destination;
    }

    /**
     * add one file to ZIP file.
     * @param null $zip @ZipArchive object
     * @param null $source will be add to ZIP file.
     * @param null $destination dest ZIP file.
     * @return null $destination
     * @throws Exception
     */
    public function zip($zip = null, $source = null, $destination = null)
    {
        if ($destination == null) {
            throw new Exception('param $destination must be not null.');
        }
        if ($source == null) {
            throw new Exception('must be added one file.');
        }
        if ($zip == null) {
            $zip = new ZipArchive;
            @mkdir($this->getParentPath($destination), 0777, true);
            $res = $zip->open($destination, ZipArchive::CREATE);
            if ($res != true) {
                throw new Exception('open zip(' . $destination . ') file error[' . $res . '].');
            }
        }
        //iconv('UTF-8','GB2312',str_replace($this->getParentPath($source).'/', NULL, $source)
        $zip->addFile($source, str_replace($this->getParentPath($source) . '/', NULL, $source));
        $zip->close();
        return $destination;
    }

    /**
     * @param $source zip file path
     * @param $destination dest directory path
     */
    public function unzip($source, $destination)
    {
        @mkdir($destination, 0777, true);
        $zip = new ZipArchive;
        if ($zip->open($source) === true) {
            $zip->extractTo($destination);
            $zip->close();
        }
    }

    public function __destruct()
    {
    }

    private function getParentPath($destination)
    {
        $path = substr($destination, 0, strripos($destination, '/'));
        return $path;
    }
}

PHP实现文件下载

简单的示例代码:

function downloadFile($filePath)
{

    set_time_limit(0);

    if (substr($filePath, strlen($filePath) - 1) == '/') {
        $filePath = substr($filePath, 0, strlen($filePath) - 1);
    }

    if (!is_file($filePath) && !is_readable($filePath)) {
        return false;
    }
    $obj = new SplFileInfo($filePath);
    header('Content-Type: application/octet-stream');
    header('Accept-Ranges:bytes');
    header('Content-Length:' . filesize($filePath)); //注意是'Content-Length:' 非Accept-Length
    header('Content-Disposition:attachment;filename=' . $obj->getFilename());//声明作为附件处理和下载后文件的名称

    $buffer = 1024;
    ob_clean();
    $handle = fopen($filePath, 'rb');
    while (!feof($handle)) {
        echo fread($handle, $buffer);
    }
    flush();
    fclose($handle);
    exit;

}

主要是设置header头:

文件类型:Content-Type: application/octet-stream

字节流:Accept-Ranges:bytes

长度:Content-Length:>0

声明作为附件处理和下载后文件的名称:

Content-Disposition:attachment;filename=FILENAME

 

*最重要的是 ob_clean();跟flush();

如果没有这两个函数,有可能下载下来的文件就是损坏的。

OOM Killer可能会导致Linux无故被杀掉

oom-killer

OOM Killer –如何在Linux中创建OOM排除项

当Linux机器上运行内存不足的内核将开始杀死进程以free up ram。这就是所谓的OOM杀手。OOM代表内存不足。不幸的是,Linux内核OOM杀手通常会杀死重要的进程。在许多情况下,一旦OOM杀手将其丑陋的头抬起,我的系统就会完全被软管塞住。幸运的是,您可以通过提供pid数字列表来告诉内核不要OOM杀死某些进程。如果您运行的系统内存压力很大,并且想确保重要进程(例如sshd)永远不会被杀死,那么这些选项可能对您有用。

告诉OOM杀手忽略一个进程

禁用OOM杀手是逐个进程完成的,因此您需要知道要保护的正在运行的进程的PID。这远非理想,因为进程ID可以经常更改,但是我们可以编写脚本。

http://linux-mm.org/OOM_Killer所述:“如果将/proc/{$PID}/oom_adj的值设置为常量OOM_DISABLE(当前定义为- 17)。”

这意味着,如果我们知道OOM杀手的PID,可以使用以下命令在单个进程上禁用它:

echo -17 > /proc/$PID/oom_adj

使用pgrep,我们可以只知道进程名称来运行它。例如,让我们确保ssh侦听器不会杀死OOM:

pgrep -f "/usr/sbin/sshd" | while read PID; do echo -17 > /proc/$PID/oom_adj; done

在这里,我们使用pgrep搜索匹配“ / usr / sbin / sshd”的完整命令行(-f),然后为每个匹配的pid将-17回显到procfs条目中。

为了自动执行此操作,您可以定期运行cron以更新oom_adj条目。这是确保在重新启动守护程序或服务器后,将sshd从OOM杀手中排除的简单方法。

*/1 * * * * root pgrep -f “/usr/sbin/sshd” | while read PID; do echo -17 > /proc/$PID/oom_adj; done

上面的作业将每分钟运行一次,更新与/ usr / sbin / sshd匹配的当前进程的oom_adj。当然,可以将其扩展为包括您希望从OOM杀手中排除的任何其他进程。

我建议在单个进程级别禁用OOM杀手,而不是在系统范围内将其关闭。完全禁用OOM Killer将导致您的系统在沉重的内存压力下陷入内核恐慌。通过排除关键的管理过程,您至少应该能够登录以解决高内存使用问题。

那怎么判断进程是不是被OOM Killer给干掉了呢?

可以从 /var/log/messages 这个日志查看,是否有abrt或kill之间的信息,如下日志:

[root@centos157 log]# cat messages-20200223
Feb 16 03:33:01 centos157 rsyslogd: [origin software=”rsyslogd” swVersion=”5.8.10″ x-pid=”1108″ x-info=”http://www.rsyslog.com”] rsyslogd was HUPed
Feb 16 15:39:29 centos157 abrt[26449]: Saved core dump of pid 23145 (/usr/lib/jvm/jdk1.8.0_171/bin/java) to /var/spool/abrt/ccpp-2020-02-16-15:38:35-23145 (998699008 bytes)
Feb 16 15:39:29 centos157 abrtd: Directory ‘ccpp-2020-02-16-15:38:35-23145′ creation detected
Feb 16 15:39:29 centos157 abrtd: Executable ‘/usr/lib/jvm/jdk1.8.0_171/bin/java’ doesn’t belong to any package and ProcessUnpackaged is set to ‘no’
Feb 16 15:39:29 centos157 abrtd: ‘post-create’ on ‘/var/spool/abrt/ccpp-2020-02-16-15:38:35-23145′ exited with 1
Feb 16 15:39:29 centos157 abrtd: Deleting problem directory ‘/var/spool/abrt/ccpp-2020-02-16-15:38:35-23145′
Feb 22 18:31:49 centos157 abrt[31071]: Saved core dump of pid 8707 (/usr/lib/jvm/jdk1.8.0_171/bin/java) to /var/spool/abrt/ccpp-2020-02-22-18:31:32-8707 (694501376 bytes)
Feb 22 18:31:49 centos157 abrtd: Directory ‘ccpp-2020-02-22-18:31:32-8707′ creation detected
Feb 22 18:31:49 centos157 abrtd: Executable ‘/usr/lib/jvm/jdk1.8.0_171/bin/java’ doesn’t belong to any package and ProcessUnpackaged is set to ‘no’
Feb 22 18:31:49 centos157 abrtd: ‘post-create’ on ‘/var/spool/abrt/ccpp-2020-02-22-18:31:32-8707′ exited with 1
Feb 22 18:31:49 centos157 abrtd: Deleting problem directory ‘/var/spool/abrt/ccpp-2020-02-22-18:31:32-8707′