如何做一个靠谱的发号器

本文曾载于 有赞技术团队博客 https://tech.youzan.com/id_generator/ 为什么需要一个发号器 在使用数据库时,表的主键经常会使用数据库的自增(auto_increment)来产生。这当然很方便也很高效。但是使用自增也会带来一些麻烦。如果从一个数据库以外的地方,也就是发号器来产生全局唯一 ID,这些问题就可以得到解决,生活就可以更美好。 难以适应分片场景 在采用数据库分片时,如果使用数据库自增 ID,不同分片上会产生相同的 ID。单靠 ID 无

排查 etcd 响应慢的问题

有一台 etcd,突然出现了响应缓慢的情况。排查中发现,系统 CPU,带宽,IO,内存,rlimit 都还有很大余量。但是 ss 发现,端口的backlog 堆积了大量连接。 $ ss -lnt State Recv-Q Send-Q Local Address:Port Peer Address:Port ... LISTEN 745 65535 10.20.30.40:2379 *:* ... 但是看并没有 SYN_RECV 状态的连接存在。所以不像由于并发连接太多造成的

一个屏蔽 IP 的脚本

在测试可用性的时候,经常需要模拟断网。这时候用 iptables 是比较方便的。但是如果想更方便一点,不用去敲那么长的命令会更好些。于是就写了个 ban_ip 脚本。 #!/bin/bash if [[ $EUID != 0 ]]; then echo should run as root exit 1 fi action=DROP comment=ban_ip cmd=$1 case $cmd in list) iptables -L -n | awk -v cm

linux capabilities

在 linux 系统中,很多操作是需要 root 用户权限才能操作的。比如 chown,改变进程 uid,使用 raw socket 等等。要不就得用 sudo 提升权限,如果想让每个用户都能用特权来执行一个程序,配置管理和权限控制就很麻烦了。还有一个办法是使用粘滞位,通过 chmod +s,可以让一个 owner 为 root 的可执行文件再运行时具有 root 权限。在一些发型版中,ping 命令就是这么干的。给 ping 命令加上粘滞位以后,普通用户也可以使用这个命令通

为 bash 提示符加上 git 状态

在有一次手误合错分支以后,就决定为 bash 提示符加上显示当前分支,以及提交状态,这样就可以更清楚地知道当前在哪个分支,以及是不是 commit 了,是不是 push 了。代码如下: function __git_prompt() { local s=$(git status -b --porcelain 2>/dev/null) if [[ -z $s ]]; then PS1=\h:\W \u$ else local l=$(echo $s|wc -

page cache 造成 java 长时间 gc

最近在升级一个 java 应用时,在刚启动不久的时候发生了长时间的 gc,时间到了数秒,业务访问纷纷超时。 看了下 gc log: 2016-12-06T22:50:44.256+0800: 13.632: [GC pause (G1 Evacuation Pause) (young) Desired survivor size 13631488 bytes, new threshold 1 (max 15) - age 1: 27212320 bytes, 27212320

Java 应用在线性能分析和火焰图

在碰到线上性能问题的时候,如果能在线通过采样方式获取热点函数/方法就可以更方便地定位问题所在,进行优化。采用在线采样的方式,由于性能影响小,可以比较放心地在线上进行,获取第一手数据。Linux 平台上,对于多数 C/C++ 编写的应用,可以通过 perf 来方便的采样,还可以进一步生成火焰图来更直观地观察。Java 是没法直接用 perf 的。虽然有一个 perf-map-agent,但是并不方便,尝试过程中还弄出了 kernel panic,所以这玩意是不敢在线上用了。不过

一次连接超时问题排查的历程

我们有一个 java 应用,启动的时候要初始化连接池,在连接一堆 sharding 过的 DB 时,经常会有一部分连接超时失败的,集中在一两台后端机器上,但每次失败的后端服务器却又不固定,也并不是每次启动都能遇到。超时时间设为了 50ms,看起来有点短但是对局域网,和压力并不算大的 DB 来说,这个时间已经长得匪夷所思了。后来尝试调大成 100ms,还是有失败的。但是如果启动成功后,却没再记录到过连接超时的情况。 排查网络问题首先是抓包,本来打算看看是不是对端响应慢有啥重传的

go http client 设置连接超时

go 语言的 http 客户端可以在初始化话的时候通过 client := http.Client{ Timeout: 5 * time.Second, } 来设置请求超时,即整个 http 请求到完成响应的时间限制。那么如果想另外设置 tcp 连接阶段的超时可以这样玩: client := http.Client{ Transport: &http.Transport{ Proxy: http.ProxyFromEnvironment, Dial: (&ne

等待一个独立进程退出并获取 exit code

linux 里,对于进程的子进程,父进程可以用 wait、waitpid 来等待结果。但是对于一个独立的进程就不行了。 有时候想监控一个进程,或者在父进程异常退出后想找回子进程状态,就只能另辟蹊径。于是,想了个通过 ptrace 来跟踪进程退出的办法,做了个小程序: https://github.com/xiezhenye/waitpid/ 可以通过 waitpid 来等待一个独立进程退出并获取 exit code。