Published on

2023 Dec Weekly Report 1

Authors
  • avatar
    Name
    Sunway
    Twitter

工作

Nginx URI 异常

要部署一个前端项目在nginx上,部署后用域名请求发现请求全部 400,又是抓包又是看日志排查了好久,其实问题很简单

错误的location
location /test {
      proxy_set_header Host $host;
      proxy_pass https://alb-xxx.cn-hongkong.alb.aliyuncs.com:8443;
}
正确的location,在URI的最后有一个/(也可以在ALB重写URIlocation /test/ {
      proxy_set_header Host $host;
      proxy_pass https://alb-xxx.cn-hongkong.alb.aliyuncs.com:8443;
}

可惜我脑子,明明以前遇到过相同的问题,这次又排查了好长时间

容灾演练

核心业务部署在同地域不同机房,演练内容包括:先下线zoneB验证zoneC是否能独立承载业务;验证完成后;拉起zoneB,下线zoneC,验证zoneB是否能独立承载业务

本来架构设计的就是跨可用区双活,理论上是完全没问题的,本来以为是走个过场很快结束,但真正实操是还是暴露了很多问题:

  • nginx upstream健康检查插件失效,导致流量转发到下线了的服务器
  • 开发在代码写死了一些配置导致某些功能异常
  • 有一些老旧的服务是单节点部署的,下线后由于新人不熟悉业务不能快速重新拉起,导致不满足RTO

同时还发现了不少可以改进的小地方,所以容灾演练还是很有必要的

PPT里写的再漂亮再高可用,也不如进行定期的容灾演练

SSH hang forever

问题: Redhat Enterprise 8.8 SSH登录时发现执行/etc/profile*时卡住,Control+C 强制退出初始化过程会导致 hostname 异常显示,很多 env alias 等初始化配置都被打断无法正常使用,但实际业务进程没有问题

bash4.4

在/etc/profile*中打echo断点发现初始化实际是卡在了:/etc/bash_completion.d/gluster 中执行的 pidof glusterfs 命令

用strace跟踪发现实际是卡在了 openat /proc/$pid/cmdline

/proc/pid/cmdline 文件包含了进程的完整命令行,包括执行文件的路径和参数。这个文件中的命令行参数是由空字符('\0')分隔的一组字符串,最后还有一个额外的空字符。这个文件的作用是让用户可以查看正在运行的进程的完整命令行信息。

strace_hang

然后进一步发现不光是 pidof 命令的参数无法读取,很多如 ps ss netstat 等命令在带参数执行时都会卡住

排查了半天,和 cgroup、permission 等完全没有关系,就好像死锁了一样,有其他进程在读写这个cmdline文件,然后导致其他进程在 openat 这个文件的时候hang forever

没有搞明白这个openat读操作是和谁死锁了,又不太方便一个个进程Kill了去排查,好在业务是集群部署的,不会有单点故障,索性直接重启服务器,然后发现ssh恢复了,果然重启能解决99%的问题~

反思:有空要学习一下 pstack gdb 等工具来排查一下这个问题

文件同步

业务有个需求需要实时同步2个目录,采用的方案是: lsyncd

跑了两天发现2个目录du -sh /xxx出来大小结果竟然不一样

# 错误的lsyncd配置
$ cat /etc/lsyncd.conf
...
sync {
   default.rsync,
   source = "/app/local/data/source/",
   target = "/app/local/data/destination/",
}
# 正确的配置
...
sync {
   default.rsync,
   source = "/app/local/data/source/",
   target = "/app/local/data/destination/",
   rsync = {
      binary = "/usr/bin/rsync",
      archive = true,
      _extra = {"--recursive"},
   },
}

lsyncd是一个 rsync + inotify 工具, rsync 提供了 -r recursive 参数来递归同步;或者使用 -a archive 参数来同步归档子目录,除了可以递归同步以外,还可以同步元信息(比如修改时间、权限等),比 -r 参数更加有效。 官方文档甚至没给这个archive = true_extra = {"--archive"} 有什么区别,没有为这个参数添加comment

同步脚本是GPT写的,验证测试的时候只验证了根目录下的同步,没有验证子目录下的同步,还好没出大问题。一周在反斜杠/的问题上栽倒2次,我是真的菜

生活

  • 最近感觉闲下来了,有更多的精力投入到个人学习和提升生活质量上了。
    • 这周睡眠质量明显提升,但是早上7点还是赖床,就是脑子醒了,但身体没醒的状态(一种说法是是因为在远古时期,祖先为了在冬天活下去,会尽量保持身体的温暖,减少热量的损失,这个习惯被深深地刻在了基因了)
    • 发现一家烧腊店非常好吃,这周吃了好多次他们家的叉烧和卤猪小肠,搞得都不想自己做饭了
    • 这周没有喝咖啡,而是用茶替代了,感觉喝茶同样不错
    • 黑五副作用来了,果然只有买VPS的那一刻是兴奋的,现在6台服务器有3台在吃灰,开始后悔了(陷入和Steam买游戏一样的状态了)

学习