OOM 调查使用到的工具
基础工具
top 与 htop。这两个东西比 free 好用。比较神奇的是,为什么线上还有装了 htop这样的非标准 top。字节跳动自己开源了一个 atop,可以细致地监控线程信息,也可以快速采集系统信息,是一个不错的监控工具。
pmap。这个东西是莫枢自己也用来 dump 详细的内存轮廓的地址,但可能需要使用他提到的一个 Serviceability Agent API 来读才读得懂。这个工具的输出可以看到各段内存的起止,但不经帮助,很难读出各个子线程的栈来。这个命令在非 root/sudo 权限下看到的是 jvm 启动参数,在 root/sudo 权限下看到的是内存轮廓,这时候就需要 Serviceability Agent API 了。
smem。这个东西对内存的 RSS/PSS/USS 分析得很好。但并不能帮助我们直接获知我们最期待的栈内存轮廓,比如当前 JVM 的 stack 到底是怎么分布的,占了多少内存?而且更重要是,线上机器没有这个工具。
直接 cat /proc/pid/smaps 其实其他的进程内存查看工具的信息可能都能在这里看得到,但是需要耐心。而且,这个东西在 ...
Docker 与网络
docker 操纵网络是无形的,它通过修改路由规则来让某些包在特定的 network 里面流动。在 Linux 下,它是通过操纵 iptables 来做到这件事的(windows下通过其他机制)。
docker 驱动docker 的网络是可插拔的,因为使用了驱动。默认就自动携带的驱动是:
bridge默认的网络驱动。当所有的容器都在一个宿主机的时候,应该使用这个驱动。
在计算机网络的范畴里,一个桥接网络是一个链路层设备,转发网络片段。一个桥可以一个硬件设备或者宿主机内核里的软件设备。在 Docker的范畴里,桥接网络使用一个软件桥来让容器连在同一座桥上,通过桥通信。同一个宿主机里,不同桥网络是不能相互通信的(实际上不同的网络就不应该彼此通信)。
启动 docker 的时候,一个默认的桥接网络就被创建了。如果没有其他网络被创建,则默认大家都使用这个网络。所有新创建的容器,都会自动在这个名称为 bridge 网络里互连。用户也可以创建自定义的桥接网络,自定义的桥接网络拥有更高的优先级。
自定义网络的优势
用户自定义网络在容器化应用程序里,提供了更好的隔离和互操作性。在同一个桥接网络里的容器 ...
日期与时间
JSR 310 Java Date与Time API新旧 API 的更迭旧的 Java API 主要包括java.util.Date和java.util.Calendar 两个包的内容。这两个包的时间类型是可变的。如 Date 的实例可以通过 setYear 来产生变化。
JSR 310 中包括的日期类型主要有:
计算机时间:Instant,对应 java.util.Date,它代表了一个确定的时间点,即相对于标准Java纪元(1970年1月1日)的偏移量;但与java.util.Date类不同的是其精确到了纳秒级别。
人类时间:对应于人类自身的观念,比如LocalDate和LocalTime。他们代表了一般的时区概念,要么是日期(不包含时间),要么是时间(不包含日期),类似于java.sql的表示方式。此外,还有一个MonthDay,它可以存储某人的生日(不包含年份)。每个类都在内部存储正确的数据而不是像java.util.Date那样利用午夜12点来区分日期,利用1970-01-01来表示时间。这些类型的实例是 immutable 的,而且只能通过工厂方法创建。
时区(比如Eu ...
使用 Truffle 来编译、安装智能合约(旧文一篇)
因为官定版本的 solidity 实在编译安装太费力了,放弃,改用 Truffle。
直接用 npm 安装:
1npm install -g truffle
创建新目录,初始化新目录:
123mkdir myprojectcd myprojecttruffle init
修改配置文件 truffle.js:
12345678910 module.exports = { networks: { development: { host: "localhost", port: 8545, network_id: "*", // Match any network id gas: 500000 } }};
生成必须的智能合约源码和迁移脚本:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545 ...
在以太坊网络上使用智能合约 solidity(旧文一篇)
因为一个并不周知的 issue,geth 客户端将不再提供 solc 编译相关功能。我们必须借助外部编译器,比如 solc/remix。
所谓 Contract,只是 Martin fowler 的书里面经常提到的一个富血的类型罢了。
注意,要用高版本的 npm,来安装 solc:
1npm install -g solc
智能合约代码:
12345678pragma solidity ^0.4.0;contract TestContract{ function multiply(uint a, uint b) returns (uint) { return a * b; }}
用 solcjs 来编译代码:
12solcjs --bin testContract.solsolcjs --abi testContract.sol
它会产生 testContract_sol_TestContract.bin 和 testContract_sol_TestContract.abi。结尾应该是 Contract 的类型 ...
在Centos 6.7 上安装并使用web3(旧文一篇)
不要使用默认 gcc,会编译安装 web3失败。
12345678910111213sudo yum erase -y gcc gcc-c++ sudo yum install -y centos-release-scl sudo yum install -y devtoolset-3-toolchain scl enable devtoolset-3 bash yum remove -y nodejs curl --silent --location https://rpm.nodesource.com/setup_8.x | sudo bash - sudo yum -y install nodejs
不能使用全局安装,要尽量本地安装:
123456mkdir calc-nodenpm initnpm install web3 # 照理来说这样也应该 work,但就是不 worknpm install -g web3 --unsafe-perm=true --allow-root
web3 本身是一系列 nodejs 模块的集合,包括但不限于
web3-eth 针对以太坊区块链和 ...
在CentOS 6.7上用 geth 搭建以太坊私链网络的全部步骤(旧文一篇)
生成基本的路径
1mkdir -p ~/home/ethereum
如果 git 版本是 1.x,卸载旧的 git,安装最新版的 2.x 以上的 git:
1git version && yum erase -y git && yum install -y git
执行以下命令,编译以太坊客户端:
123456789yum install -y golangyum install -y gmp-develgit clone https://github.com/ethereum/go-ethereumcd go-ethereummake all# 生成基本路径mkdir -p ~/home/ethereum# 进入基本路径cd ~/home/ethereum
如果有“fatal: unable to access ‘https://github.com/ethereum/go-ethereum/‘: Failed connect to github.com:443; Operation now in progress”考虑是容器的外网访问权限问题。
把 ...
如何做性能测试的问题下的答案
试着回答一下这个问题。
首先要划分系统类型:有状态还是无状态,业务系统还是存储系统。根据不同的业务场景,设立性能测试的目标:是要测 QPS,还是 TPS 还是 TPS,还是任何其他【性能】-从广义来讲,一个存储系统到底能够以多高的平均时延来管理大多的存储空间,可能也是性能的一种。
有了性能测试的目标,接下来就是拆解用例。如果把性能测试归为测试的话,测试就需要测试用例,测试用例只是用例的形式化表达。把用户的使用场景勾勒出来,把每一步拆解成的流程图或者时序图—我们已经得到了一个纸上的集成测试计划,只是没有跟性能挂上钩。
接下来就进入真正写测试用例的环节了。
我们的测试报告如果要涵盖足够立体的信息,则既要了解每一个环节/接口/API 的性能指标,又要了解整体的性能指标。
这个时候测试工具的覆盖面就很重要了。如果我们选择偏黑盒的测试工具,apache ab /JMeter,则我们的测试用例就要围绕着对外交互的 API写,也只能测到外围接口的性能。这样的测试用例写起来最简单,无需侵入任何内部代码中。
如果我们使用了 JMH 一类的工具,则可以自由编写对任何方法的测试用例。但需要对系统有非常深的理 ...
log 的历史
git
DAG
区块链
saga
binlog/WAL
JPA 的 id 生成策略
JPA 有一个@GeneratedValue注解,有一个strategy attribute,如@GeneratedValue(strategy = GenerationType.IDENTITY)。
常见的可选策略主要有IDENTITY和SEQUENCE。
GenerationType.IDENTITY要求底层有一个 integer 或者 bigint 类型的自增列( auto-incremented column)。自增列的赋值必须在插入操作之后发生,因为这个原因,Hibernate 无法进行各种优化(特别是 JDBC 的 batch 处理,一次 flush 操作会产生很多条insert 语句,分别执行)。如果事务回滚,自增列的值就会被丢弃。数据库在这个自增操作上有个高度优化的轻量级锁机制,性能非常棒。
MySQL 支持这种 id 生成策略,
使用 MySQL 应该尽量使用这个策略,即使它无法优化。
JPA 用它生成 id,会一条一条地插入新的 entity。
GenerationType.SEQUENCE数据库有一个所谓的 sequence 对象,可以通过 select (而不是 ...