Solr配置:包管理器内核机制与API详解

Solr配置:包管理器内核机制与API详解

包管理器(CLI)内部使用各种Solr API来安装、部署和更新包。本文档提供了这些API的概述和详细使用指南。

核心特性

零中断部署(热部署)

  • 支持在不重启节点或重新加载核心的情况下安装和更新包
  • 部署快速,无请求失败或缓存过期
  • 实现真正的热部署能力

简化打包流程

标准插件概念支持

  • 查询解析器、搜索组件、请求处理器、URP等标准插件概念
  • 无需特殊代码/打包更改即可支持
  • 保持传统插件开发模式

向后兼容性

  • 用户已部署的构件(包含自定义插件的jar)兼容
  • 无需重新编译或重新打包
  • 促进更广泛的采用

灵活的包格式

  • 支持单jar包和多jar包
  • 使用熟悉/标准的命名约定
  • 采用行业标准的包管理器概念和术语(类似apt、dnf、homebrew等)

类加载器架构

类加载器隔离是系统的核心。系统简化为两层类加载器:

根类加载器

  • 包含Solr类路径中的所有jar
  • 需要Solr节点重启才能更改

命名类加载器集合

  • 从根类加载器继承
  • 生命周期与ZooKeeper中的包配置绑定
  • 配置修改后,相应的类加载器重新加载,组件被要求重新加载

包加载安全机制

默认安全策略

包功能默认禁用。需要使用系统属性-Denable.packages=true启动所有节点来使用此功能。

1
bin/solr start -c -Denable.packages=true

密钥管理

上传公钥

包二进制文件必须使用私钥签名,确保公钥发布在包存储的信任存储中。

1
2
3
4
5
6
7
8
# 生成私钥
openssl genrsa -out my_key.pem 512

# 创建DER格式的公钥
openssl rsa -in my_key.pem -pubout -outform DER -out my_key.der

# 上传密钥到包存储
bin/solr package add-key my_key.der

包存储系统

系统概述

包存储是一个分布式文件存储,可以在文件系统中存储任意文件。

核心特性

  • 完全复制的基于文件系统的存储库
  • 位置:每个Solr节点的<solr.home>/filestore
  • 每个条目包含文件 + 元数据
  • 元数据文件命名为.<filename>.json
  • 元数据文件包含sha256和文件签名
  • 用户不能创建以句点(.)开头的文件
  • 与文件内容类型无关,可存储jar和其他文件

包存储工作原理

当文件上传到包存储时:

  1. 保存到本地文件系统
  2. 与元数据一起保存,元数据文件存储jar文件的sha512和签名
  3. 要求集群中的每个活动节点也下载该文件

包存储API

核心端点

  • PUT /api/cluster/filestore/files/{full/path/to/file} - 上传新文件并添加到文件存储
  • GET /api/cluster/filestore/files/{full/path/to/file} - 下载文件存储中已有的文件
  • GET /api/cluster/filestore/metadata/{full/path/to/file} - 获取特定文件的元数据或目录中可用文件列表

构件签名流程

1. 获取示例jar文件

1
curl -o runtimelibs.jar -LO https://github.com/apache/solr/blob/releases/solr/9.9.0/solr/core/src/test-files/runtimecode/runtimelibs.jar.bin?raw=true

2. 使用私钥签名jar

1
openssl dgst -sha1 -sign my_key.pem runtimelibs.jar | openssl enc -base64 | sed 's/+/%2B/g' | tr -d \\n

3. 上传带签名的jar

1
2
curl --data-binary @runtimelibs.jar -X PUT \
"http://localhost:8983/api/cluster/filestore/files/mypkg/1.0/myplugins.jar?sig=<signature-of-jar>"

4. 验证jar上传

1
curl "http://localhost:8983/api/cluster/filestore/metadata/mypkg/1.0?omitHeader=true"

响应示例:

1
2
3
4
5
6
7
8
{
"files":{"/mypkg/1.0":[{
"name":"myplugins.jar",
"timestamp":"2019-11-11T07:36:17.354Z",
"sha512":"d01b51de67ae1680a84a813983b1de3b592fc32f1a22b662fc9057da5953abd1b72476388ba342cad21671cd0b805503c78ab9075ff2f3951fdf75fa16981420",
"sig":["elNjhmWIOgTgbAzeZ+OcwR42N7vqL6Ig9eAqn4YoP2thT7FJuhiaZuCPivjMkD682EBo9gveSCTyXIsZKjOCbQ=="]
}]}
}

包配置系统

包属性结构

一个包具有以下属性:

  • 唯一名称
  • 一个或多个版本,每个版本具有:
    • version:版本字符串
    • files:来自包存储的文件数组

对于包定义中的每个包/版本,都有一个唯一的SolrResourceLoader实例,这是CoreContainer资源加载器的子级。

注意:Solr不要求版本字符串遵循任何特定格式 - 可以是任意字符串甚至空字符串。

packages.json配置

包配置存在于ZooKeeper中名为packages.json的文件中。任何时刻都可以在包配置中有给定包的多个版本。系统总是使用最新版本。版本按其值的字典序排序,最大的字符串被认为是最新的。

重要警告:版本字符串的字典序意味着对于具有版本1.2.01.9.01.11.0的包,Solr会选择1.9.0作为最新版本。

配置示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"packages" : {
"mypkg" : {
"name": "mypkg",
"versions": [
{
"version" : "0.1",
"files" : ["/path/to/myplugin/1.1/plugin.jar"]
},
{
"version" : "0.2",
"files" : ["/path/to/myplugin/1.0/plugin.jar"]
}
]
}
}
}

API端点操作

包管理API

  • GET /api/cluster/package - 获取包列表
  • POST /api/cluster/package - 编辑包
    • add命令:添加包版本
    • delete命令:删除包版本

版本管理操作

升级包

使用add命令添加高于当前版本的版本。

降级包

使用delete命令删除最高版本,选择次高版本。

并行使用多个版本

使用集合配置中的params.json存储包使用的版本。默认情况下是$LATEST

1
2
3
4
5
6
7
8
{
"params": {
"PKG_VERSIONS": {
"mypkg": "0.1",
"pkg2": "$LATEST"
}
}
}

说明

  • mypkg:无论是否有更新版本,都使用版本0.1
  • pkg2:使用最新版本(这是可选的,默认是$LATEST

注意params.json中的包版本实际上指示Solr选择不大于提供值的最大版本的包。

版本更新工作流

  1. 添加包的新版本
  2. 包加载器加载类并通知每个插件持有者新版本的可用性
  3. 检查是否应该使用特定版本,如果是则忽略更新
  4. 如果不是,则重新加载插件

在插件中使用包

类名前缀

任何类名都可以用包名作为前缀,例如mypkg:fully.qualified.ClassName,Solr会使用包的最新版本来加载类。从包加载的插件不能依赖于核心级类。

solrconfig.xml中的插件声明

1
2
<requestHandler name="/myhandler" class="mypkg:full.path.to.MyClass">
</requestHandler>

完整工作示例

1. 创建包

1
2
3
4
5
6
7
8
9
curl http://localhost:8983/api/cluster/package \
-H 'Content-type:application/json' \
-d '{
"add": {
"package" : "mypkg",
"version":"1.0",
"files" :["mypkg/1.0/myplugins.jar"]
}
}'

2. 验证创建的包

1
curl http://localhost:8983/api/cluster/package?omitHeader=true

响应示例:

1
2
3
4
5
6
7
8
9
10
11
{
"result":{
"znodeVersion":0,
"packages":{
"mypkg":[{
"version":"1.0",
"files":["/mypkg/1.0/myplugins.jar"]
}]
}
}
}

3. 注册集合中的插件

1
2
3
4
5
6
7
8
curl http://localhost:8983/solr/gettingstarted/config \
-H 'Content-type:application/json' \
-d '{
"create-requesthandler": {
"name": "/test",
"class": "mypkg:org.apache.solr.core.RuntimeLibReqHandler"
}
}'

4. 验证组件创建

1
curl "http://localhost:8983/solr/gettingstarted/config/requestHandler?componentName=/test&meta=true&omitHeader=true"

响应示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"config":{
"requestHandler":{
"/test":{
"name":"/test",
"class":"mypkg:org.apache.solr.core.RuntimeLibReqHandler",
"_packageinfo_":{
"package":"mypkg",
"version":"1.0",
"files":["/mypkg/1.0/myplugins.jar"]
}
}
}
}
}

5. 测试请求处理器

1
curl "http://localhost:8983/solr/gettingstarted/test?omitHeader=true"

6. 更新组件版本

上传新版本的jar、签名并上传:

1
2
3
4
5
6
curl -o runtimelibs3.jar -LO https://github.com/apache/solr/blob/releases/solr/9.9.0/solr/core/src/test-files/runtimecode/runtimelibs_v3.jar.bin?raw=true

openssl dgst -sha1 -sign my_key.pem runtimelibs3.jar | openssl enc -base64 | sed 's/+/%2B/g' | tr -d \\n

curl --data-binary @runtimelibs3.jar -X PUT \
"http://localhost:8983/api/cluster/filestore/files/mypkg/2.0/myplugins.jar?sig=<signature>"

7. 添加新包版本

1
2
3
4
5
6
7
8
9
curl http://localhost:8983/api/cluster/package \
-H 'Content-type:application/json' \
-d '{
"add": {
"package" : "mypkg",
"version":"2.0",
"files" :["/mypkg/2.0/myplugins.jar"]
}
}'

避免自动升级

设置集合级别的属性来固定包版本:

1
2
3
4
5
6
7
8
9
curl http://localhost:8983/solr/gettingstarted/config/params \
-H 'Content-type:application/json' \
-d '{
"set":{
"PKG_VERSIONS":{
"mypkg":"2.0"
}
}
}'

最佳实践建议

1. 安全考虑

  • 始终使用密钥签名验证包的完整性
  • 定期更新和轮换签名密钥
  • 限制包上传权限

2. 版本管理

  • 使用有意义的版本号命名规则
  • 注意字典序排序的影响
  • 建立版本回滚机制

3. 部署策略

  • 在测试环境验证新包
  • 使用滚动更新减少服务影响
  • 监控部署后的系统状态

4. 性能优化

  • 合理控制包的大小和数量
  • 避免不必要的包重载
  • 监控类加载器的内存使用

包管理器提供了现代化的插件管理能力,通过合理使用其API和最佳实践,可以实现高效、安全的插件生命周期管理。

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