第04章-目录与配置管理
第四章:目录与配置管理
4.1 引言
GeoServer 的核心是其目录(Catalog)系统,它管理着所有的配置信息,包括工作区、数据存储、图层、样式等。在传统的单体 GeoServer 中,这些配置通常存储在"数据目录"(Data Directory)的 XML 文件中。然而,在 GeoServer Cloud 的分布式环境中,需要所有服务实例能够共享和同步配置信息,这就需要更加健壮的目录后端解决方案。
本章将深入介绍 GeoServer Cloud 支持的各种目录后端,重点讲解推荐的 PGConfig(PostgreSQL)后端的配置和使用,同时也会介绍外部化配置的各种方法和最佳实践。
4.2 GeoServer Catalog 概念
4.2.1 Catalog 的作用
Catalog 是 GeoServer 的核心配置存储系统,包含以下主要内容:
Catalog
├── 工作区(Workspaces)
│ └── 命名空间(Namespaces)
├── 数据存储(Stores)
│ ├── 数据存储(DataStores) - 矢量数据
│ ├── 覆盖存储(CoverageStores) - 栅格数据
│ └── WMS/WMTS 存储 - 级联服务
├── 资源(Resources)
│ ├── 要素类型(FeatureTypes)
│ └── 覆盖(Coverages)
├── 图层(Layers)
├── 图层组(LayerGroups)
├── 样式(Styles)
├── 服务配置(Service Configurations)
│ ├── WMS 配置
│ ├── WFS 配置
│ └── ...
└── 安全配置(Security)
├── 用户(Users)
├── 角色(Roles)
└── 访问规则(Access Rules)
4.2.2 配置对象关系
理解 Catalog 中各对象的关系对于正确配置 GeoServer 至关重要:
Workspace(工作区)
│
├── Namespace(命名空间)1:1 关系
│
├── DataStore(数据存储)
│ │
│ └── FeatureType(要素类型)
│ │
│ └── Layer(图层)
│
└── CoverageStore(覆盖存储)
│
└── Coverage(覆盖)
│
└── Layer(图层)
Style(样式)──────────┘
可被多个图层引用
4.2.3 传统数据目录结构
传统 GeoServer 的数据目录结构如下:
GEOSERVER_DATA_DIR/
├── global.xml # 全局配置
├── logging.xml # 日志配置
├── workspaces/ # 工作区目录
│ └── myworkspace/
│ ├── namespace.xml
│ ├── workspace.xml
│ └── mystore/
│ ├── datastore.xml
│ └── mylayer/
│ ├── featuretype.xml
│ └── layer.xml
├── styles/ # 样式目录
│ ├── default_point.sld
│ └── mystyle.sld
├── layergroups/ # 图层组
├── gwc/ # GeoWebCache 配置
├── security/ # 安全配置
│ ├── config.xml
│ ├── layers.properties
│ ├── services.properties
│ └── usergroup/
│ └── users.xml
└── www/ # Web 资源
4.3 目录后端选择
4.3.1 后端对比
GeoServer Cloud 支持三种目录后端,各有特点:
| 特性 | PGConfig | DataDir | JDBCConfig |
|---|---|---|---|
| 推荐度 | ★★★★★ | ★★★☆☆ | ★☆☆☆☆ |
| 可扩展性 | 优秀 | 一般 | 一般 |
| 一致性 | 强一致 | 最终一致 | 最终一致 |
| 性能 | 高 | 中 | 低 |
| 维护状态 | 活跃开发 | 维护 | 已弃用 |
| 适用场景 | 生产环境 | 开发测试 | 遗留兼容 |
4.3.2 选择建议
PGConfig(推荐)
适用于:
- 生产环境部署
- 需要高可用和扩展性
- 多实例部署
优势:
- 专为 GeoServer Cloud 设计
- 强一致性保证
- 高性能查询
- 支持事务
DataDir(共享数据目录)
适用于:
- 开发和测试环境
- 小规模部署
- 需要文件级访问配置
限制:
- 需要共享文件系统(NFS 等)
- 配置同步存在延迟
- 并发写入可能导致冲突
JDBCConfig(已弃用)
- 仅用于兼容遗留系统
- 不推荐新部署使用
- 计划在未来版本中移除
4.4 PGConfig PostgreSQL 后端
4.4.1 概述
PGConfig 是 GeoServer Cloud 推荐的目录后端,它将所有配置存储在 PostgreSQL 数据库中。主要特点:
- 原生云支持:专为分布式部署设计
- 强一致性:使用数据库事务保证一致性
- 高性能:优化的数据模型和查询
- 易维护:标准数据库运维工具支持
4.4.2 数据库要求
- PostgreSQL 15.0 或更高版本
- 建议启用 PostGIS 扩展(可选)
- 推荐使用 SSD 存储
4.4.3 配置 PGConfig
1. 准备数据库
-- 创建用户
CREATE USER geoserver WITH PASSWORD 'your_password';
-- 创建数据库
CREATE DATABASE geoserver_config OWNER geoserver;
-- 连接到数据库并创建扩展(可选)
\c geoserver_config
CREATE EXTENSION IF NOT EXISTS postgis;
2. 配置服务
在 compose.yml 或环境变量中配置:
services:
wms:
image: geoservercloud/geoserver-cloud-wms:${TAG}
environment:
- SPRING_PROFILES_ACTIVE=pgconfig
# 数据库连接
- PGCONFIG_HOST=database
- PGCONFIG_PORT=5432
- PGCONFIG_DATABASE=geoserver_config
- PGCONFIG_SCHEMA=public
- PGCONFIG_USERNAME=geoserver
- PGCONFIG_PASSWORD=your_password
# 连接池配置
- PGCONFIG_HIKARI_MINIMUM_IDLE=2
- PGCONFIG_HIKARI_MAXIMUM_POOL_SIZE=10
3. 完整的 Spring 配置示例
spring:
profiles:
active: pgconfig
geoserver:
backend:
pgconfig:
enabled: true
# 数据库连接
host: ${PGCONFIG_HOST:localhost}
port: ${PGCONFIG_PORT:5432}
database: ${PGCONFIG_DATABASE:geoserver}
schema: ${PGCONFIG_SCHEMA:public}
username: ${PGCONFIG_USERNAME:geoserver}
password: ${PGCONFIG_PASSWORD:geoserver}
# HikariCP 连接池
hikari:
minimum-idle: ${PGCONFIG_HIKARI_MINIMUM_IDLE:2}
maximum-pool-size: ${PGCONFIG_HIKARI_MAXIMUM_POOL_SIZE:10}
idle-timeout: ${PGCONFIG_HIKARI_IDLE_TIMEOUT:30000}
max-lifetime: ${PGCONFIG_HIKARI_MAX_LIFETIME:60000}
connection-timeout: ${PGCONFIG_HIKARI_CONNECTION_TIMEOUT:10000}
# 初始化配置
initialize: ${PGCONFIG_INITIALIZE:true}
create-schema: ${PGCONFIG_CREATE_SCHEMA:true}
4.4.4 数据库架构
PGConfig 会自动创建以下表结构:
-- 工作区表
CREATE TABLE workspaces (
id VARCHAR(36) PRIMARY KEY,
name VARCHAR(255) NOT NULL UNIQUE,
isolated BOOLEAN DEFAULT FALSE,
date_created TIMESTAMP,
date_modified TIMESTAMP
);
-- 数据存储表
CREATE TABLE datastores (
id VARCHAR(36) PRIMARY KEY,
workspace_id VARCHAR(36) REFERENCES workspaces(id),
name VARCHAR(255) NOT NULL,
description TEXT,
type VARCHAR(255),
enabled BOOLEAN DEFAULT TRUE,
connection_params JSONB
);
-- 要素类型表
CREATE TABLE featuretypes (
id VARCHAR(36) PRIMARY KEY,
store_id VARCHAR(36) REFERENCES datastores(id),
name VARCHAR(255) NOT NULL,
native_name VARCHAR(255),
title VARCHAR(255),
description TEXT,
srs VARCHAR(255),
native_bounds GEOMETRY,
lat_lon_bounds GEOMETRY,
metadata JSONB
);
-- 样式表
CREATE TABLE styles (
id VARCHAR(36) PRIMARY KEY,
workspace_id VARCHAR(36) REFERENCES workspaces(id),
name VARCHAR(255) NOT NULL,
format VARCHAR(50),
language_version VARCHAR(50),
filename VARCHAR(255),
style_body TEXT
);
-- ... 更多表
4.4.5 数据库维护
备份
# 完整备份
pg_dump -U geoserver -h localhost geoserver_config > backup.sql
# 仅备份数据
pg_dump -U geoserver -h localhost --data-only geoserver_config > data_backup.sql
恢复
# 恢复到新数据库
createdb geoserver_config_restore
psql -U geoserver -h localhost geoserver_config_restore < backup.sql
性能监控
-- 查看活动连接
SELECT * FROM pg_stat_activity WHERE datname = 'geoserver_config';
-- 查看表大小
SELECT
relname AS table_name,
pg_size_pretty(pg_total_relation_size(relid)) AS total_size
FROM pg_catalog.pg_statio_user_tables
ORDER BY pg_total_relation_size(relid) DESC;
-- 查看慢查询
SELECT * FROM pg_stat_statements
WHERE dbid = (SELECT oid FROM pg_database WHERE datname = 'geoserver_config')
ORDER BY total_time DESC LIMIT 10;
4.4.6 PGBouncer 连接池
在大规模部署中,建议使用 PGBouncer 作为连接池代理:
# compose.yml
services:
pgbouncer:
image: bitnami/pgbouncer:latest
environment:
- POSTGRESQL_HOST=database
- POSTGRESQL_PORT=5432
- POSTGRESQL_USERNAME=geoserver
- POSTGRESQL_PASSWORD=${PGCONFIG_PASSWORD}
- POSTGRESQL_DATABASE=geoserver_config
- PGBOUNCER_POOL_MODE=transaction
- PGBOUNCER_MAX_CLIENT_CONN=1000
- PGBOUNCER_DEFAULT_POOL_SIZE=20
ports:
- "6432:6432"
wms:
environment:
- PGCONFIG_HOST=pgbouncer
- PGCONFIG_PORT=6432
PGBouncer 配置说明:
| 参数 | 说明 | 推荐值 |
|---|---|---|
| POOL_MODE | 连接池模式 | transaction |
| MAX_CLIENT_CONN | 最大客户端连接 | 根据服务数调整 |
| DEFAULT_POOL_SIZE | 默认池大小 | 20-50 |
4.5 DataDir 数据目录后端
4.5.1 概述
DataDir 后端使用传统的文件系统数据目录存储配置。在 GeoServer Cloud 中,需要所有服务实例共享同一个数据目录。
4.5.2 配置方式
1. 使用 Docker 卷
services:
wms:
image: geoservercloud/geoserver-cloud-wms:${TAG}
environment:
- SPRING_PROFILES_ACTIVE=datadir
- GEOSERVER_DATA_DIR=/opt/app/data_directory
volumes:
- geoserver-data:/opt/app/data_directory:rw
wfs:
image: geoservercloud/geoserver-cloud-wfs:${TAG}
environment:
- SPRING_PROFILES_ACTIVE=datadir
- GEOSERVER_DATA_DIR=/opt/app/data_directory
volumes:
- geoserver-data:/opt/app/data_directory:rw
volumes:
geoserver-data:
2. 使用 NFS 共享存储
volumes:
geoserver-data:
driver: local
driver_opts:
type: nfs
o: addr=nfs-server.example.com,nolock,soft,rw
device: ":/exports/geoserver-data"
4.5.3 初始化数据目录
GeoServer Cloud 可以从空数据目录启动,也可以使用预配置的数据目录:
使用示例数据目录
# 下载示例数据
wget https://github.com/geoserver/geoserver-cloud/raw/main/compose/catalog-datadir.tgz
# 解压到数据目录
tar -xzf catalog-datadir.tgz -C /path/to/data_directory
从现有 GeoServer 迁移
# 复制现有数据目录
cp -r /var/geoserver/data/* /new/data_directory/
# 确保权限正确
chown -R 1000:1000 /new/data_directory
4.5.4 配置同步机制
DataDir 后端依赖事件总线进行配置同步:
1. 管理员通过 WebUI 修改配置
2. WebUI 服务写入文件系统
3. WebUI 发送配置变更事件到 RabbitMQ
4. 所有服务实例接收事件
5. 各实例重新加载受影响的配置
配置事件总线:
spring:
rabbitmq:
host: ${RABBITMQ_HOST:rabbitmq}
port: ${RABBITMQ_PORT:5672}
username: ${RABBITMQ_USERNAME:guest}
password: ${RABBITMQ_PASSWORD:guest}
cloud:
bus:
enabled: true
4.5.5 注意事项
使用 DataDir 后端时需要注意:
- 文件锁定:并发写入可能导致问题
- 网络存储性能:NFS 等网络存储可能影响性能
- 同步延迟:配置变更需要时间传播
- 一致性:不保证强一致性
4.6 外部化配置详解
4.6.1 配置来源优先级
GeoServer Cloud 支持多种配置来源,按以下优先级(从高到低)加载:
1. 命令行参数 --server.port=8080
2. 系统属性 -Dserver.port=8080
3. 环境变量 SERVER_PORT=8080
4. Config Server 从配置服务器获取
5. 本地 application.yml
6. 默认值 框架内置默认值
4.6.2 环境变量配置
环境变量是最常用的配置方式,命名规则:
配置属性:geoserver.backend.pgconfig.host
环境变量:GEOSERVER_BACKEND_PGCONFIG_HOST
规则:
- 将点(.)替换为下划线(_)
- 将连字符(-)替换为下划线(_)
- 转换为大写
常用环境变量示例:
# 基本配置
GEOSERVER_BASE_PATH=/geoserver/cloud
GEOSERVER_ADMIN_USERNAME=admin
GEOSERVER_ADMIN_PASSWORD=secure_password
# 数据库配置
PGCONFIG_HOST=localhost
PGCONFIG_PORT=5432
PGCONFIG_DATABASE=geoserver
PGCONFIG_USERNAME=geoserver
PGCONFIG_PASSWORD=password
# JVM 配置
JAVA_OPTS=-Xms512m -Xmx2g -XX:+UseG1GC
# 日志配置
LOGGING_LEVEL_ORG_GEOSERVER=INFO
LOGGING_LEVEL_ORG_GEOTOOLS=WARN
4.6.3 JNDI 数据源配置
GeoServer Cloud 提供了简化的 JNDI 支持,用于配置数据源:
jndi:
datasources:
# PostGIS 数据源
postgis:
enabled: true
wait-for-it: true # 等待数据库可用
wait-timeout: 60 # 等待超时(秒)
url: jdbc:postgresql://localhost:5432/geodata
username: geoserver
password: ${POSTGIS_PASSWORD}
# HikariCP 配置
connection-timeout: 5000
idle-timeout: 60000
max-lifetime: 120000
minimum-idle: 2
maximum-pool-size: 10
# Oracle 数据源
oracle:
enabled: ${ORACLE_ENABLED:false}
url: jdbc:oracle:thin:@//oracle-host:1521/ORCL
username: geoserver
password: ${ORACLE_PASSWORD}
driver-class-name: oracle.jdbc.OracleDriver
在 GeoServer 中使用 JNDI 数据源:
JNDI 名称:java:comp/env/jdbc/postgis
4.6.4 HTTP 代理配置
配置级联 WMS/WMTS/WFS 服务的 HTTP 代理:
geotools:
httpclient:
proxy:
enabled: true
http:
host: proxy.example.com
port: 8080
user: proxyuser
password: proxypassword
nonProxyHosts: localhost,*.internal.com
https:
host: ${geotools.httpclient.proxy.http.host}
port: ${geotools.httpclient.proxy.http.port}
环境变量方式:
HTTP_PROXYHOST=proxy.example.com
HTTP_PROXYPORT=8080
HTTP_PROXYUSER=proxyuser
HTTP_PROXYPASSWORD=proxypassword
HTTP_NONPROXYHOSTS=localhost,*.internal.com
4.6.5 数据格式过滤
可以控制启用哪些数据格式:
geotools:
data:
filtering:
enabled: true
# 矢量格式
vector-formats:
"[PostGIS]": true
"[Shapefile]": true
"[GeoPackage]": true
"[Oracle NG]": ${ORACLE_ENABLED:false}
"[Microsoft SQL Server]": false
# 栅格格式
raster-formats:
"[GeoTIFF]": true
"[ImageMosaic]": true
"[WorldImage]": true
"[ArcGrid]": false
4.6.6 服务路径配置
修改默认的服务访问路径:
# 默认路径:/geoserver/cloud
# 修改为:/gis
geoserver:
base-path: /gis
# 或通过环境变量
GEOSERVER_BASE_PATH=/gis
4.7 配置版本管理
4.7.1 Git 管理配置
推荐使用 Git 管理 GeoServer Cloud 配置:
# 初始化配置仓库
mkdir geoserver-cloud-config
cd geoserver-cloud-config
git init
# 目录结构
geoserver-cloud-config/
├── application.yml # 共享配置
├── wms-service.yml # WMS 配置
├── wfs-service.yml # WFS 配置
├── gateway-service.yml # 网关配置
├── application-docker.yml # Docker 环境
├── application-k8s.yml # Kubernetes 环境
└── application-prod.yml # 生产环境
4.7.2 Config Server 使用 Git
# config-service 配置
spring:
cloud:
config:
server:
git:
uri: https://github.com/your-org/geoserver-cloud-config
default-label: main
search-paths: '{application}'
clone-on-start: true
force-pull: true
# 私有仓库认证
username: ${GIT_USERNAME}
password: ${GIT_PASSWORD}
4.7.3 配置版本追踪
利用 Git 追踪配置变更:
# 查看配置历史
git log --oneline application.yml
# 查看特定版本的配置
git show abc123:application.yml
# 比较配置差异
git diff HEAD~1 application.yml
# 回滚配置
git checkout abc123 -- application.yml
git commit -m "Rollback to previous config"
git push
然后刷新服务配置:
curl -X POST http://config-server:8888/actuator/bus-refresh
4.8 配置最佳实践
4.8.1 安全配置
敏感信息处理
# 不要这样做
geoserver:
admin:
password: admin123
# 应该这样做
geoserver:
admin:
password: ${GEOSERVER_ADMIN_PASSWORD}
使用 Kubernetes Secrets
apiVersion: v1
kind: Secret
metadata:
name: geoserver-secrets
type: Opaque
stringData:
admin-password: "secure-password-here"
db-password: "db-password-here"
引用 Secret:
env:
- name: GEOSERVER_ADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: geoserver-secrets
key: admin-password
4.8.2 环境分离
为不同环境创建独立的配置:
# application-dev.yml
geoserver:
backend:
pgconfig:
host: localhost
hikari:
maximum-pool-size: 5
---
# application-prod.yml
geoserver:
backend:
pgconfig:
host: postgres-cluster.internal
hikari:
maximum-pool-size: 30
激活特定环境:
SPRING_PROFILES_ACTIVE=pgconfig,prod
4.8.3 配置验证
启动时验证配置的有效性:
spring:
cloud:
config:
fail-fast: true # 配置加载失败时快速失败
retry:
initial-interval: 1000
max-interval: 5000
max-attempts: 10
4.8.4 配置文档化
为配置添加注释:
# ============================================
# GeoServer Cloud - WMS Service Configuration
# ============================================
#
# Environment: Production
# Last Updated: 2024-01-15
# Maintainer: ops@example.com
#
geoserver:
wms:
# 渲染线程池大小
# 建议设置为 CPU 核心数的 1-2 倍
rendering:
pool-size: ${WMS_RENDERING_POOL_SIZE:4}
# 最大请求内存(字节)
# 限制单个请求可使用的最大内存
max-request-memory: ${WMS_MAX_REQUEST_MEMORY:67108864} # 64MB
4.8.5 监控配置变更
设置配置变更通知:
management:
endpoints:
web:
exposure:
include: health,info,refresh,bus-refresh,env
# 启用审计日志
logging:
level:
org.springframework.cloud.bus: DEBUG
org.springframework.cloud.config: INFO
4.9 故障排除
4.9.1 常见配置问题
问题:数据库连接失败
# 检查数据库连接
docker compose exec wms nc -zv database 5432
# 检查数据库用户权限
docker compose exec database psql -U geoserver -c "\du"
# 查看服务日志
docker compose logs wms | grep -i "database\|connection\|postgres"
问题:配置不生效
# 检查当前配置
curl http://localhost:9102/actuator/env | jq '.propertySources'
# 刷新配置
curl -X POST http://localhost:9102/actuator/refresh
# 检查 Config Server 是否可达
curl http://config:8888/wms-service/default
问题:事件同步失败
# 检查 RabbitMQ 连接
docker compose exec wms nc -zv rabbitmq 5672
# 查看 RabbitMQ 队列状态
docker compose exec rabbitmq rabbitmqctl list_queues
# 检查 Bus 事件
docker compose logs wms | grep -i "bus\|event\|rabbit"
4.9.2 配置调试技巧
启用配置调试日志
logging:
level:
org.springframework.boot.context.config: DEBUG
org.springframework.cloud.config: DEBUG
查看实际加载的配置
# 所有配置属性
curl http://localhost:9102/actuator/configprops | jq
# 环境变量
curl http://localhost:9102/actuator/env | jq '.propertySources[] | select(.name | contains("systemEnvironment"))'
4.9.3 数据库诊断
-- 检查配置数据
SELECT * FROM workspaces;
SELECT * FROM datastores WHERE workspace_id IS NOT NULL;
SELECT * FROM styles LIMIT 10;
-- 检查最近修改
SELECT * FROM workspaces ORDER BY date_modified DESC LIMIT 5;
-- 检查数据一致性
SELECT w.name AS workspace, COUNT(d.id) AS stores
FROM workspaces w
LEFT JOIN datastores d ON w.id = d.workspace_id
GROUP BY w.name;
4.10 本章小结
本章深入介绍了 GeoServer Cloud 的目录和配置管理:
-
Catalog 概念:理解了 GeoServer 目录系统的核心对象和它们之间的关系。
-
后端选择:比较了 PGConfig、DataDir 和 JDBCConfig 三种后端的特点和适用场景。
-
PGConfig 配置:详细学习了 PostgreSQL 后端的配置、维护和优化方法。
-
DataDir 配置:了解了数据目录后端在 GeoServer Cloud 中的使用方法和限制。
-
外部化配置:掌握了环境变量、JNDI 数据源、HTTP 代理等配置方法。
-
配置管理:学习了使用 Git 进行配置版本管理的最佳实践。
-
故障排除:了解了常见配置问题的诊断和解决方法。
在下一章中,我们将深入探讨 GeoServer Cloud 的安全配置和认证机制。
4.11 思考题
-
PGConfig 相比 DataDir 后端有哪些优势?在什么情况下仍然应该选择 DataDir?
-
如何设计一个支持配置回滚的 GeoServer Cloud 部署方案?
-
在多租户环境中,如何使用工作区隔离实现配置隔离?
-
PGBouncer 在大规模部署中的作用是什么?应该如何配置?
-
如何确保敏感配置(如数据库密码)在分布式环境中的安全性?

浙公网安备 33010602011771号