区块链学习之一-Hyperledger搭建第一个区块链网络

本文介绍如何快速利用fabric自带的例子搭建第一个区块链网络。

1 环境

MAC OS。

首先需要确保完成了一些前置工作:go、docker的安装。

2 步骤

接下来从github下载fabric-samples代码,地址:https://github.com/hyperledger/fabric-samples

注意需要将其放置与gopath中,我的路径是:
~/Documents/Work/mycode/gopath/src/github.com/hyperledger/fabric-samples/first-network

1
2
echo $GOPATH
~/Documents/Work/mycode/gopath/

本文基于如下版本:

1
2
3
4
5
6
7
8
9
➜ first-network git:(a76d649) ✗ git branch
* (HEAD detached at v1.0.6)
master
➜ first-network git:(a76d649) ✗ git tag
v1.0.2
v1.0.6
v1.1.0-alpha
v1.1.0-preview
v1.1.0-rc1

接下来切换到first-network子目录,可以看到有个脚本文件byfn.sh。后面我们相关操作都在此子目录中。
这个脚本文件封装了很多操作,我们可以利用这个脚本方便的启动区块链网络。关于细节后面会展开讨论。

执行命令:

1
./byfn.sh -m generate

可以在控制台看到如下输出:
1

这一步生成了网络中证书和key,排序服务的创世区块以及channel的配置。

接下来便可以运行如下命令启动网络:

1
./byfn.sh -m up

注意需要先启动docker。

1
2
3
➜ first-network git:(a76d649) ✗ ./byfn.sh -m up
Starting with channel 'mychannel' and CLI timeout of '10'
Continue (y/n)

选择y,接下来会创建channel,部署各个节点,安装链码等等。如果看到如下输出,表示执行成功:

1
2
3
4
5
6
7
8
9
10
11
2018-05-06 09:09:42.028 UTC [main] main -> INFO 007 Exiting.....
===================== Query on PEER3 on channel 'mychannel' is successful =====================
========= All GOOD, BYFN execution completed ===========
_____ _ _ ____
| ____| | \ | | | _ \
| _| | \| | | | | |
| |___ | |\ | | |_| |
|_____| |_| \_| |____/

关闭网络:

1
./byfn.sh -m down

输出日志:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
➜ first-network git:(a76d649) ✗ ./byfn.sh -m down
Stopping with channel 'mychannel' and CLI timeout of '10'
Continue (y/n)? y
proceeding ...
WARNING: The CHANNEL_NAME variable is not set. Defaulting to a blank string.
WARNING: The DELAY variable is not set. Defaulting to a blank string.
WARNING: The TIMEOUT variable is not set. Defaulting to a blank string.
Stopping orderer.example.com ... done
Stopping peer1.org2.example.com ... done
Stopping peer0.org2.example.com ... done
Stopping peer1.org1.example.com ... done
Stopping peer0.org1.example.com ... done
Removing cli ... done
Removing orderer.example.com ... done
Removing peer1.org2.example.com ... done
Removing peer0.org2.example.com ... done
Removing peer1.org1.example.com ... done
Removing peer0.org1.example.com ... done
Removing network net_byfn
Removing volume net_peer0.org2.example.com
Removing volume net_peer1.org2.example.com
Removing volume net_peer1.org1.example.com
Removing volume net_peer0.org1.example.com
Removing volume net_orderer.example.com
WARNING: The CHANNEL_NAME variable is not set. Defaulting to a blank string.
WARNING: The DELAY variable is not set. Defaulting to a blank string.
WARNING: The TIMEOUT variable is not set. Defaulting to a blank string.
Removing network net_byfn
WARNING: Network net_byfn not found.
Removing volume net_peer0.org2.example.com
WARNING: Volume net_peer0.org2.example.com not found.
Removing volume net_peer1.org2.example.com
WARNING: Volume net_peer1.org2.example.com not found.
Removing volume net_peer1.org1.example.com
WARNING: Volume net_peer1.org1.example.com not found.
Removing volume net_peer0.org1.example.com
WARNING: Volume net_peer0.org1.example.com not found.
Removing volume net_orderer.example.com
WARNING: Volume net_orderer.example.com not found.
6970b9a0fb75
dcd2b3b66bb8
6d79e9fcf20a
b47bdb303acf
fce5d85cbbaf
8f01a8e18b98
58d14dede52f
ca2f8cbb15ca
Untagged: dev-peer1.org2.example.com-mycc-1.0-26c2ef32838554aac4f7ad6f100aca865e87959c9a126e86d764c8d01f8346ab:latest
Deleted: sha256:906bff156357014748b71a348083d33176d294a6a1311e7df0fc54fc8d081745
Deleted: sha256:36f74509559873d1ee64d93681acdd78e2d8c330ba73377fc837edf0ef431b91
Deleted: sha256:9d27eb407a1c2acd04f093ac57ffc6a6ac416db510d9dd5c61b8651516525b2f
Deleted: sha256:c1e7964d91a0cb4c50150588a75c9b2dcbf0cdda7988accd1291e01ebee219d2
Deleted: sha256:4fb2551d453747c6eefb6a032ea6f0c3adf4e908652c4a242ec49b7882a2af94
Deleted: sha256:bb201d21c3b5ddf072c1c88a9facf165f3dc41884007ac39c57b7db6ada6660f
Deleted: sha256:17bb731d4c48aeca66ddbfff413c6ed6d0e3aaaf2c1e39c2a80190b04162784a
Untagged: dev-peer0.org1.example.com-mycc-1.0-384f11f484b9302df90b453200cfb25174305fce8f53f4e94d45ee3b6cab0ce9:latest
Deleted: sha256:f8ef2ebed09a2bdc16e0ce832879ef9612cbc1c621018560b640b6ddabd4145a
Deleted: sha256:b1a821ab9e0c17d5a25e79351888b63048b2a4404f6a42104c24b29f127da5e5
Deleted: sha256:c0aa1d65ac849a0a0b55bd9f1d441dd72ad6a5a0d1463f69ee1e60bf936278f3
Deleted: sha256:02750049903dca9fdc8bc6de13517968c4364e4c355b145abb3fb0e6c7f668df
Deleted: sha256:7825160930eebcbd8c739de264927d2765db870bb2917cf26fc4cb3c7b4336ac
Deleted: sha256:d2b686a165f3fa3a2f9d7ddaead3b27cc5b2f95901deb15687925459a33eef98
Deleted: sha256:aede0e567de2e6f82d38172974ad2c3ba8a21fe37550b3b40590aa56a436f7aa
Untagged: dev-peer0.org2.example.com-mycc-1.0-15b571b3ce849066b7ec74497da3b27e54e0df1345daff3951b94245ce09c42b:latest
Deleted: sha256:d601184df16e34971d7bbbe2b9af5db5005bb1597a2d20e78eb91a74c28a8e47
Deleted: sha256:d54ba0376a7ffe21541d5514d316c7d9b4bd76bbaf58a1370df156f90a8fc9a6
Deleted: sha256:722ba7f245425b0323ecfe58415d1622aba46b9b850ae34ce514a2fd8be035dd
Deleted: sha256:a956031b925713c8657d6f9b6d215141f87467cec0b7a8c5fb52944b8cc428f4
Deleted: sha256:1f1302db16d7dc4a99f302cd0328982db99a11e2d32effd4d0a9f96e60595585
Deleted: sha256:c6e1de55501abb5fcf7e23c77bfc897f33db61f9aa965131ae43c54295a0011e
Deleted: sha256:7aea8b0de30036baaa12e83d5cb1396584ac7a584679ef7082aaf96055ffd87a

3 附录-可能遇到的一些错误:

启动网络的时候遇到:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
➜ first-network git:(a76d649) ✗ ./byfn.sh -m up
Starting with channel 'mychannel' and CLI timeout of '10'
Continue (y/n)? y
proceeding ...
Creating cli ... error
Starting peer1.org2.example.com ...
Starting peer0.org2.example.com ...
Starting peer1.org1.example.com ...
Starting peer1.org1.example.com ... done
Creating cli ...
ERROR: for cli Cannot create container for service cli: Conflict. The container name "/cli" is already in use by container "a813a21e2dcc5e8b0f617b8fbdf695ea983b27ecbb4abc9c22f5341116ef7014". You have to remove (or rename) that container to be able to reuse that name.
ERROR: for cli Cannot create container for service cli: Conflict. The container name "/cli" is already in use by container "a813a21e2dcc5e8b0f617b8fbdf695ea983b27ecbb4abc9c22f5341116ef7014". You have to remove (or rename) that container to be able to reuse that name.
ERROR: Encountered errors while bringing up the project.
ERROR !!!! Unable to start network

原因以及解决方案:
原因是之前已经启动过该名字的container。需要删除:

1
2
docker stop /cli
docker rm .cli

4 参考资料:

docker-run-name-is-already-in-use-by-container

版权声明

本文首发于江南烟雨的个人博客博客( http://xiajunhust.github.io/ ),版权所有,侵权必究。
本文永久链接:http://xiajunhust.github.io/2018/05/06/区块链学习之一-Hyperledger搭建第一个区块链网络/

Redis源码学习之一-Redis过期键删除

本文内容是Redis过期键删除。

注:
源码基于Redis 2.9版本。

1 常见的三种过期键删除策略

常见的过期键删除策略有三种:

  • 定时删除
    使用定时器在键的过期时间来临时,立即执行对键的删除操作。

优点:
能保证过期键会被尽快删除,及时释放内存。

Read More

一次大表SQL查询优化历程

本文主要介绍了一次查询SQL查询性能优化的整个过程。

1 背景

有一张存储了订单数据的单表,为了防止表过大,需要删除历史的已达到终态的订单,只保留近期的数据以及历史的未达到终态的订单数据。这张表trade_order的大致结构是这样的(内容有缩减):

1
2
3
4
5
6
7
8
9
10
11
12
13
CREATE TABLE "trade_order" (
"id" int(10) unsigned NOT NULL AUTO_INCREMENT,
"order_no" varchar(30) NOT NULL DEFAULT '',
"update_time" datetime DEFAULT NULL COMMENT '订单更新时间',
"book_time" datetime DEFAULT NULL COMMENT '预订时间',
"gmt_create_time" datetime NOT NULL COMMENT 'DB数据创建时间',
"gmt_modify_time" datetime NOT NULL COMMENT 'DB数据更新时间',
"version" tinyint(4) unsigned NOT NULL DEFAULT '0' COMMENT '乐观锁',
PRIMARY KEY ("id"),
UNIQUE KEY "order_no" ("order_no"),
KEY "update_time_state" ("update_time","state"),
KEY "idx_stbyway_bktime" ("state","buy_way","book_time","id")
)

Read More

Hystrix Dashborad数据介绍

从Hystrix DashboardData看ReativeX的使用

最近在将系统中服务降级框架Hystrix的运行时的一些指标数据接入到监控平台,需要获取Hystrix的Dashboard数据。发现用到了ReactiveX的知识,因此总结下。

注:本文基于的Hystrix的版本是:

1
2
3
4
5
6
<hystrix.version>1.5.7</hystrix.version>
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-core</artifactId>
<version>${hystrix.version}</version>
</dependency>

1 如何获取Hystrix的Dashboard数据

获取Hystrix的Dashboard数据比较简单,实现一个观察者即可接收Dashboard数据,如下代码:

1
2
3
4
5
6
7
8
9
10
Observable<HystrixDashboardStream.DashboardData>
dashboardDataObservable = HystrixDashboardStream.getInstance().observe();
dashboardDataObservable.subscribe(new Action1<HystrixDashboardStream.DashboardData>() {
@Override
public void call(HystrixDashboardStream.DashboardData dashboardData) {
//do something
}
});

2 HystrixDashboard设计

Read More

InfluxDB写入失败-partial write: max-values-per-tag limit exceeded

最近线上向InfluxDB写入数据突然报错,大概意思是tag的值超限,详细错误信息:

1
2
3
4
5
6
7
8
9
10
11
2016-12-02 20:47:11.485 [] [] [] ERROR c.y.t.p.m.m.i.OrderCreateMonitorManageImpl - InfluxDB写入异常!influxDO=InfluxDO(measurement=com.XXX.trade.create.request.result, timeStamp=1480682831481, tagKeyList=[cluster, host, count_time, count, count_type], tagValList=[DEFAULT_CLUSTER, xxx-inc.com, 1480682831481, 3, bill_new], fieldKeyList=[result, cost], fieldValList=[true, 112]), exception={}
java.lang.RuntimeException: {"error":"partial write: max-values-per-tag limit exceeded (100000/100000): measurement=\"com.XXX.trade.create.request.result\" tag=\"count_time\" value=\"count_time\" dropped=1"}
at org.influxdb.impl.InfluxDBImpl.execute(InfluxDBImpl.java:266) ~[influxdb-java-2.4.jar:na]
at org.influxdb.impl.InfluxDBImpl.write(InfluxDBImpl.java:167) ~[influxdb-java-2.4.jar:na]
at org.influxdb.impl.InfluxDBImpl.write(InfluxDBImpl.java:157) ~[influxdb-java-2.4.jar:na]
at com.XXX.trade.process.monitor.dal.impl.InfluxDBDAOImpl.insert(InfluxDBDAOImpl.java:104) ~[trade-process-service-1.0.0-SNAPSHOT.jar:na]
at com.XXX.trade.process.monitor.manage.impl.OrderCreateMonitorManageImpl.save(OrderCreateMonitorManageImpl.java:40) ~[trade-process-service-1.0.0-SNAPSHOT.jar:na]
at com.XXX.trade.process.nsq.processor.impl.MonitorProcessor.process(MonitorProcessor.java:69) [trade-process-service-1.0.0-SNAPSHOT.jar:na]
at com.XXX.trade.process.nsq.NSQSubscriber.lambda$init$0(NSQSubscriber.java:71) [trade-process-service-1.0.0-SNAPSHOT.jar:na]
at com.XXX.trade.process.nsq.NSQSubscriber$$Lambda$8/1829287142.process(Unknown Source) [trade-process-service-1.0.0-SNAPSHOT.jar:na]

Google搜索了下,这是InfluxDB v1.1.0 [2016-11-14]版本新加的一个特性(CHANGELOG.md):

Read More

RocketMQ源码学习之四-PushConsumer

本文主要讲解RocketMQ的push消息消费者的实现原理。

1 RocketMQ的两种消息消费者

RocketMQ支持两种形式的消息消费者:

  • Push Consumer
    通常是应用向Consumer对象注册一个Listener,一旦收到消息,Consumer对象立即回调Listener接口方法。底层采用的是Pull长轮询拉取消息的方式。
  • Pull Consumer
    应用通常主动调用Consumer的拉消息方法从Broker拉消息,主动权由应用控制。

2 Push Consumer的一个demo

Read More

RocketMQ源码学习之三-异步消息发送

本文主要介绍RocketMQ异步消息发送的原理。

1 异步消息发送Demo

首先看一段RocketMQ异步消息发送的Demo代码:
消息生产者:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import com.alibaba.rocketmq.client.exception.MQClientException;
import com.alibaba.rocketmq.client.producer.DefaultMQProducer;
import com.alibaba.rocketmq.common.message.Message;
import com.SpringTest.rocketmq.callback.MySendCallback;
public class Producer3 {
public static void main(String[] args) throws MQClientException, InterruptedException {
DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName");
producer.setNamesrvAddr("192.168.2.104:9876");
producer.setInstanceName("Producer3");
producer.start();
for (int i = 0; i < 1; i++)
try {
{
Message msg = new Message("TopicTest",// topic
"TagA",// tag
"OrderID188",// key
("Hello MetaQ").getBytes());// body
producer.send(msg, new MySendCallback());
}
}
catch (Exception e) {
e.printStackTrace();
}
producer.shutdown();
}
}

Read More

RocketMQ源码学习之二-同步消息发送

本文讲述RocketMQ同步发送消息的原理。

1 消息生产者demo

先看一段同步发送消息的demo代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import com.alibaba.rocketmq.client.exception.MQClientException;
import com.alibaba.rocketmq.client.producer.DefaultMQProducer;
import com.alibaba.rocketmq.client.producer.SendResult;
import com.alibaba.rocketmq.common.message.Message;
public class Producer1 {
public static void main(String[] args) throws MQClientException, InterruptedException {
DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName");
producer.setNamesrvAddr("192.168.2.101:9876");
producer.setInstanceName("Producer1");
producer.start();
for (int i = 0; i < 1; i++)
try {
{
Message msg = new Message("TopicTest",// topic
"TagA",// tag
"OrderID188",// key
("Hello MetaQ").getBytes());// body
SendResult sendResult = producer.send(msg);
System.out.println(sendResult);
}
}
catch (Exception e) {
e.printStackTrace();
}
producer.shutdown();
}
}

Read More

RocketMQ源码学习之一-MAC单机环境搭建

本文讲述如何在单机(MAC)上搭建RocketMQ环境,实现正常收发消息。

1 安装JDK、maven等工具

忽略。

2 部署RocketMQ服务端

https://github.com/alibaba/RocketMQ下载压缩包,并解压。

Read More