使用Docker和虚拟IP在一台服务器上灵活部署多个Neo4j实例
前言
在现代应用开发中,图数据库Neo4j因其强大的关系处理能力而备受青睐。但有时候我们需要在同一台服务器上运行多个Neo4j实例,比如用于开发测试、多租户环境或者A/B测试。传统的端口映射方式需要修改大量配置,而使用虚拟IP方案则更加优雅和灵活。
本文将介绍如何使用Docker和虚拟IP技术,在一台服务器上部署多个Neo4j实例,并实现按需启动的灵活管理。
方案优势
- 端口一致性:所有实例使用相同的标准端口(7474/7687)
- IP隔离:通过不同虚拟IP地址区分实例
- 灵活启动:可根据资源情况按需启动单个或多个实例
- 配置简单:使用Docker Compose和环境变量管理
- 性能优化:使用主机网络模式,减少网络开销
环境准备
首先确保服务器已安装Docker和Docker Compose:
步骤一:配置虚拟IP
在服务器上设置两个虚拟IP地址:
# 添加虚拟IP(根据实际网卡名称调整,通常是ens33或ens33)
sudo ip addr add 192.168.10.100/24 dev ens33
sudo ip addr add 192.168.10.101/24 dev ens33
# 验证IP配置
ip addr show ens33
# 设置开机自动添加虚拟IP(可选)
echo 'ip addr add 192.168.10.100/24 dev ens33' | sudo tee -a /etc/rc.local
echo 'ip addr add 192.168.10.101/24 dev ens33' | sudo tee -a /etc/rc.local
sudo chmod +x /etc/rc.local
步骤二:创建项目结构
创建项目目录并组织文件结构:
mkdir neo4j-cluster
cd neo4j-cluster
mkdir -p {data1,data2,logs1,logs2,import1,import2}
步骤三:配置环境变量
创建 .env
配置文件:
# Neo4j实例启动控制
START_INSTANCE1=true
START_INSTANCE2=false
# 虚拟IP配置
VIP1=192.168.10.100
VIP2=192.168.10.101
# Neo4j认证信息
NEO4J_PASSWORD1=password1
NEO4J_PASSWORD2=password2
# 公共配置
NEO4J_VERSION=5.13.0
步骤四:创建Docker Compose配置
创建 docker compose.yml
文件:
version: '3.8'
services:
neo4j-instance1:
image: neo4j:${NEO4J_VERSION}
container_name: neo4j-instance1
network_mode: host
environment:
- NEO4J_AUTH=neo4j/${NEO4J_PASSWORD1}
- NEO4J_apoc_export_file_enabled=true
- NEO4J_apoc_import_file_enabled=true
- NEO4J_apoc_import_file_use__neo4j__config=true
- NEO4JLABS_PLUGINS=["apoc"]
- NEO4J_server_bolt_listen__address=${VIP1}:7687
- NEO4J_server_http_listen__address=${VIP1}:7474
- NEO4J_server_https_listen__address=${VIP1}:7473
volumes:
- ./data1:/data
- ./logs1:/logs
- ./import1:/var/lib/neo4j/import
restart: unless-stopped
profiles: ["instance1"]
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://${VIP1}:7474"]
interval: 30s
timeout: 10s
retries: 3
neo4j-instance2:
image: neo4j:${NEO4J_VERSION}
container_name: neo4j-instance2
network_mode: host
environment:
- NEO4J_AUTH=neo4j/${NEO4J_PASSWORD2}
- NEO4J_apoc_export_file_enabled=true
- NEO4J_apoc_import_file_enabled=true
- NEO4J_apoc_import_file_use__neo4j__config=true
- NEO4JLABS_PLUGINS=["apoc"]
- NEO4J_server_bolt_listen__address=${VIP2}:7687
- NEO4J_server_http_listen__address=${VIP2}:7474
- NEO4J_server_https_listen__address=${VIP2}:7473
volumes:
- ./data2:/data
- ./logs2:/logs
- ./import2:/var/lib/neo4j/import
restart: unless-stopped
profiles: ["instance2"]
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://${VIP2}:7474"]
interval: 30s
timeout: 10s
retries: 3
步骤五:管理脚本
创建管理脚本 manage-neo4j.sh
:
#!/bin/bash
set -e
# 加载环境变量
if [ -f .env ]; then
export $(cat .env | grep -v '#' | awk '/=/ {print $1}')
fi
case "$1" in
"start")
echo "正在启动Neo4j实例..."
if [ "$START_INSTANCE1" = "true" ]; then
echo "启动实例1 (${VIP1})..."
docker compose --profile instance1 up -d
fi
if [ "$START_INSTANCE2" = "true" ]; then
echo "启动实例2 (${VIP2})..."
docker compose --profile instance2 up -d
fi
;;
"stop")
echo "正在停止Neo4j实例..."
docker compose down
;;
"restart")
echo "正在重启Neo4j实例..."
$0 stop
sleep 2
$0 start
;;
"status")
echo "Neo4j实例状态:"
docker ps --filter "name=neo4j-instance"
;;
"logs")
shift
docker compose logs $@
;;
"config")
echo "当前配置:"
echo "实例1: START_INSTANCE1=$START_INSTANCE1, VIP=$VIP1"
echo "实例2: START_INSTANCE2=$START_INSTANCE2, VIP=$VIP2"
;;
"update-env")
shift
if [ "$1" = "instance1" ]; then
sed -i "s/START_INSTANCE1=.*/START_INSTANCE1=$2/" .env
elif [ "$1" = "instance2" ]; then
sed -i "s/START_INSTANCE2=.*/START_INSTANCE2=$2/" .env
else
echo "用法: $0 update-env {instance1|instance2} {true|false}"
fi
;;
*)
echo "用法: $0 {start|stop|restart|status|logs|config|update-env}"
echo ""
echo "命令说明:"
echo " start 启动配置的实例"
echo " stop 停止所有实例"
echo " restart 重启实例"
echo " status 查看实例状态"
echo " logs 查看日志"
echo " config 显示当前配置"
echo " update-env 更新启动配置"
exit 1
;;
esac
给脚本执行权限:
chmod +x manage-neo4j.sh
步骤六:使用和管理
启动实例
如docker compose不可用,可以替换为docker compose
# 查看当前配置
./manage-neo4j.sh config
# 启动配置的实例
./manage-neo4j.sh start
# 查看状态
./manage-neo4j.sh status
动态调整配置
# 只启动实例1
./manage-neo4j.sh update-env instance1 true
./manage-neo4j.sh update-env instance2 false
./manage-neo4j.sh restart
# 只启动实例2
./manage-neo4j.sh update-env instance1 false
./manage-neo4j.sh update-env instance2 true
./manage-neo4j.sh restart
# 启动两个实例(资源充足时)
./manage-neo4j.sh update-env instance1 true
./manage-neo4j.sh update-env instance2 true
./manage-neo4j.sh restart
访问实例
- 实例1: http://192.168.10.100:7474 (用户名: neo4j, 密码: password1)
- 实例2: http://192.168.10.101:7474 (用户名: neo4j, 密码: password2)
故障排除
虚拟IP无法访问
# 检查虚拟IP是否设置
ip addr show ens33
# 检查防火墙规则
sudo ufw status
sudo ufw allow from any to 192.168.10.100 port 7474,7687
sudo ufw allow from any to 192.168.10.101 port 7474,7687
端口冲突
如果端口已被占用,可以检查并终止冲突进程:
sudo lsof -i :7474
sudo lsof -i :7687