nest.js 使用 node-http-proxy 导致请求阻塞

问题的原因是代理中间件与body-parser中间件发生了冲突。请求体的解析如果在转发之前,那么后端服务将会收不到请求结束的消息,导致请求一直 pending。

nest默认是启用body-parser的,需要在初始化时将其关闭。
const app = await NestFactory.create(AppModule, { bodyParser: false });

然后需要为不需要代理的请求添加body-parser中间件。body-parser包括了json,urlencoded和text的解析,根据情况按需引用。

const unless = (path, middleware) => (req, res, next) => {
  if (req.path.indexOf(path) !== -1) {
    return next();
  } else {
    return middleware(req, res, next);
  }
};


app.use(unless('/db', json()));
app.use(unless('/db', urlencoded({ extended: false })));

编译 php 提示 cURL 找不到

问题:
确定机器已经安装curl,而且通过--with-curl=指定路径也不管用。错误信息如下:

checking for cURL 7.10.5 or greater... configure: error: cURL version 7.10.5 or later is required to compile php with cURL support

解决方法:
这些都不允许您在启用cURL的情况下编译PHP。

要使用cURL进行编译,需要libcurl头文件(.h文件)。 它们通常位于/usr/include/curl中。 它们通常捆绑在一个单独的开发包中。

例如,在Ubuntu中安装libcurl

sudo apt-get install libcurl4-gnutls-dev
或CentOS:

sudo yum install curl-devel
然后你可以这样做:

./configure --with-curl #其他选项......
如果手动编译cURL,则可以指定不带lib或include后缀的文件的路径。 (例如:/usr/local如果cURL标题位于/usr/local/include/curl中)。

原文地址:Compiling php with curl, where is curl installed?

fail2ban 配置

我们先要了解一些名词:
过滤器:过滤器定义了一个正则表达式,它必须匹配与登录失败或任何其他表达式相对应的模式
动作:一个动作定义了几个在不同时刻执行的命令
监狱:监狱是一个过滤器和一个或多个行动的组合。Fail2ban可以同时处理几个监狱。

配置

/etc/fail2ban目录如下:

/etc/fail2ban/
├── action.d
│   ├── dummy.conf
│   ├── hostsdeny.conf
│   ├── iptables.conf
│   ├── mail-whois.conf
│   ├── mail.conf
│   └── shorewall.conf
├── fail2ban.conf
├── fail2ban.local
├── filter.d
│   ├── apache-auth.conf
│   ├── apache-noscript.conf
│   ├── couriersmtp.conf
│   ├── postfix.conf
│   ├── proftpd.conf
│   ├── qmail.conf
│   ├── sasl.conf
│   ├── sshd.conf
│   └── vsftpd.conf
├── jail.conf
└── jail.local

每个.conf文件都可以用名为.local的文件覆盖。 .conf文件首先被读取,然后是.local,稍后的设置将覆盖较早的设置。 因此,.local文件不必在相应的.conf文件中包含所有内容,只包含那些您希望覆盖的设置。修改应该在.local中进行,而不是在.conf中进行。 这避免了升级时的合并问题。 这些文件都有详细的文档记录,并且应该有详细的信息。

Jails

[ssh-iptables]
#enabled  = false
enabled  = true
filter   = sshd
action   = iptables[name=SSH, port=ssh, protocol=tcp]
#          mail-whois[name=SSH, [email protected]]
#logpath  = /var/log/sshd.log
logpath  = /var/log/auth.log
maxretry = 5

每个监狱只允许使用一个过滤器,但可以在单独的行上指定多个动作。 例如,您可以首先添加一个新的防火墙规则,然后使用whois检索有关违规主机的一些信息,最后发送电子邮件通知,从而对SSH闯入企图做出反应。

Filters

目录filter.d主要包含正则表达式,用于检测破解企图,密码失败等。下面是filter.d/sshd.conf的一个示例,其中包含3个可能的正则表达式以匹配日志文件的行:

failregex = Authentication failure for .* from <HOST>
            Failed [-/\w]+ for .* from <HOST>
            ROOT LOGIN REFUSED .* FROM <HOST>
            [iI](?:llegal|nvalid) user .* from <HOST>

Actions

目录action.d包含定义动作的不同脚本。 这些动作在执行Fail2ban期间的明确时刻执行:启动/停止监狱,禁止/解除主机等。

https://www.fail2ban.org/wiki/index.php/MANUAL_0_8#Configuration

TCP层的keepalive与HTTP层的Keep-Alive

TCP的keepalive

网络两端通过三次握手建立好TCP连接,如果这个连接一直处于闲置状态即没有数据往来,我们就需要在一定时间之后检测对方是否还在。如果不在就需要及时关闭这个连接,避免浪费系统资源,这就是TCP层面的keepalive机制。

我们可以通过以下命令查看内核参数:

$ cat /proc/sys/net/ipv4/tcp_keepalive_time
  7200
$ cat /proc/sys/net/ipv4/tcp_keepalive_intvl
  75
$ cat /proc/sys/net/ipv4/tcp_keepalive_probes
  9

当tcp发现有tcp_keepalive_time(7200)秒未收到对端数据后,开始以间隔tcp_keepalive_intvl(75)秒的频率发送的空心跳包,如果连续tcp_keepalive_probes(9)次以上未响应,关闭连接。

Nginx配置tcp keepalive

so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]

HTTP层的Keep-Alive

HTTP层的Keep-Alive表示长连接(persistent connection)。

HTTP_persistent_connection.png

如上图所示,短链接在发送完一个响应后,会马上关闭相应的tcp连接,而长连接在一个http产生的tcp连接在传送完最后一个响应后,还需要等待keepalive_timeout秒,才开始关闭这个连接。如果这段时间内还有其他请求那就还使用此tcp连接。但是,keep-alive也不能设置过长,长时间的tcp连接容易导致系统资源无效占用。
在HTTP/1.0里,必须在HTTP请求头里显示指定Connection:keep-alive,而在HTTP/1.1里,keep-alive是默认开启的。

Nginx HTTP层的keepalive配置有:

keepalive_timeout timeout [header_timeout];
keepalive_requests number;

总结

HTTP层的keep-alive是为了让tcp活得更久一点,以便在同一个连接上传送多个http,提高socket的效率。而TCP层的keepalive是一种检测TCP连接状况的保鲜机制。当nginx的keepalive_timeout值设置高于tcp_keepalive_time,并且距此TCP连接传输的最后一个HTTP响应,经过了tcp_keepalive_time时间之后,操作系统才会发送侦测包来决定是否要丢弃这个TCP连接。

数据库范式

范式(Normal Form)这个名词不好理解,你可以把数据库范式当作一种标准,就像电器的节能等级一样,范式越高,磁盘的冗余越少,满足高等级的范式的先决条件是满足低等级范式。

  • 1NF:所有的属性均有原子性(字段为最小单元不能再分,关系数据库一定满足第一范式)
  • 2NF:满足1NF,表中的字段必须完全依赖于全部主键而非部分主键 (要有主键)
  • 3NF:满足2NF,非主键外的所有字段必须互不依赖(没有冗余数据)
  • BCNF:满足2NF和3NF,BC范式是在第三范式的基础上的一种特殊情况,既每个表中只有一个候选键(在一个数据库中每行的值都不相同,则可称为候选键)。判断方法:箭头左边的必须是候选码,不是候选码的就不是BC范式。