如何验证 ulimit 中的资源限制?如何查看当前使用量?

ulimit 可以限制进程的资源使用量。在设置 ulimit 之后,如何验证各个资源限制是有效的?如何查看每个进程当前使用了多少资源?本文将尝试对多个设定值进行演示。

ulimit 的设定,是 per-user 的还是 per-process 的?

我们从 ulimit 中看到的设定值,都是 per-process 的。也就是说,每个进程有自己的 limits 值。

$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 46898
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 65536
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 46898
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

ulimit, limits.conf 和 pam_limits 的关系?

首先,limit的设定值是 per-process 的。在 Linux 中,每个普通进程可以调用 getrlimit() 来查看自己的 limits,也可以调用 setrlimit() 来改变自身的 soft limits。 而要改变 hard limit, 则需要进程有 CAP_SYS_RESOURCE 权限。另外,进程 fork() 出来的子进程,会继承父进程的 limits 设定。具体可参考 getrlimit/setrlimit/prlimit 的手册。

`ulimit` 是 shell 的内置命令。在执行`ulimit`命令时,其实是 shell 自身调用 getrlimit()/setrlimit() 来获取/改变自身的 limits. 当我们在 shell 中执行应用程序时,相应的进程就会继承当前 shell 的 limits 设定。

那么一个 shell 的初始 limits 是谁设定的? 通常是 pam_limits 设定的。顾名思义,pam_limits 是一个 PAM 模块,用户登录后,pam_limits 会给用户的 shell 设定在 limits.conf 定义的值。我们可以开启 pam_limits 的 debug 来查看大致过程:

[root@rhel674 ~]# cat /etc/security/limits.conf | grep -v ^# | grep -v ^$
test        hard    memlock         102410

[root@rhel674 ~]# grep pam_limits /etc/pam.d/password-auth-ac
session     required      pam_limits.so debug

[root@rhel674 ~]# tail /var/log/secure
Sep  4 00:12:49 rhel674 sshd[3151]: Accepted publickey for test from 192.168.122.1 port 41556 ssh2
Sep  4 00:12:49 rhel674 sshd[3151]: pam_limits(sshd:session): reading settings from '/etc/security/limits.conf'
Sep  4 00:12:49 rhel674 sshd[3151]: pam_limits(sshd:session): process_limit: processing hard memlock 102410 for USER
Sep  4 00:12:49 rhel674 sshd[3151]: pam_limits(sshd:session): reading settings from '/etc/security/limits.d/90-nproc.conf'
Sep  4 00:12:49 rhel674 sshd[3151]: pam_limits(sshd:session): process_limit: processing soft nproc 1024 for DEFAULT
Sep  4 00:12:49 rhel674 sshd[3151]: pam_unix(sshd:session): session opened for user test by (uid=0)

在 limits.conf 中,对 test 用户设定 memlock 的 hard limit 为 102410. 当用户通过 SSH 登录后,可以看到 pam_limits 为该会话设定了 memlock=102410.
继续阅读“如何验证 ulimit 中的资源限制?如何查看当前使用量?”

/proc/interrupts 的数值是如何获得的?

之前为了确认 /proc/interrupts 文件第一列的缩进方式,看了一下相关源码,在这里做一些记录。

系统一共有多少个中断?

系统可用的中断数量主要由架构决定,x86 的具体数量可以参考以下定义。

/* kernel/irq/irqdesc.c */

 96 int nr_irqs = NR_IRQS;
 97 EXPORT_SYMBOL_GPL(nr_irqs);
/* arch/x86/include/asm/irq_vectors.h */

152 #define NR_IRQS_LEGACY            16
153    
154 #define IO_APIC_VECTOR_LIMIT        ( 32 * MAX_IO_APICS )
155    
156 #ifdef CONFIG_X86_IO_APIC
157 # define CPU_VECTOR_LIMIT       (64 * NR_CPUS)
158 # define NR_IRQS                    \
159     (CPU_VECTOR_LIMIT > IO_APIC_VECTOR_LIMIT ?  \
160         (NR_VECTORS + CPU_VECTOR_LIMIT)  :  \
161         (NR_VECTORS + IO_APIC_VECTOR_LIMIT))
162 #else /* !CONFIG_X86_IO_APIC: */
163 # define NR_IRQS            NR_IRQS_LEGACY
164 #endif

继续阅读“/proc/interrupts 的数值是如何获得的?”

使用 Pacemaker 搭建集群服务

背景

对于一些重要应用,我们希望实现高可用(High-Availability). 在 RHEL7 中,可以使用 Pacemaker 达到这样的效果。

Pacemaker 是一个集群资源管理器,它负责管理集群环境中资源(服务)的整个生命周期。除了传统意义上的 Active/Passive 高可用,Pacemaker 可以灵活管理各节点上的不同资源,实现如 Active/Active,或者多活多备等架构。

下图是一个经典的 Active/Passive 高可用例子, Host1/Host2 只有一台服务器在提供服务,另一台服务器作为备机时刻准备着接管服务。

Pacemaker Active Passive
Pacemaker Active Passive

为了节省服务器资源,有时候可以采取 Shared Failover 的策略,两台服务器同时提供不同的服务,留有一台备用服务器接管失效的服务。

Pacemaker Shared Failover
Pacemaker Shared Failover

通过共享文件系统如 GFS2,也可以实现 Active/Active 的多活形式。

Pacemaker Active Active
Pacemaker Active Active

继续阅读“使用 Pacemaker 搭建集群服务”

Where will log goes during logrotate.

During logroate, if there comes a log entry, where will this log entry goes? To the rotated file, lost, or to the newly created file?

It depends.

The logrotate process

In RHEL 6 (centos 6), logrotate works like below:

1. Rename the original file. For example, /var/log/messages --> /var/log/messages.1

2. Create a new file. In this example, create an empty /var/log/messages

3. Run post-rotate script. For rsyslog, it would send a HUP signal to rsyslogd.

继续阅读“Where will log goes during logrotate.”

Socket listen() backlog 是什么?

listen() backlog 是什么?

1. Linux 服务器上的一些程序会监听特定端口.

2. 当有 client 连接到服务器的相应端口,进行完 tcp 三次握手之后,相应的连接会放到服务器相应 socket 的队列,等待服务器的应用程序调用 accept() 来读取这个连接;

3. 这个队列的长度,就是 listen() backlog.

以 apache httpd 为例。

1. httpd 会监听 80 端口;

2. 当有用户端连接到服务器的 80 端口,首先会进行 tcp 的三次握手。进行完三次握手后,这个连接会被放到 80 端口这个 socket 的队列里,等待 httpd 去获取这个连接;

3. httpd 随后会调用 accept() 来获取这个连接。这个连接被获取之后,会从这个队列里移除;

4. 这个监听 80 端口的 socket 对应的队列长度,就是 listen() backlog.
继续阅读“Socket listen() backlog 是什么?”

如何使用 Linux 中的 TCP keepalive?

tcp-keepalive 是什么

1. tcp-keepalive,顾名思义,它可以尽量让 TCP 连接“活着”,或者让一些对方无响应的 TCP 连接“宣告死亡”。

2. 一些特定环境,防火墙会自动断开长期无活动的 TCP 连接,tcp-keepalive 可以在连接无活动一段时间后,发送一个空 ack,使 TCP 连接不会被防火墙关闭。

3. 一些时候,对方的服务器可能出现宕机或者网络中断等问题, tcp-keepalive 可以帮助断开这些无响应的连接。

4. tcp-keepalive 需要在应用程序层面针对其所用到的 Socket 进行开启。操作系统层面无法强制所有 socket 启用 tcp-keepalive. (本文在 CentOS/RHEL 6/7 环境进行测试)

继续阅读“如何使用 Linux 中的 TCP keepalive?”

微信/支付宝的条码支付是如何验证账户的?安全吗?

请留意:本文所述的方法仅是经过资料收集和讨论所提出的一种原理假设,并非微信/支付宝官方披露的具体方法。

疑问

在信息时代,路边摊都能接受支付宝付款。于是,我一直有个疑问。

1. 微信/支付宝/Paypal 的条形码支付/二维码支付是如何实现的?它们安全吗?

2. 为什么用户不需要联网,也能完成支付?

条形码/二维码支付的特点

二维码支付主要有“用户扫码”和“商家扫码”(反扫)两种。“用户扫码”是商家提供二维码,用户手机客户端扫码,确认购物信息后进行支付。“商家扫码”(“刷卡支付”)则是用户出示二维码,商户扫描该二维码进行扣款。

“用户扫码”的二维码实际是个购物网站的链接,扫描后的流程与我们通常的网上购物差异不大。

“商家扫码”(“刷卡支付”)则是由用户的手机客户端生成一串“支付码”(如下图),商家读取支付码后,交由支付网关进行清算。据观察,它有如下特点:

1. 用户的手机客户端不需要联网,即可生成支付码并完成交易(第一次使用时,需要联网验证支付密码,来开启扫码支付功能);

2. 这串18位的支付码是动态变化的,大约30秒动态变化一次。

本文将探讨“商家扫码”(“刷卡支付”)背后的原理。

1600126017

继续阅读“微信/支付宝的条码支付是如何验证账户的?安全吗?”