包管理器内部
软件包管理器 (CLI) 在内部使用各种 Solr API 来安装、部署和更新软件包。本文档包含了这些 API 的概述。
显著功能
-
零中断部署(热部署):应该能够在不重新启动节点或重新加载内核的情况下安装和更新软件包,因此部署应该快速且没有失败的请求或过期的缓存。
-
轻松打包
-
应支持标准插件概念,例如查询解析器、搜索组件、请求处理程序、URP 等,而无需任何特殊代码/打包更改。
-
用户已经部署(并且在生产中使用)的工件(包含自定义插件的 jar)应兼容,无需重新编译或重新打包,以便更广泛地采用。
-
应支持单个 jar 软件包以及多个 jar 软件包。
-
使用熟悉的/标准命名
-
使用围绕软件包管理器的行业标准概念和术语,类似于 apt、dnf、homebrew 等。
-
类加载器
在系统的核心,我们有类加载器隔离。为了实现这一点,系统被简化为两个分层的类加载器
-
根类加载器,其中包含来自 Solr 类路径的所有 jar。这需要重新启动 Solr 节点才能更改任何内容。
-
一组从根类加载器继承的命名类加载器。命名类加载器的生命周期与 ZooKeeper 中的软件包配置相关联。一旦修改了配置,相应的类加载器就会重新加载,并要求组件重新加载。
软件包加载安全性
软件包默认情况下处于禁用状态。使用系统属性 -Denable.packages=true
启动所有节点以使用此功能。
示例
bin/solr -c -Denable.packages=true
软件包存储
软件包存储是一个分布式文件存储,它可以将任意文件存储在文件系统中。
-
这是一个基于完全复制文件系统的存储库。
-
它位于每个 Solr 节点上的 <solr.home>/filestore 中。
-
每个条目是一个文件 + 元数据。元数据命名为
.<filename>.json
。 -
元数据文件包含文件的 sha256 和签名。
-
用户无法创建以句点 (.) 开头的文件。
-
它与文件的内容类型无关。您可以存储 jar 文件以及其他文件。
Package Store 如何工作?
当文件上传到 Package Store 时,以下情况成立
-
它被保存到本地文件系统。
-
它与元数据一起保存。元数据文件也存储 jar 文件的 sha512 和签名。
-
集群中的每个活动节点都会被要求下载它。
Package Store API
端点是
-
每个节点中的
PUT /api/cluster/files/{full/path/to/file}
-
GET /api/node/files/{full/path/to/file}
下载文件 -
GET /api/node/files/{full/path/to/file}?meta=true
获取文件的元数据 -
GET /api/node/files/{full/path/to/}
获取/full/path/to
中的文件列表
对您的制品进行签名
使用以下步骤上传使用您的公钥签名的 jar
-
如果您没有带有插件的 jar 文件,请从 GitHub 下载一个示例
curl -o runtimelibs.jar -LO https://github.com/apache/solr/blob/releases/solr/9.5.0/solr/core/src/test-files/runtimecode/runtimelibs.jar.bin?raw=true
-
使用您的私钥对 jar 进行签名
openssl dgst -sha1 -sign my_key.pem runtimelibs.jar | openssl enc -base64 | sed 's/+/%2B/g' | tr -d \\n | sed
-
上传您的 jar 和签名,用前一个命令的输出替换
sig
参数curl --data-binary @runtimelibs.jar -X PUT http://localhost:8983/api/cluster/files/mypkg/1.0/myplugins.jar?sig=<signature-of-jar>
-
验证您的 jar 上传
curl http://localhost:8983/api/node/files/mypkg/1.0?omitHeader=true
{ "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.0、1.9.0、1.11.0 的软件包,Solr 会选择 1.9.0 作为最新版本。 |
例如
{
"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 端点
-
GET /api/cluster/package
获取软件包列表 -
POST /api/cluster/package
编辑包-
add
命令:添加包的版本 -
delete
命令:删除包的版本
-
并行使用多个版本
我们在集合配置中使用 params.json
存储它使用的包版本。默认情况下,它为 $LATEST
。
{"params":{
"PKG_VERSIONS": {
"mypkg": "0.1", (1)
"pkg2" : "$LATEST", (2)
}}}
1 | 对于 mypkg ,无论是否有较新版本可用,都使用版本 0.1 。 |
2 | 对于 pkg2 ,使用最新版本。这是可选的。默认值为 $LATEST 。 |
因此,在上面的示例中,如果 |
在插件中使用包
任何类名都可以使用包名作为前缀,例如 mypkg:fully.qualified.ClassName
,Solr 将使用包的最新版本从中加载类。从包加载的插件不能依赖于核心级别的类。
solrconfig.xml
中的插件声明<requestHandler name="/myhandler" class="mypkg:full.path.to.MyClass">
</requestHandler>
完整的操作示例
-
创建包
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"]}}'
-
验证已创建的包
curl http://localhost:8983/api/cluster/package?omitHeader=true
{"result":{ "znodeVersion":0, "packages":{"mypkg":[{ "version":"1.0", "files":["/mypkg/1.0/myplugins.jar"]}]}}}
-
此时包应该可以使用了。接下来,从包中在集合中注册插件。请注意应用于
class
属性的mypkg:
前缀。通过编辑solrconfig.xml
也可以实现相同的效果curl http://localhost:8983/solr/gettingstarted/config -H 'Content-type:application/json' -d '{ "create-requesthandler": { "name": "/test", "class": "mypkg:org.apache.solr.core.RuntimeLibReqHandler" }}'
-
验证组件是否已创建,并且它使用正确的包版本加载类
curl http://localhost:8983/solr/gettingstarted/config/requestHandler?componentName=/test&meta=true&omitHeader=true
{ "config":{"requestHandler":{"/test":{ "name":"/test", "class":"mypkg:org.apache.solr.core.RuntimeLibReqHandler", "_packageinfo_":{ "package":"mypkg", "version":"1.0", "files":["/mypkg/1.0/myplugins.jar"]}}}}}
-
测试请求处理程序
curl http://localhost:8983/solr/gettingstarted/test?omitHeader=true
{ "params":{ "omitHeader":"true"}, "context":{ "webapp":"/solr", "path":"/test", "httpMethod":"GET"}, "class":"org.apache.solr.core.RuntimeLibReqHandler", "loader":"java.net.FactoryURLClassLoader"}
-
更新组件版本。获取新版本的 jar,签名并上传
curl -o runtimelibs3.jar -LO https://github.com/apache/solr/blob/releases/solr/9.5.0/solr/core/src/test-files/runtimecode/runtimelibs_v3.jar.bin?raw=true openssl dgst -sha1 -sign my_key.pem runtimelibs.jar | openssl enc -base64 | sed 's/+/%2B/g' | tr -d \\n | sed curl --data-binary @runtimelibs3.jar -X PUT http://localhost:8983/api/cluster/files/mypkg/2.0/myplugins.jar?sig=
-
验证
curl http://localhost:8983/api/node/files/mypkg/2.0?omitHeader=true
{ "files":{"/mypkg/2.0":[{ "name":"myplugins.jar", "timestamp":"2019-11-11T11:46:14.771Z", "sha512":"60ec88c2a2e9b409f7afc309273383810a0d07a078b482434eda9674f7e25b8adafa8a67c9913c996cbfb78a7f6ad2b9db26dbd4fe0ca4068f248d5db563f922", "sig":["ICkC+nGE+AqiANM0ajhVPNCQsbPbHLSWlIe5ETV5835e5HqndWrFHiV2R6nLVjDCxov/wLPo1uK0VzvAPIioUQ=="]}]}}
-
添加包的新版本
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"]}}'
-
验证插件以查看是否使用包的正确版本
curl http://localhost:8983/solr/gettingstarted/config/requestHandler?componentName=/test&meta=true&omitHeader=true
{ "config": { "requestHandler": { "/test": { "name": "/test", "class": "mypkg:org.apache.solr.core.RuntimeLibReqHandler", "_packageinfo_": { "package": "mypkg", "version": "2.0", "files": [ "/mypkg/2.0/myplugins.jar" ] }}}}}
-
测试插件
curl http://localhost:8983/solr/gettingstarted/test?omitHeader=true
{ "params": { "omitHeader": "true" }, "context": { "webapp": "/solr", "path": "/test", "httpMethod": "GET" }, "class": "org.apache.solr.core.RuntimeLibReqHandler", "loader": "java.net.FactoryURLClassLoader", "Version": "2" }
请注意,
Version
值为"2"
,这意味着插件已更新。