前面讨论了peer的启动,但都没有讨论完peer node start的全过程。本文继续跟着讨论。

我们在上文分析了serve的第一行代码,现在接着往下看。

devmode

刚开始显示了如果是开发模式的话,就设置相关的内容 没有啥内容,就不做详细分析了。

缓存配置

fabric为了使处理速度更快,就对一些常用的内容做了缓存,就是调用这个函数进行处理

1
2
3
	if err := peer.CacheConfiguration(); err != nil {
		return err
	}

具体的是得看函数内容的定义。

 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
func CacheConfiguration() (err error) {
	getLocalAddress := func() (peerAddress string, err error) {
		if viper.GetBool("peer.addressAutoDetect") {	
			_, port, err := net.SplitHostPort(viper.GetString("peer.address"))
			if err != nil {
				err = fmt.Errorf("Error auto detecting Peer's address: %s", err)
				return "", err
			}
			peerAddress = net.JoinHostPort(GetLocalIP(), port)
			peerLogger.Infof("Auto detected peer address: %s", peerAddress)
		} else {
			peerAddress = viper.GetString("peer.address")
		}
		return
	}

	getPeerEndpoint := func() (*pb.PeerEndpoint, error) {
		var peerAddress string
		peerAddress, err := getLocalAddress()
		if err != nil {
			return nil, err
		}
		return &pb.PeerEndpoint{Id: &pb.PeerID{Name: viper.GetString("peer.id")}, Address: peerAddress}, nil
	}

	localAddress, localAddressError = getLocalAddress()
	peerEndpoint, _ = getPeerEndpoint()

	configurationCached = true

	if localAddressError != nil {
		return localAddressError
	}
	return
}

实际上并不是多复杂。 显示定义了两个内部函数,需要的数据填充上去,就结束了。为什么要定义两个内部函数,注释说的原因是为了保持程序结构的abstract,好吧。 这几个常用的内容被定义成了全局变量

1
2
3
4
5
var configurationCached = false
var localAddress string
var localAddressError error
var peerEndpoint *pb.PeerEndpoint
var peerEndpointError error

这几个就是我们会经常使用的变量了。第一个是用来判断是否已经数据处理过的。 现在看一看获取本机地址的函数。这个段代码不复杂,首先从core.yaml文件读取是否自动检测本机地址。 如果需要检测的话,就调用go内部的net接口转换出来。如果不需要检测的话就用配置文件中的默认地址。 经查看,文件中设置的addressAutoDetect设置的是不自动检测,默认地址是0.0.0.0:7051.所以嘛,那么多自己判断的没什么意义。 再来看下获取peer的端点的ip地址,就是调用我们刚刚定义的函数,生成proto所需要的类型。 然后就是记录下已经修改过配置,返回内容,结束。

ip端口等设置

经过了刚刚的缓存,接下来就是读取相应的配置信息了。

1
2
3
4
5
6
7
peerEndpoint, err := peer.GetPeerEndpoint()
	if err != nil {
		err = fmt.Errorf("Failed to get Peer Endpoint: %s", err)
		return err
	}

	listenAddr := viper.GetString("peer.listenAddress")

没有什么值得注意的,很简单,其中listenAddr就是0.0.0.0:7051,这个端口就是七佛那个服务监听的地址。

安全配置

由于peer需要跟client和order进行通信,肯定需要确定需要不要tls,对应的证书等文件。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
secureConfig, err := peer.GetSecureConfig()
	if err != nil {
		logger.Fatalf("Error loading secure config for peer (%s)", err)
	}
	peerServer, err := peer.CreatePeerServer(listenAddr, secureConfig)
	if err != nil {
		logger.Fatalf("Failed to create peer server (%s)", err)
	}

	if secureConfig.UseTLS {
		logger.Info("Starting peer with TLS enabled")
		// set up CA support
		caSupport := comm.GetCASupport()
		caSupport.ServerRootCAs = secureConfig.ServerRootCAs
	}

一堆log日志,没什么用。第一句

1
GetSecureConfig()

是获取安全配置,如果启用tls通信,就加载对应的证书文件,然而fabric并没有启动。 下面的createPeerServer是重点了,创建监听服务器。看下函数怎么写的

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
func CreatePeerServer(listenAddress string,
	secureConfig comm.SecureServerConfig) (comm.GRPCServer, error) {

	var err error
	peerServer, err = comm.NewGRPCServer(listenAddress, secureConfig)
	if err != nil {
		peerLogger.Errorf("Failed to create peer server (%s)", err)
		return nil, err
	}
	return peerServer, nil
}

核心就一句:

1
peerServer, err = comm.NewGRPCServer(listenAddress, secureConfig)

创建了grpc服务,调用开始进行函数处理。 好吧,不会GRPC啊! 下面的代码也开始跟rpc相关了! 溜溜溜!看一看grpc再继续学!