第一页 上页 2 3 4 5 6 7 8 9 10 11 下页 最后页 [ 显示模式: 摘要 | 列表 ]

个人博客迁移至香港机房

[不指定 2019/07/16 15:29 | by 刘新修 ]

 看了co的源码 比较难懂 了解了其原理后实现了一个最简版本https://github.com/yucong/simple-co 希望对想学习的tx有帮助~ yeild后面只支持thunk,co本身也是一个thunk 核心代码:

JavaScript代码
  1. function co(generator) {  
  2.   return function(fn) {  
  3.     var gen = generator();  
  4.     function next(err, result) {  
  5.         if(err){  
  6.             return fn(err);  
  7.         }  
  8.         var step = gen.next(result);  
  9.         if (!step.done) {  
  10.             step.value(next);  
  11.         } else {  
  12.             fn(null, step.value);  
  13.         }  
  14.     }  
  15.     next();  
  16.    }  
  17. }  

用法:

JavaScript代码
  1. var co = require('./co');  
  2. // wrap the function to thunk  
  3. function readFile(filename) {  
  4.     return function(callback) {  
  5.         require('fs').readFile(filename, 'utf8', callback);  
  6.     };  
  7. }  
  8.   
  9. co(function * () {  
  10.     var file1 = yield readFile('./file/a.txt');  
  11.     var file2 = yield readFile('./file/b.txt');  
  12.   
  13.     console.log(file1);  
  14.     console.log(file2);  
  15.     return 'done';  
  16. })(function(err, result) {  
  17.     console.log(result)  
  18. });  

会打印出: content in a.txt content in b.txt done

 

下面做个简单对比:
传统方式,sayhello是一个异步函数,执行helloworld会先输出"world"再输出"hello"

JavaScript代码
  1. function sayhello() {  
  2.     return Promise.resolve('hello').then(function(hello) {  
  3.         console.log(hello);  
  4.     });  
  5. }  
  6. function helloworld() {  
  7.     sayhello();  
  8.     console.log('world');  
  9. }  
  10. helloworld();  

输出

 

JavaScript代码
  1. "world"  
  2. "hello"  

co 的方式,会先输出"hello"再输出"world"

JavaScript代码
  1. function co(gen) {  
  2.     var it = gen();  
  3.     var ret = it.next();  
  4.     ret.value.then(function(res) {  
  5.         it.next(res);  
  6.     });  
  7. }  
  8. function sayhello() {  
  9.     return Promise.resolve('hello').then(function(hello) {  
  10.         console.log(hello);  
  11.     });  
  12. }  
  13. co(function *helloworld() {  
  14.     yield sayhello();  
  15.     console.log('world');  
  16. });  

输出

JavaScript代码
  1. "hello"  
  2. "world"  

 

消除回调金字塔

假设sayhello/sayworld/saybye是三个异步函数,用真正的 co 模块就可以这么写:

JavaScript代码
  1. var co = require('co');  
  2. co(function *() {  
  3.     yield sayhello();  
  4.     yield sayworld();  
  5.     yield saybye();  
  6. });  

输出

JavaScript代码
  1. "hello"  
  2. "world"  
  3. "bye"  

 

 问题背景,从vmware6.0版本的物理机上导出虚拟机ovf模板后,导入到4.1版本物理机上时报错:“硬件系列vmx-11不受支持”。

1.打开xxx.ovf文件,将<vssd:VirtualSystemType>vmx-11</vssd:VirtualSystemType> 改成物理机支持的版本:<vssd:VirtualSystemType>vmx-7</vssd:VirtualSystemType> 

2.打开xxx.mf文件,将对VOF引用的哪一行删掉,不然 在部署的时候会报文件 xxxx.ovf 的完整性检查失败,可能在传输过程中已损坏。

删掉 SHA1(xxx.ovf)= f801b24cd5f664a9f3f88810b87e0080fb5bf29f

google chrome 插件安装目录

[不指定 2017/06/19 13:52 | by 刘新修 ]

MAC:

C#代码
  1. /Users/jesse/Library/Application Support/Google/Chrome/Default/Extensions/nhdogjmejiglipccpnnnanhbledajbpd/0.0.2_0  

windows:

C#代码
  1. C:\Users\Administrator\AppData\Local\Google\Chrome\User Data\Default\Extensions\nhdogjmejiglipccpnnnanhbledajbpd\3.1.4_0  

 

Docker v17.04.0-ce-rc1 发布了,并将于 2017-04-05 发布 17.04.0-ce  版本。本次更新内容如下:

Client

  • Sort docker stack ls by name #31085

  • Flags for specifying bind mount consistency #31047

  • Suppressing image digest in docker ps #30848

  • Hide command options that are related to Windows #30788

  • Fix docker plugin install prompt to accept "enter" for the "N" default #30769

  • Add truncate function for Go templates #30484

  • Support expanded syntax of ports in stack deploy #30476

  • Support expanded syntax of mounts in stack deploy #30597 #31795

  • Add --add-host for docker build #30383

  • Add .CreatedAt placeholder for docker network ls --format #29900

  • Update order of --secret-rm and --secret-add #29802

  • Fix use of **/ in .dockerignore #29043

  • Add --filter enabled=true for docker plugin ls #28627

  • Add --format to docker service ls #28199

  • Add publish and expose filter for docker ps --filter #27557

  • Support multiple service IDs on docker service ps #25234

  • Allow swarm join with --availability=drain #24993

  • Removal of the email from docker login #26868

Networking

  • Check parameter --ip, --ip6 and --link-local-ip in docker network connect #30807

  • Added support for dns-search #30117

  • Added --verbose option for docker network inspect to show task details from all swarm nodes #31710

Runtime

  • Handle paused container when restoring without live-restore set #31704

  • Do not allow sub second in healthcheck options in Dockerfile #31177

  • Support name and id prefix in secret update #30856

  • Use binary frame for websocket attach endpoint #30460

  • Fix linux mount calls not applying propagation type changes #30416

  • Fix ExecIds leak on failed exec -i #30340

  • Prune named but untagged images if danglingOnly=true #30330

  • Add daemon flag to set no_new_priv as default for unprivileged containers #29984

  • Add daemon option --default-shm-size #29692

  • Support registry mirror config reload #29650

  • Ignore the daemon log config when building images #29552

  • Move secret name or ID prefix resolving from client to daemon #29218

  • Implement optional ring buffer for container logs #28762

  • Allow adding rules to cgroup devices.allow on container create/run #22563

Swarm Mode

  • Add Service logs formatting #31672

  • Fix service logs API to be able to specify stream #31313

  • Add --stop-signal for service create and service update #30754

  • Add --read-only for service create and service update #30162

  • Renew the context after communicating with the registry #31586

Windows

  • Wait for OOBE to prevent crashing during host update #31054

  • Block pulling Windows images on non-Windows daemons #29001

下载

3月2日,Docker 官方发布了一篇 blog ,宣布企业版到来。版本也从1.13.x一跃到17.03。

之后,Docker 会每月发布一个 edge 版本(17.03, 17.04, 17.05...),每三个月发布一个 stable 版本(17.03, 17.06, 17.09...),企业版(EE) 和 stable 版本号保持一致,但每个版本提供一年维护。

Docker 的 Linux 发行版的软件仓库也从以前的https://apt.dockerproject.org / https://yum.dockerproject.org 变更为目前的 https://download.docker.com/。软件包名变更为 docker-ce(社区版) 和 docker-ee(企业版)。

旧的仓库和包名(docker-engine)依旧可以使用,但不确定什么时候会被废弃,docker-engine 的版本号也变成了17.03.0~ce-0这种的版本号。

Docker v17.03.0-ce 版本更新内容和下载地址请查看发行日志

Docker的网络模式和跨主机通信(Docker的四种网络模式Bridge模式)

当Docker进程启动时,会在主机上创建一个名为docker0...

Docker的四种网络模式

1. Bridge模式

当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。

从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备,Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker0网桥中。可以通过brctl show命令查看。

bridge模式是docker的默认网络模式,不写--net参数,就是bridge模式。使用docker run -p时,docker实际是在iptables做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL查看。

 

bridge模式如下图所示:

演示:

C#代码
  1. #docker run -tid --net=bridge --name docker_bri1 ubuntu-base:v3  
  2. #docker run -tid --net=bridge --name docker_bri2 ubuntu-base:v3  
  3.  
  4. #brctl show  
  5. #docker exec -ti docker_bri1 /bin/bash  
  6. #docker exec -ti docker_bri1 /bin/bash  
  7.  
  8. #ifconfig –a  
  9. #route –n  

2. Host模式

如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。

Host模式如下图所示:

演示:

C#代码
  1. #docker run -tid --net=host --name docker_host1 ubuntu-base:v3  
  2. #docker run -tid --net=host --name docker_host2 ubuntu-base:v3  
  3.  
  4. #docker exec -ti docker_host1 /bin/bash  
  5. #docker exec -ti docker_host1 /bin/bash  
  6.  
  7. #ifconfig –a  
  8. #route –n  

3. Container模式

这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信。

Container模式示意图:

演示:

C#代码
  1. #docker run -tid --net=container:docker_bri1 --name docker_con1 ubuntu-base:v3  
  2.  
  3. #docker exec -ti docker_con1 /bin/bash  
  4. #docker exec -ti docker_bri1 /bin/bash  
  5.  
  6. #ifconfig –a  
  7. #route -n  

4. None模式

使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。

Node模式示意图:

演示:

C#代码
  1. #docker run -tid --net=none --name docker_non1 ubuntu-base:v3  
  2. #docker exec -ti docker_non1 /bin/bash  
  3.  
  4. #ifconfig –a  
  5. #route -n  

跨主机通信

Docker默认的网络环境下,单台主机上的Docker容器可以通过docker0网桥直接通信,而不同主机上的Docker容器之间只能通过在主机上做端口映射进行通信。这种端口映射方式对很多集群应用来说极不方便。如果能让Docker容器之间直接使用自己的IP地址进行通信,会解决很多问题。按实现原理可分别直接路由方式、桥接方式(如pipework)、Overlay隧道方式(如flannel、ovs+gre)等。

直接路由

通过在Docker主机上添加静态路由实现跨宿主机通信:

Pipework

Pipework是一个简单易用的Docker容器网络配置工具。由200多行shell脚本实现。通过使用ip、brctl、ovs-vsctl等命令来为Docker容器配置自定义的网桥、网卡、路由等。

使用新建的bri0网桥代替缺省的docker0网桥

bri0网桥与缺省的docker0网桥的区别:bri0和主机eth0之间是veth pair

Webbench MAC下安装

[不指定 2017/06/10 16:57 | by 刘新修 ]

Webbench是有名的网站压力测试工具,它是由 Lionbridge公司开发。

Webbech能测试处在相同硬件上,不同服务的性能以及不同硬件上同一个服务的运行状况。webBech的标准测试可以向我们展示服务器的两项内容:每秒钟相应请求数和每秒钟传输数据量。webbench不但能具有便准静态页面的测试能力,还能对动态页面(ASP,PHP,Java,CGI)进 行测试的能力。还有就是他支持对含有SSL的安全网站例如电子商务网站进行静态或动态的性能测试。

安装: Make install 需 sudo 权限, 需要写入 /usr/local/bin

C#代码
  1. brew install ctags # 依赖安装  
  2. curl -o webbench.tar.gz http://blog.zyan.cc/soft/linux/webbench/webbench-1.5.tar.gz  
  3. tar -zxvf webbench-1.5.tar.gz  
  4. cd webbench-1.5/  
  5. mkdir -pv /usr/local/man/man1 # 关键  
  6. sudo make && sudo make install # sudo 权限因为需要创建文件夹  

Mac下自带apache压力测试:

C#代码
  1. localhost:webbench-1.5 jesse$ webbench -c 500 -t 120 http://localhost/  
  2. Webbench - Simple Web Benchmark 1.5  
  3. Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software.  
  4.   
  5. Benchmarking: GET http://localhost/  
  6. 500 clients, running 120 sec.  
  7.   
  8. Speed=33001 pages/min, 696314 bytes/sec.  
  9. Requests: 64078 susceed, 1924 failed.  
  10. localhost:webbench-1.5 jesse$   

 

  当我们实例化一个php类的时候,要怎么传递参数呢?这取决于该类的构造方法。

  例:

  person.class.php

  

  class person{

  var $name;

  var $color;

  var $sex;

  var $age;

  function __construct($name,$age='',$sex='boy'){

  $this->name = $name;

  $this->age = $age;

  $this->sex = $sex;

  $this->color = 'yello';

  }

  function eat(){

  echo $this->name.'要吃饭';

  }

  function xinxi(){

  echo $this->name.' is '.$this->sex.' and age is '.$this->age.' fuse is '.$this->color;

  }

  }

  ?>

  son.php

  

  include('person.class.php');

  $son = new person('cuihua',25,'girl');//此处的参数传递要和类的构造方法里面的参数顺序对应

  //$son->xinxi();//cuihua is girl and age is 25 fuse is yello

  $son->name = '田妞';

  $son->eat();//田妞要吃饭

  ?>

搞定 koa 之generator 与 co

[不指定 2017/05/17 17:29 | by 刘新修 ]

 koa 是由 tj大神利用 generator 开发的 web 框架。要理解 koa,首先要先了解 generator 与 co。作为搞定 koa 的第一篇,我们便谈谈这个。文章首发在boke.io

generator介绍

 function* Gene(){

    yield 1;

    yield 2;

}

var gene = Gene();

console.log(gene.next());//{ value: 1, done: false }

console.log(gene.next());//{ value: 2, done: false }

console.log(gene.next());//{ value: undefined, done: true }

console.log(gene.next());//Error: Generator has already finished  经@Ralph-Wang提醒从 v0.11.13 开始不抛错了,返回{ value: undefined, done: true }

从上面我们可以看到

generator 的定义和函数类似,只是在 function 后面多了一个*

调用generator 和调用函数一样,只是不像函数立即执行,而是会生成一个对象

generator 生成的对象存在一个 next 函数,调用 next 会返回 yield运算的结果对象,并停止。再次调用会在下一个 yield 处停止。

当所有的 yield 被执行完,调用 next 函数会返回{ value: undefined, done: true }。再次调用会报错

generator 与异步

 看完 generator 的介绍,你心里回想这跟异步有毛关系?不着急听我接着说

串行请求两个网页的代码

var request = require('request');

var a = {};

var b = {};

request('http://www.google.com', function (error, response, body) {

    if (!error && response.statusCode == 200) {

        a.response = response;

        a.body = body;

        request('http://www.yahoo.com', function (error, response, body) {

            if (!error && response.statusCode == 200) {

                b.response = response;

                b.body = body;

            }

        });

    }

});

我们再看看最终我们是如何利用 generator请求网页的

co(function *(){

  var a = yield request('http://google.com');

  var b = yield request('http://yahoo.com');

  console.log(a[0].statusCode);

  console.log(b[0].statusCode);

})()

上面的代码可以看到,co 里面传入了一个 generator,里面用 yield 调用异步函数。从逻辑上看,里面的异步被变成了同步。

co 到底有什么魔法?可以把我们从异步中解救出来?

想想 generator 的特性,当我们执行第一个 next 的时候,会调用第一个 request,此时我们去调用 request 的逻辑,然后把 generator 的实例穿进去。当第一个 request 逻辑完成时,在调用这个 generator 的 next,这样就到了第二个 yield 的逻辑了。当然这需要一些逻辑的封装,也就是 co 了。

根据上面的分析,我们大概可以写出下面的代码

function co(Gene){

    //先实例化一下

    var gene = Gene();

    //如果存在 next 函数

    if(gene.next){

        var fun = gene.next();//把异步函数返回过来,好继续封装

        //fun 处理完,再调用 gene.next()

        //...

    }

}

从上面的代码可以看出

yield 后面的内容需要返回一个异步函数,这样我们才可进一步封装异步处理的逻辑。

fun 需要可以传入参数,这样才可以处理多个异步

需要一个递归调用,这样才可以持续调用 next,同时根据 next 返回对象中的done属性停止逻辑

需要考虑错误处理

 今天就到这里,下一篇详细讲一下 co 的源码

看了co的源码 比较难懂 了解了其原理后实现了一个最简版本https://github.com/yucong/simple-co 希望对想学习的tx有帮助~ yeild后面只支持thunk,co本身也是一个thunk

核心代码:

function co(generator) {

  return function(fn) {

  var gen = generator();

  function next(err, result) {

    if(err){

      return fn(err);

    }

    var step = gen.next(result);

    if (!step.done) {

      step.value(next);

    } else {

      fn(null, step.value);

    }

  }

  next();

   }

}

用法:


var co = require('./co');

// wrap the function to thunk

function readFile(filename) {

    return function(callback) {

      require('fs').readFile(filename, 'utf8', callback);

    };

}


co(function * () {

    var file1 = yield readFile('./file/a.txt');

    var file2 = yield readFile('./file/b.txt');


    console.log(file1);

    console.log(file2);

    return 'done';

})(function(err, result) {

    console.log(result)

});

会打印出:

content in a.txt

content in b.txt

done

================================

generator_co:  http://liuxinxiu.com/generator_co/

第一页 上页 2 3 4 5 6 7 8 9 10 11 下页 最后页 [ 显示模式: 摘要 | 列表 ]