背景:项目需要,合作方只提供线上mongo集群,不提供线下mongo集群。为了测试,需要自己搭建一套本地的mongo replicaSet。
过程:看完mongo官方文档,搭建一个replicaSet至少需要2-3台机器。虽然我的mac上装了3台虚拟机ubuntu14,centos7,windowXp,但是考虑到虚拟机的开销,并不值得为了三个mongo实例打开二三个虚拟机。因而想到了docker,考虑到最近的流行度,顺便也尝试一下。
决定用docker之后,先简单在官网学习下docker的基础概念,再配合之前的了解,大概能够动手做。然后找到一个用docker搭建mongo replicSet的教程,按步骤操作。这个过程有点坎坷,但基本没问题。做好之后,命令行都可以连接,但是php里用mongoclient无法连接,提示
“no candicate server found”
Google之,最终定位是代码内提供的主机名与mongo server返回的主机名不同,因而mongoclient主动断开了连接。
定位到问题后,考虑如何解决,既然是主机名的问题,统一就好。需要说明的是,代码里给的是ip:port,而且是类似如下
127.0.0.1:36739
docker container内的mongo服务是通过端口映射暴露到mac的,这样,mac通过本地端口就能访问到container内的mongo服务。但是container内部,注册的ip是内网IP,“172.16.x.x”,而主机名也是随机生成的(container返回的实例ID)
首先考虑,只要都写成一样的主机名就行了,尝试把container的主机名写到mac的host中,绑定127.0.0.1,然后代码内直接写主机名就行,如
“xxxxxxx:36275"
这样就能转发到mac,mac在转发到container内的mongo。
但这样子依然不行。错误依然。
这时候考虑到,mongoclient连接mongo服务,服务返回的主机名可能并不是mongo服务所在主机的主机名,而是mongo配置内写入的主机名。这个主机名可以是ip:port, 也可以是domain:port, 只要是可以正常访问的mongo服务即可。
依此,尝试修改mongo配置内的host字段,改为“xxxxx:27017",失败告终,没有成功修改。但其实,即便成功了,也可能返回一样的错误,因为端口无法一样,container内部是27017,而暴露到mac的是367xx,代码里写的必然是367xx。因而整个domain:port串还是不一样。
这时,我开始怀疑mongoclient连接mongo replica返回的host到底是什么,到底为什么不一样。如果不能确定这个问题,我就不能继续往下研究。因而我尝试找到这个实际的值。
第一个想法是日志,查文档,打开mongoclient的详细日志,但依然没看到什么,可能是我的配置方法不对。继续考虑别的方案。想到我可以在c的层面debug mongoclient。因为之前debug过php的src code,因而对这样方案,我确定是有可行性的,只要我能坚持。
确定了debug mongoclient extension之后,google如何debug 扩展。http://istrone.com/?p=1343