Solr概念:生产环境部署与优化

Solr 生产环境部署指南

生产部署概述

将 Apache Solr 部署到生产环境需要超越基本安装和配置,涉及系统优化、安全加固、性能调优、监控告警等多个维度。本指南提供了将 Solr 成功部署到生产环境的全面指导,确保系统的稳定性、安全性和高性能。

安装和服务配置

1. 使用服务脚本安装

推荐的安装方式

1
2
3
4
5
6
# 下载 Solr 安装包
wget https://archive.apache.org/dist/lucene/solr/9.7.0/solr-9.7.0.tgz

# 解压并运行安装脚本
tar -xzf solr-9.7.0.tgz
sudo bash solr-9.7.0/bin/install_solr_service.sh solr-9.7.0.tgz

安装脚本的优势

  • 系统服务集成:自动创建 systemd 服务单元
  • 用户权限分离:创建专用的 “solr” 用户运行服务
  • 目录结构规范:标准的文件系统布局
  • 安全权限设置:适当的文件和目录权限配置

自定义安装选项

1
2
3
4
5
6
7
# 指定安装目录和数据目录
sudo bash install_solr_service.sh solr-9.7.0.tgz \
-i /opt/solr \
-d /var/solr \
-u solr \
-s solr \
-p 8983

参数说明

  • -i - Solr 安装目录(默认:/opt/solr)
  • -d - Solr 数据目录(默认:/var/solr)
  • -u - 运行用户(默认:solr)
  • -s - 服务名称(默认:solr)
  • -p - 服务端口(默认:8983)

2. 系统服务管理

服务控制命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 启动 Solr 服务
sudo systemctl start solr

# 停止 Solr 服务
sudo systemctl stop solr

# 重启 Solr 服务
sudo systemctl restart solr

# 设置开机自启
sudo systemctl enable solr

# 查看服务状态
sudo systemctl status solr

# 查看服务日志
sudo journalctl -u solr -f

服务配置文件

1
2
3
4
# 主要配置文件位置
/etc/default/solr.in.sh # 环境变量配置
/opt/solr/bin/solr.in.sh # 默认配置模板
/var/solr/log4j2.xml # 日志配置

内存和性能调优

1. JVM 内存配置

堆内存设置

1
2
3
# 在 /etc/default/solr.in.sh 中配置
SOLR_HEAP="8g" # 推荐:8-16GB
SOLR_JAVA_MEM="-Xms8g -Xmx8g" # 固定堆大小避免扩容开销

内存配置原则

  • 堆内存大小:通常设置为系统内存的 25-50%
  • 避免过大堆:单个 JVM 堆不建议超过 32GB
  • 预留系统内存:为操作系统和文件缓存预留足够内存
  • 多实例策略:大内存服务器考虑运行多个 Solr 实例

垃圾收集器优化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# G1 垃圾收集器配置(推荐)
GC_TUNE="-XX:+UseG1GC \
-XX:+PerfDisableSharedMem \
-XX:+ParallelRefProcEnabled \
-XX:MaxGCPauseMillis=250 \
-XX:+UseLargePages \
-XX:+AlwaysPreTouch"

# CMS 垃圾收集器配置(备选)
GC_TUNE="-XX:+UseConcMarkSweepGC \
-XX:CMSInitiatingOccupancyFraction=75 \
-XX:+UseCMSInitiatingOccupancyOnly \
-XX:+CMSScavengeBeforeRemark \
-XX:+CMSParallelRemarkEnabled"

# JVM 崩溃处理
SOLR_OPTS="$SOLR_OPTS -XX:+CrashOnOutOfMemoryError"

GC 日志配置

1
2
3
4
5
6
7
# 详细的 GC 日志记录
GC_LOG_OPTS="-Xlog:gc*:$SOLR_LOGS_DIR/solr_gc.log:time,tags:filecount=9,filesize=20M"

# GC 日志分析工具
# - GCViewer: 图形化 GC 日志分析
# - GCeasy.io: 在线 GC 日志分析
# - jstat: 实时 GC 监控

2. 索引性能优化

合并调度器配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!-- 在 solrconfig.xml 中配置 -->
<indexConfig>
<!-- 并发合并调度器 -->
<mergeScheduler class="org.apache.lucene.index.ConcurrentMergeScheduler">
<!-- 最大线程数建议为 CPU 核心数的一半 -->
<int name="maxThreadCount">4</int>
<int name="maxMergeCount">6</int>
<!-- I/O 限制:MB/s -->
<double name="ioThrottle">true</double>
</mergeScheduler>

<!-- 合并策略 -->
<mergePolicy class="org.apache.lucene.index.TieredMergePolicy">
<int name="maxMergeAtOnce">10</int>
<int name="segmentsPerTier">10</int>
<double name="maxMergedSegmentMB">5000</double>
</mergePolicy>

<!-- 写入缓冲区大小 -->
<ramBufferSizeMB>128</ramBufferSizeMB>
<maxBufferedDocs>1000</maxBufferedDocs>
</indexConfig>

提交策略优化

1
2
3
4
5
6
7
8
9
10
11
<!-- 自动提交配置 -->
<autoCommit>
<maxTime>15000</maxTime> <!-- 15秒硬提交 -->
<maxDocs>10000</maxDocs> <!-- 或1万文档 -->
<openSearcher>false</openSearcher>
</autoCommit>

<!-- 自动软提交配置 -->
<autoSoftCommit>
<maxTime>1000</maxTime> <!-- 1秒软提交 -->
</autoSoftCommit>

3. 查询性能优化

缓存配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!-- 查询结果缓存 -->
<queryResultCache
class="solr.FastLRUCache"
size="512"
initialSize="512"
autowarmCount="0"/>

<!-- 过滤器缓存 -->
<filterCache
class="solr.FastLRUCache"
size="512"
initialSize="512"
autowarmCount="128"/>

<!-- 文档缓存 -->
<documentCache
class="solr.FastLRUCache"
size="512"
initialSize="512"
autowarmCount="0"/>

SolrCloud 生产配置

1. ZooKeeper 集群配置

外部 ZooKeeper 集群

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 生产环境必须使用外部 ZooKeeper 集群
# 避免使用嵌入式 ZooKeeper

# ZooKeeper 配置示例
# /opt/zookeeper/conf/zoo.cfg
tickTime=2000
dataDir=/var/zookeeper
clientPort=2181
initLimit=5
syncLimit=2

# ZooKeeper 集群节点
server.1=zk1.example.com:2888:3888
server.2=zk2.example.com:2888:3888
server.3=zk3.example.com:2888:3888

Solr ZooKeeper 连接配置

1
2
3
4
5
# 在 /etc/default/solr.in.sh 中配置
ZK_HOST="zk1.example.com:2181,zk2.example.com:2181,zk3.example.com:2181/solr"

# 使用 chroot 隔离 Solr 数据
# /solr 是 ZooKeeper 中的命名空间,将 Solr 数据与其他应用隔离

2. 节点配置

主机名配置

1
2
3
4
5
6
# 明确设置主机名,避免自动检测问题
SOLR_HOST="solr1.example.com"
SOLR_PORT=8983

# 确保主机名可以从其他节点访问
# 避免使用 localhost 或 127.0.0.1

集群发现配置

1
2
3
4
5
6
# 节点角色配置
SOLR_OPTS="$SOLR_OPTS -Dsolr.node.roles=data:on,overseer:off"

# 选举超时配置
SOLR_OPTS="$SOLR_OPTS -DzkClientTimeout=30000"
SOLR_OPTS="$SOLR_OPTS -DzkConnectTimeout=60000"

3. 分片和副本策略

集合创建最佳实践

1
2
3
4
5
6
7
8
9
# 创建生产集合
solr create_collection \
-c products \
-d _default \
-shards 6 \
-replicationFactor 2 \
-maxShardsPerNode 2 \
-autoAddReplicas true \
-rule "shard:*,replica:<2,node:*"

配置说明

  • 分片数量:基于数据量和查询负载确定
  • 副本因子:至少为 2,重要数据考虑 3
  • 分片分布:每个节点的分片数量限制
  • 自动副本:节点故障时自动创建副本
  • 放置规则:控制副本在节点间的分布

系统级优化

1. 操作系统配置

文件句柄限制

1
2
3
4
5
6
7
8
9
10
11
12
13
# 在 /etc/security/limits.conf 中添加
solr soft nofile 65000
solr hard nofile 65000
solr soft nproc 65000
solr hard nproc 65000

# 虚拟内存设置
solr soft as unlimited
solr hard as unlimited

# 验证设置
sudo -u solr ulimit -n
sudo -u solr ulimit -u

交换分区管理

1
2
3
4
5
6
7
8
9
10
11
12
13
# 查看当前交换使用情况
swapon -s
cat /proc/swaps

# 临时禁用交换
sudo swapoff -a

# 永久配置(减少交换使用)
echo 'vm.swappiness=1' >> /etc/sysctl.conf
echo 'vm.max_map_count=262144' >> /etc/sysctl.conf

# 应用配置
sudo sysctl -p

网络接口配置

1
2
3
4
5
# 绑定到特定网络接口
SOLR_JETTY_HOST="192.168.1.100"

# 在 /etc/default/solr.in.sh 中配置
SOLR_OPTS="$SOLR_OPTS -Djetty.host=192.168.1.100"

2. 存储系统优化

磁盘 I/O 优化

1
2
3
4
5
6
7
# 文件系统挂载选项
# 在 /etc/fstab 中添加
/dev/sdb1 /var/solr ext4 defaults,noatime,nodiratime 0 2

# SSD 优化
echo deadline > /sys/block/sdb/queue/scheduler
echo 0 > /sys/block/sdb/queue/rotational

目录结构规划

1
2
3
4
5
6
7
8
9
10
# 推荐的目录结构
/opt/solr/ # Solr 安装目录(只读)
/var/solr/ # Solr 数据目录(读写)
├── data/ # 索引数据
├── logs/ # 日志文件
└── backup/ # 备份目录

# 分离日志和数据到不同磁盘
SOLR_LOGS_DIR="/var/log/solr"
SOLR_HOME="/var/solr/data"

安全配置

1. 网络安全

防火墙配置

1
2
3
4
5
6
7
8
# 使用 iptables 限制访问
# 只允许特定 IP 访问 Solr 端口
sudo iptables -A INPUT -p tcp --dport 8983 -s 192.168.1.0/24 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 8983 -j DROP

# 使用 ufw(Ubuntu)
sudo ufw allow from 192.168.1.0/24 to any port 8983
sudo ufw deny 8983

网络接口绑定

1
2
3
# 限制监听接口
SOLR_JETTY_HOST="10.0.1.100" # 内网 IP
# 避免绑定到 0.0.0.0 或公网 IP

2. 认证和授权

基础认证配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 启用认证插件
SOLR_OPTS="$SOLR_OPTS -Dsolr.authentication.enabled=true"

# 在 security.json 中配置
{
"authentication": {
"blockUnknown": true,
"class": "solr.BasicAuthPlugin",
"credentials": {
"admin": "IV0EHq1OnNrj6gvRCwvFwTrZ1+z1oBbnQdiVC3otuq0= Ndd7LKvVBAaZIF0QAVi1ekCfAJXr1GGfLtRUXhgrF8c=",
"solr": "IV0EHq1OnNrj6gvRCwvFwTrZ1+z1oBbnQdiVC3otuq0= Ndd7LKvVBAaZIF0QAVi1ekCfAJXr1GGfLtRUXhgrF8c="
}
},
"authorization": {
"class": "solr.RuleBasedAuthorizationPlugin",
"permissions": [
{"name": "security-edit", "role": "admin"},
{"name": "collection-admin-edit", "role": "admin"},
{"name": "core-admin-edit", "role": "admin"},
{"name": "read", "role": "*"},
{"name": "update", "role": "writer"}
],
"user-role": {
"admin": ["admin"],
"solr": ["writer"]
}
}
}

SSL/TLS 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 生成自签名证书(测试用)
keytool -genkeypair \
-alias solr-ssl \
-keyalg RSA \
-keysize 2048 \
-keypass secret \
-storepass secret \
-validity 9999 \
-keystore solr-ssl.keystore.p12 \
-storetype PKCS12 \
-ext SAN=DNS:localhost,IP:127.0.0.1,DNS:solr.example.com

# SSL 配置
SOLR_SSL_ENABLED=true
SOLR_SSL_KEY_STORE=/var/solr/ssl/solr-ssl.keystore.p12
SOLR_SSL_KEY_STORE_PASSWORD=secret
SOLR_SSL_TRUST_STORE=/var/solr/ssl/solr-ssl.keystore.p12
SOLR_SSL_TRUST_STORE_PASSWORD=secret
SOLR_SSL_NEED_CLIENT_AUTH=false
SOLR_SSL_WANT_CLIENT_AUTH=false

3. 数据安全

敏感数据保护

1
2
3
4
5
6
<!-- 在 schema.xml 中标记敏感字段 -->
<field name="creditCard" type="text_general" indexed="false" stored="false"/>
<field name="ssn" type="text_general" indexed="false" stored="false"/>

<!-- 使用字段加密 -->
<field name="personalInfo" type="encrypted_text"/>

审计日志配置

1
2
3
4
5
6
7
<!-- 启用审计日志 -->
<requestHandler name="/admin/audit" class="solr.AuditLogHandler">
<lst name="defaults">
<str name="logFile">/var/solr/logs/audit.log</str>
<str name="logLevel">INFO</str>
</lst>
</requestHandler>

多节点部署考虑

1. 单主机多实例

何时使用多实例

  • 大内存服务器:单个 JVM 堆超过 16-32GB 时
  • GC 延迟控制:避免长时间的垃圾收集暂停
  • 资源隔离:不同应用或团队的数据隔离
  • 故障隔离:减少单点故障的影响范围

多实例配置

1
2
3
4
5
6
7
8
9
10
11
# 实例 1 配置
SOLR_PORT=8983
SOLR_HOME="/var/solr/instance1"
SOLR_LOGS_DIR="/var/log/solr/instance1"
SOLR_PID_DIR="/var/solr/instance1"

# 实例 2 配置
SOLR_PORT=8984
SOLR_HOME="/var/solr/instance2"
SOLR_LOGS_DIR="/var/log/solr/instance2"
SOLR_PID_DIR="/var/solr/instance2"

资源分配策略

1
2
3
4
5
6
# 为每个实例分配专用资源
# 实例 1:CPU 0-7,内存 16GB
taskset -c 0-7 sudo -u solr /opt/solr/bin/solr start -m 16g -p 8983

# 实例 2:CPU 8-15,内存 16GB
taskset -c 8-15 sudo -u solr /opt/solr/bin/solr start -m 16g -p 8984

2. 节点间通信优化

网络配置

1
2
3
4
5
6
7
8
# 优化 TCP 参数
echo 'net.core.rmem_max = 16777216' >> /etc/sysctl.conf
echo 'net.core.wmem_max = 16777216' >> /etc/sysctl.conf
echo 'net.ipv4.tcp_rmem = 4096 87380 16777216' >> /etc/sysctl.conf
echo 'net.ipv4.tcp_wmem = 4096 65536 16777216' >> /etc/sysctl.conf

# 应用设置
sudo sysctl -p

连接池配置

1
2
3
4
5
# HTTP 客户端优化
SOLR_OPTS="$SOLR_OPTS -Dsolr.httpclient.retries=1"
SOLR_OPTS="$SOLR_OPTS -Dsolr.httpclient.timeout=60000"
SOLR_OPTS="$SOLR_OPTS -Dsolr.httpclient.connTimeout=15000"
SOLR_OPTS="$SOLR_OPTS -Dsolr.jetty.request.header.size=65536"

监控和维护

1. 日志管理

日志配置优化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<!-- log4j2.xml 配置 -->
<Configuration>
<Appenders>
<!-- 主日志文件 -->
<RollingFile name="MainLogFile" fileName="${sys:solr.log.dir}/solr.log"
filePattern="${sys:solr.log.dir}/solr.log.%i">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p (%t) [%X{collection} %X{shard} %X{replica} %X{core}] %c{1.} %m%n"/>
<Policies>
<SizeBasedTriggeringPolicy size="32 MB"/>
</Policies>
<DefaultRolloverStrategy max="10"/>
</RollingFile>

<!-- 慢查询日志 -->
<RollingFile name="SlowLogFile" fileName="${sys:solr.log.dir}/solr_slow_requests.log"
filePattern="${sys:solr.log.dir}/solr_slow_requests.log.%i">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p (%t) %c{1.} %m%n"/>
<Policies>
<SizeBasedTriggeringPolicy size="10 MB"/>
</Policies>
<DefaultRolloverStrategy max="5"/>
</RollingFile>
</Appenders>

<Loggers>
<!-- 慢查询记录器 -->
<Logger name="org.apache.solr.core.SolrCore.SlowRequest" level="INFO" additivity="false">
<AppenderRef ref="SlowLogFile"/>
</Logger>

<Root level="INFO">
<AppenderRef ref="MainLogFile"/>
</Root>
</Loggers>
</Configuration>

慢查询监控

1
2
3
4
5
6
# 设置慢查询阈值
SOLR_OPTS="$SOLR_OPTS -Dsolr.log.slowQueries.enabled=true"
SOLR_OPTS="$SOLR_OPTS -Dsolr.log.slowQueries.threshold=1000"

# 分析慢查询日志
grep "SlowRequest" /var/solr/logs/solr_slow_requests.log | tail -20

2. 性能监控

JMX 监控配置

1
2
3
4
5
6
7
8
9
# 启用 JMX
ENABLE_REMOTE_JMX_OPTS=true
RMI_PORT=18983

# JMX 连接配置
SOLR_OPTS="$SOLR_OPTS -Dcom.sun.management.jmxremote"
SOLR_OPTS="$SOLR_OPTS -Dcom.sun.management.jmxremote.port=$RMI_PORT"
SOLR_OPTS="$SOLR_OPTS -Dcom.sun.management.jmxremote.authenticate=false"
SOLR_OPTS="$SOLR_OPTS -Dcom.sun.management.jmxremote.ssl=false"

指标收集脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/bash
# solr-metrics.sh

SOLR_URL="http://localhost:8983/solr"

# 获取系统指标
curl -s "$SOLR_URL/admin/metrics?group=jvm&wt=json" | jq '.metrics."solr.jvm".memory'

# 获取查询性能指标
curl -s "$SOLR_URL/admin/metrics?group=core&wt=json" | jq '.metrics | to_entries[] | select(.key | contains("requests")) | {(.key): .value.avgRequestsPerSecond}'

# 获取缓存指标
curl -s "$SOLR_URL/admin/metrics?group=cache&wt=json" | jq '.metrics | to_entries[] | select(.key | contains("cache")) | {(.key): {hitRatio: .value.hitratio, size: .value.size}}'

3. 健康检查

自动化健康检查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/bin/bash
# health-check.sh

SOLR_URL="http://localhost:8983/solr"
THRESHOLD_RESPONSE_TIME=5000 # 5秒
THRESHOLD_HEAP_USAGE=80 # 80%

# 检查 Solr 响应
response_time=$(curl -w "%{time_total}" -s -o /dev/null "$SOLR_URL/admin/ping")
if (( $(echo "$response_time > $THRESHOLD_RESPONSE_TIME" | bc -l) )); then
echo "WARNING: Solr response time is high: ${response_time}ms"
fi

# 检查内存使用
heap_usage=$(curl -s "$SOLR_URL/admin/metrics?group=jvm&wt=json" | jq '.metrics."solr.jvm".memory.heap.used_percent')
if (( $(echo "$heap_usage > $THRESHOLD_HEAP_USAGE" | bc -l) )); then
echo "WARNING: High heap usage: ${heap_usage}%"
fi

# 检查集群状态
if curl -s "$SOLR_URL/admin/collections?action=CLUSTERSTATUS&wt=json" | jq -e '.cluster.live_nodes | length > 0' > /dev/null; then
echo "OK: Cluster is healthy"
else
echo "ERROR: Cluster is not healthy"
fi

故障排除和诊断

1. 常见问题诊断

内存问题

1
2
3
4
5
6
7
8
# 检查内存使用
jstat -gc -t $(pgrep -f solr) 5s

# 生成堆转储
jmap -dump:format=b,file=/tmp/solr-heap.hprof $(pgrep -f solr)

# 分析 GC 日志
# 使用 GCViewer 或 GCeasy.io 分析 GC 性能

索引问题

1
2
3
4
5
6
7
8
# 检查索引健康状况
curl "$SOLR_URL/admin/cores?action=STATUS&wt=json" | jq '.status'

# 检查分片状态
curl "$SOLR_URL/admin/collections?action=CLUSTERSTATUS&wt=json" | jq '.cluster.collections'

# 索引优化
curl "$SOLR_URL/collection_name/update?optimize=true&maxSegments=1"

2. 性能调优工具

查询分析

1
2
3
4
5
6
7
8
# 启用查询调试
curl "$SOLR_URL/collection_name/select?q=*:*&debug=true&debugQuery=true&wt=json"

# 分析查询性能
curl "$SOLR_URL/collection_name/select?q=*:*&debug=timing&wt=json"

# 缓存统计
curl "$SOLR_URL/admin/mbeans?cat=CACHE&wt=json"

备份和恢复策略

1. 数据备份

集合级备份

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 创建备份
curl -X POST "$SOLR_URL/admin/collections" \
-d "action=BACKUP&name=products-$(date +%Y%m%d)&collection=products&location=/var/solr/backup"

# 增量备份脚本
#!/bin/bash
# backup-solr.sh

BACKUP_DIR="/var/solr/backup"
COLLECTION="products"
DATE=$(date +%Y%m%d-%H%M%S)

# 创建备份
curl -X POST "$SOLR_URL/admin/collections" \
-d "action=BACKUP&name=${COLLECTION}-${DATE}&collection=${COLLECTION}&location=${BACKUP_DIR}"

# 清理旧备份(保留7天)
find "$BACKUP_DIR" -name "${COLLECTION}-*" -mtime +7 -exec rm -rf {} \;

2. 灾难恢复

完整恢复流程

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/bash
# disaster-recovery.sh

BACKUP_NAME="products-20241201-120000"
NEW_COLLECTION="products-restored"
BACKUP_LOCATION="/var/solr/backup"

# 恢复集合
curl -X POST "$SOLR_URL/admin/collections" \
-d "action=RESTORE&name=${BACKUP_NAME}&collection=${NEW_COLLECTION}&location=${BACKUP_LOCATION}"

# 验证恢复
curl "$SOLR_URL/${NEW_COLLECTION}/select?q=*:*&rows=0&wt=json" | jq '.response.numFound'

小结

生产环境部署 Apache Solr 是一个复杂的系统工程,需要从多个维度进行细致的规划和配置:

关键成功因素

  1. 合理的资源配置

    • 适当的内存分配和 GC 策略
    • 充足的文件句柄和进程限制
    • 优化的磁盘 I/O 配置
  2. 健壮的集群架构

    • 外部 ZooKeeper 集群
    • 合理的分片和副本策略
    • 节点故障的容错机制
  3. 全面的安全保护

    • 网络层面的访问控制
    • 应用层面的认证授权
    • 数据传输的加密保护
  4. 有效的监控运维

    • 实时性能监控
    • 自动化健康检查
    • 完善的备份恢复策略

通过遵循这些最佳实践和配置建议,可以构建一个稳定、安全、高性能的 Solr 生产环境,满足企业级应用的各种需求。记住,生产部署是一个持续优化的过程,需要根据实际使用情况不断调整和改进配置。

© 2025 Solr Community of China All Rights Reserved. 本站访客数人次 本站总访问量
Theme by hiero