使用Docker和虚拟IP在一台服务器上灵活部署多个Neo4j实例

发布于:2025-09-15 ⋅ 阅读:(21) ⋅ 点赞:(0)

使用Docker和虚拟IP在一台服务器上灵活部署多个Neo4j实例

前言

在现代应用开发中,图数据库Neo4j因其强大的关系处理能力而备受青睐。但有时候我们需要在同一台服务器上运行多个Neo4j实例,比如用于开发测试、多租户环境或者A/B测试。传统的端口映射方式需要修改大量配置,而使用虚拟IP方案则更加优雅和灵活。

本文将介绍如何使用Docker和虚拟IP技术,在一台服务器上部署多个Neo4j实例,并实现按需启动的灵活管理。

方案优势

  • 端口一致性:所有实例使用相同的标准端口(7474/7687)
  • IP隔离:通过不同虚拟IP地址区分实例
  • 灵活启动:可根据资源情况按需启动单个或多个实例
  • 配置简单:使用Docker Compose和环境变量管理
  • 性能优化:使用主机网络模式,减少网络开销

环境准备

首先确保服务器已安装Docker和Docker Compose:

点击进入docker安装方法

步骤一:配置虚拟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