使用pubma对网络进行 Chaos-testing


使用pubma对网络进行 Chaos-testing

在联盟区块链的开发过程当中,需要模拟区块链网络的抖动,并对其进行测试。本文将针对hyperchain平台,使用pubma进行chaos-testing

Author: 陈权@hyperchain

0x01 问题明确

当前我们需要模拟如下场景:

  • 节点在高网络延迟下的表现
  • 节点在高网络丢包率下的表现

有些bug我们是在比较苛刻的网络条件下测试得到的,而按照传统的经验,我们会想办法将环境部署到互联网上进行测试,但是这种方式非常原始,而且得到的结果也具备大量的偶然性,我们想要复现相同的结果也是十分困难的,因此我们使用容器技术对不同的网络情况进行模拟,以期得到可控的网络抖动测试环境。

0x02 pumba 工具介绍

先对容器网络Chaos-testing 工具pubma进行简单介绍,以及相关使用的说明。

What is Pubma(a)?

相信出生于90年代的小伙伴们都知道一个电影叫 The Lion King(狮子王),里面有一个角色的名字就叫Pumbaa,在Swahili语中,Pumbaa的意识是”保持愚蠢,无知,以及懒惰”。当然这个工具起这个名字的内涵大概就是想模拟一个“愚蠢的,不可预知的环境”的意思。

Pumba 能做什么?

简单地说,Pubma 能够完成包括对Docker容器的 killstopremovepause

当然, Pubma 也能够完成网络模拟,模拟包括一系列的网络问题(延迟,丢包,使用不同的丢包模型,带宽限制等等)。针对网络模拟,Pumba使用的是Linux内核tc netem实现的。 如果目标container不支持tc的话,Pumba将会使用sidekick 附着到目标容器进行控制。

继续阅读 “使用pubma对网络进行 Chaos-testing”

寻觅了很久的VIMRC


导言

.vimrc熟悉又痛苦的一个文件,从自己编译YCM,安装Ctags到索性一键安装SpaceVim最终还是归于沉寂。

玩来玩去,我觉得一个vim的配置还是要简单实用才是最实在的。因此我找到vim-bootstrap然后稍微改了一下,现在放在我自己的dotfile中,供大家参考。

在这里我放上我的 vim-cheatsheet。

VIM cheat sheet

如果你在使用本.vimrc,你可以参考本使用文档
直接将vimrc文件放到$HOME并命名为.vimrc即可

继续阅读 “寻觅了很久的VIMRC”

如何用GN编译V8引擎


在v8引擎的6.5版本以上,google采用了GN+Ninja的编译组合,因此本文主要是基于GN+Ninjia的编译方式进行说明。

获取源码

在官方文档中,还特别提示了避免HFS环境下的unicode问题,需要额外配置一下:

$ git config --global core.precomposeUnicode true

现在v8在github上面有源码镜像,你只需要git clone下来即可。

$ git clone [email protected]:v8/v8.git

继续阅读 “如何用GN编译V8引擎”

Lodash 源码分析(三)Array


前言

这是Lodash源码分析系列文章的第三篇,前面两篇文章(Lodash 源码分析(一)“Function” MethodsLodash 源码分析(二)“Function” Methods)分别分析了Lodash “Function” 中的一些重要函数,也给出了简化的实现,为理解其内部机理和执行方式提供了便利。这篇文章将专注于Array,Array是Lodash中非常重要的内容,我们将分析其代码实现以及同类似库中的实现对比。

_.head

_.head函数其实很简单,返回一个数组的第一个元素,完全可以在两三行代码中实现。可以看到Lodash中是这么实现的:

function head(array) {
   return (array && array.length) ? array[0] : undefined;
}

Lodash进行了简单的判断,然后返回了第一个元素。这么简单的函数其实没有什么好说的,但我拿出来说是想介绍另一个库Ramda.js的实现:

module.exports = nth(0);

它是用nth函数实现该功能的,那么这个函数式怎么样的呢?

module.exports = _curry2(function nth(offset, list) {
  var idx = offset < 0 ? list.length + offset : offset;
  return _isString(list) ? list.charAt(idx) : list[idx];
});

这个函数就有点意思了,用了柯里化,是一个函数式的实现,当head函数返回一个nth(0)时,其实返回的是一个柯里化之后的函数,然后再接受一个数组,判断数组类型之后返回list[offset]的值。

再看看Lodash的nth的实现:

function nth(array, n) {
   return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;
}

function baseNth(array, n) {
  var length = array.length;
  if (!length) {
    return;
  }
  n += n < 0 ? length : 0;
  return isIndex(n, length) ? array[n] : undefined;
}

仔细对比两个库的实现,两个库都允许负下标的处理,但是对于Ramda而言,如果list是一个null或者undefined类型的数据的话,将会抛出TypeError,而Lodash则优雅一些。

_.join

_.join函数是另一个简单的函数:

var arrayProto = Array.prototype;
var nativeJoin = arrayProto.join;

function join(array, separator) {
  return array == null ? '' : nativeJoin.call(array, separator);
}

重写之后函数变为:

function join(array,separator) {
    return array == null ? '' : Array.prototype.join.call(array, separator);
}

我们再对比一下Ramda的实现:


var invoker = require('./invoker'); module.exports = invoker(1, 'join');

再看看invoker函数:

module.exports = _curry2(function invoker(arity, method) {
  return curryN(arity + 1, function() {
    var target = arguments[arity];
    if (target != null && _isFunction(target[method])) {
      return target[method].apply(target, Array.prototype.slice.call(arguments, 0, arity));
    }
    throw new TypeError(toString(target) + ' does not have a method named "' + method + '"');
  });
});

invoker函数就是为了返回一个curry化的函数,那么我们其实可以这么理解如果用Lodash实现一个函数化的join可以这么实现:

function _join(array,separator){
        return Array.prototype.join.call(array,seprator);
}
var join = _.curry(_join);

那么我们可以和Ramda的使用方式一样使用:

join(_,",")([1,2,3]);
// 1,2,3

继续阅读 “Lodash 源码分析(三)Array”