最近在做cgi响应时间优化。发现其中一个点是在读取系统用户信息的时候,比较慢,需要5ms级别。
其中一个是,获取用户所有组getgrouplist(),strace发现,它并没有去读取/etc/group,而是走了systemd的接口。
connect(4, {sa_family=AF_UNIX, sun_path="/run/systemd/userdb/io.systemd.DynamicUser"}, 45) = 0
epoll_create1(EPOLL_CLOEXEC) = 5
timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC|TFD_NONBLOCK) = 6
timerfd_settime(6, TFD_TIMER_ABSTIME, {it_interval={tv_sec=0, tv_nsec=0}, it_value={tv_sec=71785, tv_nsec=34376000}}, NULL) = 0
epoll_pwait2(5, [{events=EPOLLOUT, data={u32=1826926800, u64=366899146960}}, {events=EPOLLOUT, data={u32=1826927824, u64=366899147984}}], 16, {tv_
sec=0, tv_nsec=0}, NULL, 8) = 2
sendto(4, "{\"method\":\"io.systemd.UserDataba"..., 139, MSG_DONTWAIT|MSG_NOSIGNAL, NULL, 0) = 139
epoll_ctl(5, EPOLL_CTL_MOD, 4, {events=EPOLLIN, data={u32=1826926800, u64=366899146960}}) = 0
epoll_pwait2(5, [{events=EPOLLIN, data={u32=1826926800, u64=366899146960}}, {events=EPOLLOUT, data={u32=1826927824, u64=366899147984}}], 16, {tv_s
ec=0, tv_nsec=0}, NULL, 8) = 2
sendto(7, "{\"method\":\"io.systemd.UserDataba"..., 134, MSG_DONTWAIT|MSG_NOSIGNAL, NULL, 0) = 134
epoll_ctl(5, EPOLL_CTL_MOD, 7, {events=EPOLLIN, data={u32=1826927824, u64=366899147984}}) = 0
epoll_pwait2(5, [{events=EPOLLIN, data={u32=1826926800, u64=366899146960}}], 16, {tv_sec=0, tv_nsec=0}, NULL, 8) = 1
recvfrom(4, "{\"error\":\"io.systemd.UserDatabas"..., 131080, MSG_DONTWAIT, NULL, NULL) = 66
epoll_ctl(5, EPOLL_CTL_MOD, 4, {events=0, data={u32=1826926800, u64=366899146960}}) = 0
epoll_pwait2(5, [], 16, {tv_sec=0, tv_nsec=0}, NULL, 8) = 0
epoll_pwait2(5, [{events=EPOLLIN, data={u32=1826927824, u64=366899147984}}], 16, {tv_sec=0, tv_nsec=0}, NULL, 8) = 1
epoll_ctl(5, EPOLL_CTL_DEL, 4, NULL) = 0
close(4) = 0
epoll_pwait2(5, [{events=EPOLLIN, data={u32=1826927824, u64=366899147984}}], 16, {tv_sec=0, tv_nsec=0}, NULL, 8) = 1
recvfrom(7, "{\"error\":\"io.systemd.UserDatabas"..., 131080, MSG_DONTWAIT, NULL, NULL) = 66
epoll_ctl(5, EPOLL_CTL_MOD, 7, {events=0, data={u32=1826927824, u64=366899147984}}) = 0
epoll_pwait2(5, [], 16, {tv_sec=0, tv_nsec=0}, NULL, 8) = 0
epoll_pwait2(5, [], 16, {tv_sec=0, tv_nsec=0}, NULL, 8) = 0 研究发现,这格式nss的一个功能。nss可以配置走不同的系统。
# cat /etc/nsswitch.conf # /etc/nsswitch.conf # # Example configuration of GNU Name Service Switch functionality. # If you have the `glibc-doc' and `info' packages installed, try: # `info libc "Name Service Switch"' for information about this file. passwd: compat systemd group: compat systemd shadow: compat systemd hosts: files myhostname mdns mdns4_minimal [NOTFOUND=return] dns networks: files protocols: db files services: db files ethers: db files rpc: db files netgroup: nis
passwd和group配置了systemd,它有插件机制,会去打开/lib/libnss_systemd.so.2
参考:
https://man7.org/linux/man-pages/man5/nsswitch.conf.5.html
https://man7.org/linux/man-pages/man8/nss-systemd.8.html