背景:
公司使用阿里云的云数据库MongoDB。基于安全原因考虑,阿里云MongoDB云数据库目前只支持从阿里云ECS上访问,无法通过公网直接访问,不方便用户在本地开发环境里直接进行测试。
阿里云官方推荐使用rinetd搭建跳板系统,实现公网访问云mongo。使用过程中,发现,python程序在使用过程中如果没有正确释放连接,即使python程序退出后,该mongo连接仍然被rinetd占用。曾出现调用该地址的python程序全部退出后,rinetd仍占用100多个连接,导致云mongo可用连接数不足。此时,需要重启rinetd方可释放被占用的连接。
最终使用本机ssh连接阿里云ECS,再从该主机使用私网连接到mongo的方法,实现云mongo公网访问。这种方法可以使开发环境中的robomongo连接到mongo。
python连接云mongo:
1 依赖
python -m pip install sshtunnel==0.1.2
2 demo
1 # -*- coding:utf-8 -*- 2 from __future__ import unicode_literals 3 4 import pymongo 5 from sshtunnel import SSHTunnelForwarder 6 7 8 def get_aliyun_mongo_client(only_read=True): 9 # 跳板机参数 10 ecs_host = "<ecs ip>" 11 ecs_user = "<ecs user>" 12 ecs_password = "<ecs password>" 13 14 # 云mongo 配置 15 aliyun_mongo_master_host = "<mongo 副本集 主服务器>" 16 aliyun_mongo_slave_host = "<mongo 副本集 副本>" 17 aliyun_mongo_database = "<mongo 数据库>" 18 aliyun_mongo_account = "<mongo 账号>" 19 aliyun_mongo_password = "<mongo 密码>" 20 21 host = aliyun_mongo_slave_host if only_read else aliyun_mongo_master_host 22 server = SSHTunnelForwarder( 23 (ecs_host, 22), 24 ssh_password=ecs_password, 25 ssh_username=ecs_user, 26 remote_bind_address=(host, 3717)) 27 28 server.start() 29 30 client = pymongo.MongoClient(‘127.0.0.1‘, server.local_bind_port) 31 mongo_database = client[aliyun_mongo_database] 32 mongo_database.authenticate(aliyun_mongo_account, aliyun_mongo_password) 33 34 return client 35 36 37 if __name__ == ‘__main__‘: 38 mongo_client = get_aliyun_mongo_client(only_read=False) 39 mongo_client["Test"]["ssh_test"].insert({"msg": "Hello World!"}) 40 mongo_client.close()