GeoServer 集群及Nas共享数据部署

一、前言

由于官网与网上Geoserver各种部署文章参次不齐,以至于我们团队小鹭科技使用Geo共享数据及集群部署时遇到了很多困难。为了让大家少走弯路这也是写这篇文章的初衷。

二、安装并配置数据共享

1. 安装JDK 1.8
由于本文主要扯的是Geo的部署,所以安装JDK及环境变量配置自行百度。

2. 创建文件夹并挂载NAS
通过 NAS(本质上不通过NAS一样可以,配置NAS是为了集群做数据共享) 指定 geoserver数据存储/缓存目录

mkdir /data  
# 挂载NAS
mount xxxxx:/volume2/nfs1 /data
# 设置开机自动挂载
vim /etc/fstab
#在内容后方写入以下内容
 xxxx:/volume2/nfs /data nfs nolock 0 0

3. 下载 Geoserver 并解压启动Geoserver

wget  https://sourceforge.net/projects/geoserver/files/GeoServer/2.16.2/geoserver-2.16.2-bin.zip
# 依据官方建议将程序解压到 /usr/share 目录中
unzip geoserver-2.16.2-bin.zip -d /usr/share/
# 重命名,不要问为什么命名为geoserver01 看到后面你就知道了
mvgeoserver-2.16.2 geoserver01
# 进入 geoserver01通过 bin/ startup.sh 启动geoserver
cd  /usr/share/geoserver01/bin &&  sh startup.sh
# 至此Geoserver就启动了 通过访问 IP:8080/geoserver 即可。默认账号密码 admin/geoserver

4. 配置数据目录的两种方案

在/usr/share/geoserver-2.16.2目录中进入 webapps/geoserver/WEB-INF 目录打开 web.xml 文件往下滑动可以
看见以下图片内容:
<context-param>
<param-name>GEOSERVER_DATA_DIR</param-name>
<param-value>/data/geoserver/data</param-value>
</context-param>

即可在不同的服务器中实现指定数据目录,但是这种方式牵涉到需要调整web服务器的内容并不建议这样简单粗暴的进行处理。
经过对官方文档的以及google的查询,发现Geo本身也支持以环境变量的形式对数据存储、缓存进行指定路径
我们打开bin/startup.sh 文件可以看到以下内容:

#!/bin/sh
# -----------------------------------------------------------------------------
# Start Script for GEOSERVER
#
# $Id$
# -----------------------------------------------------------------------------

# Guard against misconfigured JAVA_HOME
if [ ! -z "$JAVA_HOME" -a ! -x "$JAVA_HOME"/bin/java ]; then
  echo "The JAVA_HOME environment variable is set but JAVA_HOME/bin/java"
  echo "is missing or not executable:"
  echo "    JAVA_HOME=$JAVA_HOME"
  echo "Please either set JAVA_HOME so that the Java runtime is JAVA_HOME/bin/java"
  echo "or unset JAVA_HOME to use the Java runtime on the PATH."
  exit 1
fi

# Find java from JAVA_HOME or PATH
if [ ! -z "$JAVA_HOME" ]; then
  _RUNJAVA="$JAVA_HOME"/bin/java
elif [ ! -z "$(which java)" ]; then
  _RUNJAVA=java
else
  echo "A Java runtime (java) was not found in JAVA_HOME/bin or on the PATH."
  echo "Please either set the JAVA_HOME environment variable so that the Java runtime"
  echo "is JAVA_HOME/bin/java or add the Java runtime to the PATH."
  exit 1
fi

if [ -z $GEOSERVER_HOME ]; then
  #If GEOSERVER_HOME not set then guess a few locations before giving
  # up and demanding user set it.
  if [ -r start.jar ]; then
     echo "GEOSERVER_HOME environment variable not found, using current "
     echo "directory.  If not set then running this script from other "
     echo "directories will not work in the future."
     export GEOSERVER_HOME=`pwd`
  else
    if [ -r ../start.jar ]; then
      echo "GEOSERVER_HOME environment variable not found, using current "
      echo "location.  If not set then running this script from other "
      echo "directories will not work in the future."
      export GEOSERVER_HOME=`pwd`/..
    fi
  fi

  if [ -z "$GEOSERVER_HOME" ]; then
    echo "The GEOSERVER_HOME environment variable is not defined"
    echo "This environment variable is needed to run this program"
    echo "Please set it to the directory where geoserver was installed"
    exit 1
  fi

fi
#!/bin/sh
# -----------------------------------------------------------------------------
# Start Script for GEOSERVER
#
# $Id$
# -----------------------------------------------------------------------------
# Guard against misconfigured JAVA_HOME
if [ ! -z "$JAVA_HOME" -a ! -x "$JAVA_HOME"/bin/java ]; then
  echo "The JAVA_HOME environment variable is set but JAVA_HOME/bin/java"
  echo "is missing or not executable:"
  echo "    JAVA_HOME=$JAVA_HOME"
  echo "Please either set JAVA_HOME so that the Java runtime is JAVA_HOME/bin/java"
  echo "or unset JAVA_HOME to use the Java runtime on the PATH."
  exit 1
fi

# Find java from JAVA_HOME or PATH
if [ ! -z "$JAVA_HOME" ]; then
  _RUNJAVA="$JAVA_HOME"/bin/java
elif [ ! -z "$(which java)" ]; then
  _RUNJAVA=java
else
  echo "A Java runtime (java) was not found in JAVA_HO
if [ ! -r "$GEOSERVER_HOME"/bin/startup.sh ]; then
  echo "The GEOSERVER_HOME environment variable is not defined correctly"
  echo "This environment variable is needed to run this program"
  exit 1
fi

#Find the configuration directory: GEOSERVER_DATA_DIR
if [ -z $GEOSERVER_DATA_DIR ]; then
    if [ -r "$GEOSERVER_HOME"/data_dir ]; then
        export GEOSERVER_DATA_DIR="$GEOSERVER_HOME"/data_dir
    else
        echo "No GEOSERVER_DATA_DIR found, using application defaults"
              GEOSERVER_DATA_DIR=""
    fi
fi

cd "$GEOSERVER_HOME"

if [ -z $MARLIN_JAR]; then
    export MARLIN_JAR=`find \`pwd\`/webapps -name "marlin*.jar" | head -1`
    export MARLIN_ENABLER="-Xbootclasspath/a:$MARLIN_JAR -Dsun.java2d.renderer=org.marlin.pisces.MarlinRenderingEngine"
fi

echo "GEOSERVER DATA DIR is $GEOSERVER_DATA_DIR"
#added headless to true by default, if this messes anyone up let the list
#know and we can change it back, but it seems like it won't hurt -ch
exec "$_RUNJAVA" $JAVA_OPTS $MARLIN_ENABLER -DGEOSERVER_DATA_DIR="$GEOSERVER_DATA_DIR" -Djava.awt.headless=true -DSTOP.PORT=8079 -DSTOP.KEY=geoserver -jar start.jar 
  • 第一种方案 - 配置环境变量

通过以上脚本内容基本我们确定通过系统环境变量可以实现设置数据目录、设置缓存目录、设置Geo环境变量:

# 通过编辑 ~./profile  
vim ~/.profile  
# 在结尾处增加以下内容
# 设置数据目录
export GEOSERVER_DATA_DIR=/data/geoserver/data_dir
# 设置缓存目录
export GEOWEBCACHE_CACHE_DIR=/data/geoserver/geowebcache
# 使环境变量生效
source ~/.profile
# 将geoserver01 目录下的 data_dir 移动到 /data/geoserver/目录下
mv /usr/share/geoserver01/data_dir /data/geoserver/
# sh startup.sh 启动 GeoServer 方法与第三步一致。
  • 第二种方案 - Jetty 配置

Jetty start.ini
# 通过编辑 start.ini  
# 在结尾处增加以下内容
# 设置数据目录
-DGEOSERVER_DATA_DIR=/data/geoserver/data_dir
# 设置缓存目录
-DGEOWEBCACHE_CACHE_DIR=/data/geoserver/geowebcache

三、配置集群 Peer-to-peer

1. 下载集群扩展jar包

# 下载集群扩展jar包
wget https://build.geoserver.org/geoserver/2.16.x/community-latest/geoserver-2.16-SNAPSHOT-jms-cluster-plugin.zip 
# 解压至
unzip  geoserver-2.16-SNAPSHOT-jms-cluster-plugin.zip -d /usr/share/geoserver01/webapps/geoserver/WEB-INF/lib/

2. 新增 Geoserver 实例

  • 复制实例
# 复制实例
cp   geoserver01  geoserver02
  • 修改不同节点端口
# 通过编辑 start.ini  
vim start.ini 
# 找到  jetty.port 调整为你指定的端口
 jetty.port=8080

3.集群配置
需要注意的点:不同节点之间同上方调整端口一样需DCLUSTER_CONFIG_DIR指向不同目录

# 通过编辑 start.ini  
# 在结尾处增加以下内容
# 设置集群配置
-DCLUSTER_CONFIG_DIR=/data/data_dir/cluster/01

3.启动Geoserver

cd /usr/share/geoserver01/bin
nohup ./startup.sh &

启动之后在/data/data_dir/cluster/01 会生成以下内容:

├── cluster.properties
├── embedded-broker.properties
└── kahadb
    ├── db-1.log
    ├── db.data
    ├── db.redo
    └── lock

下载 broker.xml 并 复制到/data/data_dir/cluster/01
PS:其他节点以此类推

5.再次启动Geoserver

#第一个节点
cd /usr/share/geoserver01/bin
nohup ./startup.sh &
#第二个节点
cd /usr/share/geoserver02/bin
nohup ./startup.sh &

四、通过浏览器访问并测试

通过不同浏览器访问 localhost:8080/geoserver
通过不同浏览器访问 localhost:8081/geoserve

- 拓展集群UI

image.png

- 测试删除结果

image.png

image.png

image.png

五、结语

5.1. 注意事项

  1. 同一台服务器两个不同的实例需要将端口号进行调整,不同服务器则不用。
  2. 使用p2p 的方式不同的服务器之间需要开启多播网络发现。
  3. 不太建议使用tomcat的形式去启动geoserver。

5.2. 本次使用的是 嵌入式代理和共享数据目录的对等网络的方式

  • 每个GeoServer实例将运行一个嵌入式代理
  • 每个GeoServer实例将在不打开端口的情况下与其自己的嵌入式代理通信,而直接在同一VM进程中
  • 每个代理将自动发现同一网络上的其他代理,并绑定到它们以创建代理网络(充当单个容错代理)
  • 发送给代理的消息将被传递到同一网络中的所有其他代理
  • .GeoServer实例可以动态加入和离开网络


    GeoServer实例的P2P集群

5.3. 参考文档