首页 > 代码库 > nexus构件管理研究-关于nexus中有构件仓库中无法搜索到但是在指定构件的Browse Remote中可查到的原因分享

nexus构件管理研究-关于nexus中有构件仓库中无法搜索到但是在指定构件的Browse Remote中可查到的原因分享

背景:

周五同事和我探讨一个话题,他在我们搭建的nexus仓库中搜到的slf4j版本是3.1(打个比方),位于代理的Central Repository,但是他需要的版本是3.2(打个比方), 但是此nexus中没有slf4j的3.2版本,但是当他点击进Central Repository并且选择browse Remote Index时候,却看到有3.2版本(和其他版本)的构件,为什么呢?


原因分析:

经过分析,我找到了原因,原来搜索仓库和点击某仓库选择browse Remote Index走的是不一样的机制。


对于仓库搜索,其等效于仓库查询:

其调用的请求是:http://localhost:8081/nexus/service/local/repositories?_dc=1416624550968 ,这个请求的响应入口在${bundleBaseDir}/nexus/WEB-INF/plugin-repository/nexus-restlet1x-plugin-2.10.0-02目录下的nexus-restlet1x-plugin-2.10.0-02.jar包中的RepositoryListPlexusResource类的get()方法:

wKiom1Ryk9fCAL11AADujVEaTMU731.jpg

其中listRepositories()方法定义在父类AbstractRepositoryPlexusResource中,它用于构造响应json payload.构造完响应对象就是每个被nexus代理的repository类的详细信息,为了突出重点,我这里只贴了一部分(比如代理的central repository的信息):

wKioL1RylNTihoUEAAEZYcc6g2c912.jpg

从这里看出,请求查看的配置URI是http://localhost:8081/nexus/service/local/repositories/central,它打开后是一个XML格式的仓库配置文件。而仓库中缓存的中央仓库的内容则可以通过contentResourceURI来访问。缓存的内容存储在nexus所在文件系统的effectiveLocalStorageUrl (即${bundleBasedir}/../sonatype-work /nexus/storage/{repositoryId}),缓存的内容所代理的真正远程仓库地址配置在remoteUri中。而我们知道,只有maven应用配置了指向本地仓库,当使用某构件时候,nexus发现自己没有,这才会从中央仓库下载指定的构件并且存储在storage子目录下。否则,它是绝对不会主动从远程仓库吧这些构件都下载到本地的(这个很容易想,因为代理的仓库都非常巨大,涉及构件多个版本,你总不能把自己搭的服务器去和真正远程仓库去比把,存储的数量级也不一样)。


实验也证实了我们这一点,比如刚安装的这个干净的nexus, 这个${bundleBasedir}/../sonatype-work /nexus/storage/{repositoryId})里面是没有具体的构件的,只有一个archetype-catalog.xml:

干净的nexus local 存储截图如下(以代理的repositoryId=central 为例):

wKioL1Ryl8zCJOwNAAHfPf0R1JU398.jpg

这个archetype-catalog.xml只用于标示此仓库中构件的目录。


所以,我们相信,如果在nexus仓库中搜到了slf4j版本是3.1的构件,那么肯定我们有某个项目的<dependency>或者间接<dependency>中用到了这个构件,因此同事在构件仓库搜索中是搜到了这个构件的。但是因为从来没任何的项目用到slf4j版本是3.2的构件,所以构件仓库搜索中搜不到。


关于某仓库的“Browse Remote ”:

从web 客户端工具可以看出,它实际请求的URL是:

wKioL1RymnnQYCvYAACnTn8SEtI672.jpg

这个请求会被位于${bundleBaseDir}\nexus\WEB-INF\plugin-repository\nexus-rrb-plugin-2.10.0-02目录下的nexus-rrb-plugin-2.10.0-02中的RemoteBrowserResource类的get()方法所响应。

wKioL1Rymq7QEkWsAAF32S5PAZU745.jpg

在get方法中,它会先获取repositoryId(比如我们例子中的id=central),接着调用getResourceStoreRequest(request)方法来获取remote的列表,它其中会调用getValidRemoteIPAddress(request))方法来获取真正要访问的远程IP地址,比如我们的central就是访问前面多次提到的repo1.maven.org。 所以这一步必需要联网,否则无法解析出repo1.maven.org. 比如我做了个实验,我故意吧网络断开,则当点击”Browse Remote”并刷新时,就无法显示结果:

wKiom1RymmXThMDEAAE_Ho4sjLA805.jpg

所以我们相信,当我们点击central repository并且查看“browse remote"时候,在联网的情况下,他总能找到这个构件(比如例子中版本是3.2的 slf4j),因为你搜索的是中央仓库。


总结:

(1)对于在仓库浏览器中浏览或者搜索构件,其搜索的是存在nexus服务器本地${bundleBasedir}/../sonatype-work /nexus/storage目录下的构件,如果找不到就找不到了。这些构件当maven应用配置指向nexus地址,并且nexus在自己层面找不到构件,才从相应的所代理的远程仓库中下载构件,并且存入storage目录。

(2)对于点击某仓库,查看其"browse remote",则只要网络通,就总能看到某版本构件,因为你直接查看了远程仓库的构件索引。

本文出自 “平行线的凝聚” 博客,请务必保留此出处http://supercharles888.blog.51cto.com/609344/1581806

nexus构件管理研究-关于nexus中有构件仓库中无法搜索到但是在指定构件的Browse Remote中可查到的原因分享