又一个centos文件顺序导致的问题

背景

新的centos似乎对于文件顺序做了特别的优化 和文件顺序出现的问题确实多了不少

centos7导致的spring循环依赖【实际上和这个问题不一样 不过由此衍生出的问题】

某应用放在新的系统开始报错

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
Exception in thread "Thread-10" redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
at redis.clients.util.Pool.getResource(Pool.java:53)
at redis.clients.jedis.JedisPool.getResource(JedisPool.java:99)
at net.oschina.j2cache.redis.support.RedisSingleFactory.getResource(RedisSingleFactory.java:23)
at net.oschina.j2cache.redis.support.RedisSingleFactory.getResource(RedisSingleFactory.java:12)
at net.oschina.j2cache.redis.RedisCacheProxy.getResource(RedisCacheProxy.java:27)
at net.oschina.j2cache.redis.RedisCacheProxy.subscribe(RedisCacheProxy.java:118)
at net.oschina.j2cache.RedisCacheChannel$1.run(RedisCacheChannel.java:51)
at java.lang.Thread.run(Thread.java:745)
Caused by: redis.clients.jedis.exceptions.JedisConnectionException: java.net.ConnectException: Connection refused
at redis.clients.jedis.Connection.connect(Connection.java:164)
at redis.clients.jedis.BinaryClient.connect(BinaryClient.java:80)
at redis.clients.jedis.BinaryJedis.connect(BinaryJedis.java:1677)
at redis.clients.jedis.JedisFactory.makeObject(JedisFactory.java:87)
at org.apache.commons.pool2.impl.GenericObjectPool.create(GenericObjectPool.java:868)
at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:435)
at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:363)
at redis.clients.util.Pool.getResource(Pool.java:49)
... 7 more
Caused by: java.net.ConnectException: Connection refused
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:579)
at redis.clients.jedis.Connection.connect(Connection.java:158)
... 14 more

分析

由于系统报错连接不上redis因此考虑如下几个可能性

  1. 是否存在防火墙
  2. 是否对应dns为解析到合适的ip
  3. redis的host和port是否存在错误

对应前两条经过排查发觉没有问题 那么着重排查一下第三条

该项目使用了maven的profile maven profile VS spring profile 因此为了避免由于某些原因导致文件没有被替换 我决定查看对应的编译文件

924b6bebd6711cf3aaa29c4f1dad2128cec.jpg

host和port均是正确的~那么缘何一直报错呢????!!!!

有点走进了绝路~

柳暗花明

既然现实告诉了我目前文件用了redis.f6car的域名并且可以正常连接~但是系统就是无法正常调用成功!

那么究竟问题是如何出现的???

查看一下获取配置文件的地方

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private final static String CONFIG_FILE = "/j2cache.properties";
private static Properties loadConfig() throws IOException {
log.info("Load J2Cache Config File : [{}].", CONFIG_FILE);
InputStream configStream = J2Cache.class.getClassLoader().getParent().getResourceAsStream(CONFIG_FILE);
if(configStream == null)
configStream = CacheManager.class.getResourceAsStream(CONFIG_FILE);
if(configStream == null)
throw new CacheException("Cannot find " + CONFIG_FILE + " !!!");
Properties props = new Properties();
try{
props.load(configStream);
}finally{
configStream.close();
}
return props;
}

我们知道getResourceAsStream中/打头的话表示使用classpath 那么发觉j2cache.properties其实存在多个……

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
/**
* Finds a resource with a given name. The rules for searching resources
* associated with a given class are implemented by the defining
* {@linkplain ClassLoader class loader} of the class. This method
* delegates to this object's class loader. If this object was loaded by
* the bootstrap class loader, the method delegates to {@link
* ClassLoader#getSystemResourceAsStream}.
*
* <p> Before delegation, an absolute resource name is constructed from the
* given resource name using this algorithm:
*
* <ul>
*
* <li> If the {@code name} begins with a {@code '/'}
* (<tt>'\u002f'</tt>), then the absolute name of the resource is the
* portion of the {@code name} following the {@code '/'}.
*
* <li> Otherwise, the absolute name is of the following form:
*
* <blockquote>
* {@code modified_package_name/name}
* </blockquote>
*
* <p> Where the {@code modified_package_name} is the package name of this
* object with {@code '/'} substituted for {@code '.'}
* (<tt>'\u002e'</tt>).
*
* </ul>
*
* @param name name of the desired resource
* @return A {@link java.io.InputStream} object or {@code null} if
* no resource with this name is found
* @throws NullPointerException If {@code name} is {@code null}
* @since JDK1.1
*/

d79599221e64533d2ad8f83bc9d745d9052.jpg

原来的第三方jar默认就提供了一个文件

那么当调用getResourceAsStream究竟会取到那个文件呢????

答案是:不确定!!!

If there are two JAR files in the classpath, both containing a resource named “config.properties” in its root. Is there a way to retrieve both files similar to getClass().getResourceAsStream()? The order is not relevant.

An alternative would be to load every property file in the class path that match certain criterias, if this is possible at all.

那么如果我们取到了对应的j2cache.properties的话会怎么样呢???

该死的redis.host变成了what????

1
redis.host = localhost

ecef28b66d106eaa2ee2902a8f81e805014.jpg

绝大部分的不确定其实都不是那么不确定【哈哈~非常绕 也就是不保证 可能会有意外】

我们看一下为何其他系统没有问题~【sb项目在j2cache-dev.properties 独一份】当然没有问题

那么我们的主项目呢???

我们的jar命名基本都是biz-XXX.jar

但是在该项目呢???【为了保证被最先加载其实最好不要放在jar中~ 不过此处是jar】

1
2
3
4
5
6
7
8
9
10
11
12
***
-rw-r--r-- 1 root root 101K 2017-06-06 16:45 j2cache-core-1.4.0.jar
***
-rw-r--r-- 1 root root 5.1K 2018-07-04 18:16 wechat-biz-api-impl-wechat-1.0-SNAPSHOT.jar
-rw-r--r-- 1 root root 3.3K 2018-07-04 18:16 wechat-biz-api-wechat-1.0-SNAPSHOT.jar
-rw-r--r-- 1 root root 5.0K 2018-07-04 18:16 wechat-biz-mapper-wechat-1.0-SNAPSHOT.jar
-rw-r--r-- 1 root root 4.7K 2018-07-04 18:16 wechat-biz-model-wechat-1.0-SNAPSHOT.jar
-rw-r--r-- 1 root root 73K 2018-07-04 18:16 wechat-biz-service-impl-wechat-1.0-SNAPSHOT.jar
-rw-r--r-- 1 root root 8.6K 2018-07-04 18:16 wechat-biz-service-wechat-1.0-SNAPSHOT.jar
-rw-r--r-- 1 root root 35K 2018-07-04 18:16 wechat-biz-vo-wechat-1.0-SNAPSHOT.jar
-rw-r--r-- 1 root root 15K 2018-07-04 18:16 wechat-utility-wechat-1.0-SNAPSHOT.jar
***

基本上来看也是按照文件顺序【不过由于有缓存所以很难说有顺序保证 毕竟可能在取得另一个文件的时候可能已经加载了所有的resource并放入缓存中】

那么是不是以前也有这个问题呢???

并没有~以前artifactId直接就是biz-XXX 那么为何要做变更呢???

第一项写明做api发布的时候要区分artifactIdo(╥﹏╥)o

方案

  1. 修改jar名称不要w打头太靠后了……【这个有点low】
  2. 将文件挪到web目录下 由于war在tomcat中会自动展开 这样文件就不会以jar的形式存在了 优先级比较高~