背景:
公司使用阿里雲的雲數據庫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
# -*- coding:utf-8 -*- from __future__ import unicode_literals import pymongo from sshtunnel import SSHTunnelForwarder class AliyunMongoDebug(object): def __init__(self): self._record = {} def get_aliyun_mongo_client(self, only_read=True): # 跳板機參數 ecs_host = "<ecs ip>" ecs_user = "<ecs user>" ecs_password = "<ecs password>" # 雲mongo 配置 aliyun_mongo_master_host = "<mongo 副本集 主服務器>" aliyun_mongo_slave_host = "<mongo 副本集 副本>" aliyun_mongo_database = "<mongo 數據庫>" aliyun_mongo_account = "<mongo 賬號>" aliyun_mongo_password = "<mongo 密碼>" host = aliyun_mongo_slave_host if only_read else aliyun_mongo_master_host server = SSHTunnelForwarder( (ecs_host, 22), ssh_password=ecs_password, ssh_username=ecs_user, remote_bind_address=(host, 3717)) server.start() client = pymongo.MongoClient('127.0.0.1', server.local_bind_port) mongo_database = client[aliyun_mongo_database] mongo_database.authenticate(aliyun_mongo_account, aliyun_mongo_password) self._record[client] = server return client def return_aliyun_mongo_client(self, client): if client in self._record: server = self._record.pop(client) else: server = None client.close() if server: server.close() if __name__ == '__main__': mongo_debug_manager = AliyunMongoDebug() mongo_client = None try: mongo_client = mongo_debug_manager.get_aliyun_mongo_client(only_read=False) mongo_client["Test"]["ssh_test"].insert({"msg": "Hello World!"}) finally: if mongo_client: mongo_debug_manager.return_aliyun_mongo_client(mongo_client)