实现 go 的 goroutine 本地存储又一种方式

go 本身没有对外提供 goroutine 本地存储,而现实中,又经常需要在上下文中传递一些数据。使用 context 也是一种方式,但是要求在所有需要的地方都要传递,还是非常麻烦,而且有侵入性。 偶然发现 go 已经提供了一个用于 profile 的 pprof label,可以在 goroutine 中携带一些数据。不过这个东西既然是用于 pprof 的,随意往里塞太多东西显然也不适合,还会对 pprof 产生干扰。所以,想办法只用其中一个 label,用一些黑科技把一个

优化 Java 反射字段访问

最近负责的一个 Java 服务经常报 CPU 占用高的告警。于是乘着一次 CPU 高的时候,去用 JFR profile 了一下。(使用 JFR 对 Java 应用 profile 可以参考这篇文章:Java 应用在线性能分析和火焰图 )。把数据拖回来用 JMC 打开一看,发现热点都在反射上: 图里排在最前面的都是反射相关的函数,而且实际都是同一个地方引入的。那里为了读取一个私有字段,使用了类似下面的代码: public class SomeSingleton { priva

tcpdump 抓包显示 toa 源地址

LVS 是个很流行的高性能负载均衡程序。不过因为工作在 3-4 层,对被代理的后端来说,就只能看到 LVS 的源地址,看不到实际的用户来源 IP 地址了。所以 LVS 提供了一个 toa 内核模块,在后端安装后,可以从 TCP 头的扩展段里获取源 IP 地址。不过这只限于应用层面。系统层面的工具比如 netstat,tcpdump 等仍然只能看到 LVS 的源地址,想通过 tcpdump 抓包过滤或者分析实际来源地址就不行了。不过既然在 TCP 头里有这数据我们就还是可以利用

升级 centos 内核到 4.x

centos 发行版是跟随 redhat 发行版的。在内核版本上比较保守。比如 centos 6.x 分支最高是 2.6.32 内核。虽然也会 backport 一些高版本的功能,但是总会需要的功能没有的情况。 不过 centos 的仓库里其实藏着一个 4.x 的内核。 在 centos 仓库里,有一个 centos-release-xen 的包,是 由 Centos、CitrixXen、Godaddy、Rackspace 共同维护的 Xen4CentOS 项目的一部分。 X

如何做一个靠谱的发号器

本文曾载于 有赞技术团队博客 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