Fork me on GitHub

大版本更新上线问题汇总

Tomcat 容器启动问题

前提

  1. Spring Boot 版本 2.0.3.RELEASE
  2. druid-spring-boot-starter 版本 1.1.9
  3. mysql-connector-java 版本 5.1.46
  4. MySQL 数据库版本 5.7
  5. Tomcat 版本 7.0.67(最终升级了版本到 Tomcat 8)
  6. JDK 版本 1.7(最终升级到1.8)

问题: 测试、生产配置文件属性不同步,生产环境很多属性未配置,导致错误注入。
解决: 将所有注入的 API 地址同步。


问题: 启动时 Dubbo 报错,找不到服务。

解决: 提供者所在机器 Dubbo 端口未开放,开放对应端口即可。


问题: Tomcat 无法启动,每次启动报不同的错误。

解决: JDK版本升级到 1.8→Tomcat 版本升级到 7.0.92


问题: java.lang.NoClassDefFoundError: javax/el/ELManager

解决:参考


问题:

配置:

1
2
3
4
5
6
7
# MySQL数据源配置
datasource:
driver-class-name: com.mysql.jdbc.Driver
druid:
url: jdbc\:mysql\://rds.xxx.com\:3306/xxx?useUnicode\=true&characterEncoding\=UTF-8&zeroDateTimeBehavior\=convertToNull
username: xxx
password: password

异常信息:

1
2
3
4
5
6
7
8
9
10
11
Caused by: java.sql.SQLException: connect error, url jdbc\:mysql\://rds.xxx.com\:3306/xxx?useUnicode\=true&characterEncoding\=UTF-8&zeroDateTimeBehavior\=convertToNull, driverClass com.mysql.jdbc.Driver
at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1582)
at com.alibaba.druid.pool.DruidDataSource.init(DruidDataSource.java:859)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeCustomInitMethod(AbstractAutowireCapableBeanFactory.java:1833)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1776)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1704)
... 116 more

解决: 异常信息里非常明确的提及是数据库连接 url 的问题,在 Spring Boot 的 yml 配置文件中,格式为:property: value 属性名称加「:」之后有一个空格,项目之前的配置文件中 MySQL 数据库的连接地址转义过,这里直接复制过来使用,是行不通的,将转义字符「\」去掉即可。


Tomcat 重启之后异常

问题:

异常信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
org.apache.catalina.session.StandardManager doLoad
SEVERE: IOException while loading persisted sessions: java.io.EOFException
java.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2298)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2767)
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:798)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:298)
...

org.apache.catalina.session.StandardManager startInternal
SEVERE: Exception loading sessions from persistent storage
java.io.EOFException
...

解决: 删除 ${catalina.home}/work/Catalina/localhost/${APP-NAME}/SESSION.ser 即可


问题: Dubbo 报错

报错信息:

1
2
3
4
5
6
7
2018-12-15 20:26:52,387 [DubboSaveRegistryCache-thread-1] WARN  [com.alibaba.dubbo.registry.zookeeper.ZookeeperRegistry] -  [DUBBO] Failed to save registry store file, cause: Can not lock the registry cache file /root/.dubbo/dubbo-registry-10.11.12.13.cache, ignore and retry later, maybe multi java process use the file, please config: dubbo.registry.file=xxx.properties, dubbo version: 2.5.3, current host: 10.20.30.40
java.io.IOException: Can not lock the registry cache file /root/.dubbo/dubbo-registry-10.11.12.13.cache, ignore and retry later, maybe multi java process use the file, please config: dubbo.registry.file=xxx.properties
at com.alibaba.dubbo.registry.support.AbstractRegistry.doSaveProperties(AbstractRegistry.java:193)
at com.alibaba.dubbo.registry.support.AbstractRegistry$SaveProperties.run(AbstractRegistry.java:150)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)

Dubbo 会使用文件缓存注册中心地址列表及服务提供者列表,默认路径在 /${user.home}/.dubbo/dubbo-registry-10.20.30.40.cache,应用重启时将基于此文件恢复,一台服务器有多个应用使用这个文件恢复时,会出现这个警告。

解决: 可以在每个项目 Dubbo 配置文件中的 dubbo:registry 标签中的 file 指定不同的文件路径。 官方文档 参考地址


问题: Tomcat 容器无日志输出
logback-spring.xml配置:

1
2
3
4
5
6
7
8
9
10
...
<!-- 测试环境+开发环境. -->
<springProfile name="test,dev">
<logger name="com.xxx.im" level="INFO"/>
</springProfile>
<!-- 生产环境 -->
<springProfile name="prod">
<logger name="com.xxx.im" level="ERROR"/>
</springProfile>
...

解决: 生产环境日志输出级别过高,INFO 级别的无法输出,将 ERROR 改为 INFO 即可。


转战华为云之后🙂

RabbitMQ 连接

Spring Boot 版本 2.0.3.RELEASE

问题: RabbitMQ 直接使用 yaml 配置如下:

1
2
3
4
5
6
spring:
rabbitmq:
host: rabbitmq.xxx.com
username: user
password: password123456
port: 5672

项目启动时报错信息:

1
2
3
...
...ForgivingExceptionHandler - An unexpected connection driver error occured (Exception message: Connection closed)
...

解决: 从异常日志中可以很明显的看到,是 Connection closed,解决思路如下:

  1. 初步判断当前机器无法连通 RabbitMQ 所在机器,使用 ping rabbitmq.xxx.com 命令可以 ping 通 RabbitMQ 所在机器,并且 telnet rabbitmq.xxx.com 5672 也是可以连通的,排除此原因;

  2. 确认 username、password 准确性,发现 RabbitMQ 是新装的,使用命令查看其用户:

    1
    2
    3
    [root@rabbit ~]# rabbitmqctl list_users
    Listing users ...
    admin [administrator]

    发现并没有 user 这个用户,创建用户:

    1
    2
    [root@rabbit ~]# rabbitmqctl add_user user password123456
    Creating user "user" ...

    设置为管理员:

    1
    2
    [root@rabbit ~]# rabbitmqctl set_user_tags user administrator
    Setting tags for user "user" to [administrator] ...

    此时,使用该用户登录 RabbitMQ WEB 端管理页面后查看该用户信息:
    image
    点击 Set permission 配置权限,重启项目后问题解决。


Tomcat 问题

问题: 启动 Tomcat 容器报错信息如下:

1
2
3
org.apache.tomcat.jni.Error: 70023: This function has not been implemented on this platform
at org.apache.tomcat.jni.SSL.initialize(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

解决: 修改 $TOMCAT_HOME/conf/server.xml 中的 <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="off" /> 即可解决。

Tomcat 问题

问题: 启动 Tomcat 容器报错信息如下:

1
2
3
org.apache.tomcat.jni.Error: 70023: This function has not been implemented on this platform
at org.apache.tomcat.jni.SSL.initialize(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

解决: 修改 $TOMCAT_HOME/conf/server.xml 中的 <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="off" /> 即可解决。

线上问题处理

问题:

MongoDB 版本:TokuMX 2.0.2 | MongoDB 2.4

spring-data-mongodb 版本:1.4.1.RELEASE

spring-data-commons 版本:1.7.2.RELEASE

1
2
3
4
5
6
7
8
java.lang.IllegalArgumentException: You have to provide at least one property to sort by!
at org.springframework.data.domain.Sort.<init>(Sort.java:91)
at org.springframework.data.domain.Sort.<init>(Sort.java:79)
...
at sun.reflect.GeneratedMethodAccessor415.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
...

解决: 异常信息很明确,未提供排序的属性,检查代码,异常代码片段如下:

1
2
3
4
5
6
7
8
9
10
11
12
...
@Autowired
private MongoTemplate mongoTemplate;
...
Query query = new Query();
List<String> sortStrList = new ArrayList<>();
if (...) {
sortStrList.add("property");
}
query.with(new Sort(Sort.Direction.DESC, sortStrList.toArray(new String[sortStrList.size()])))
mongoTemplate.find(query, Xxx.class);
...

很明显,排序属性集合 sortStrList 中有可能没有任何属性,再查看 org.springframework.data.domain.Sort 中的构造方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public Sort(Sort.Direction direction, String... properties) {
this(direction, (List)(properties == null ? new ArrayList() : Arrays.asList(properties)));
}

public Sort(Sort.Direction direction, List<String> properties) {
if (properties != null && !properties.isEmpty()) {
this.orders = new ArrayList(properties.size());
Iterator i$ = properties.iterator();

while(i$.hasNext()) {
String property = (String)i$.next();
this.orders.add(new Sort.Order(direction, property));
}

} else {
throw new IllegalArgumentException("You have to provide at least one property to sort by!");
}
}

可以看出,sortStrList 完全无需转换为数组,但这不是主要原因,从下面的构造方法中可以看出,传入的 List 集合不可为空对象并且必须集合大小必须大于 0,所以解决方案可以有多种,只需控制 sortStrList 集合不为空且 size 大于 0,或者根据判断查询不加排序条件也可以解决。


问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
org.springframework.data.mongodb.UncategorizedMongoDbException: Lock not granted. Try restarting the transaction.; nested exception is com.mongodb.MongoExcep
tion: Lock not granted. Try restarting the transaction.
at org.springframework.data.mongodb.core.MongoExceptionTranslator.translateExceptionIfPossible(MongoExceptionTranslator.java:83)
at org.springframework.data.mongodb.core.MongoTemplate.potentiallyConvertRuntimeException(MongoTemplate.java:1828)
at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:409)
at org.springframework.data.mongodb.core.MongoTemplate.doUpdate(MongoTemplate.java:995)
at org.springframework.data.mongodb.core.MongoTemplate.updateFirst(MongoTemplate.java:969)
...
at sun.reflect.GeneratedMethodAccessor378.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:80)
...
at sun.reflect.GeneratedMethodAccessor200.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)

解决: 手动配置的 MongoDB 事务问题,尚未彻底解决。


问题:

Spring 整合 MongoDB配置文件:

1
2
3
4
5
6
7
8
9
10
11
> <bean id="mongoOptions" class="com.mongodb.MongoOptions">
> ...
> <!-- 连接超时时间(毫秒),默认为4000 -->
> <property name="connectTimeout" value="4000" />
> <!-- socket读写时超时时间(毫秒),默认为0,不超时 -->
> <property name="socketTimeout" value="0" />
> <!-- 是socket连接在防火墙上保持活动的特性,默认为false -->
> <property name="socketKeepAlive" value="true" />
> ...
> </bean>
>
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
org.springframework.dao.DataAccessResourceFailureException: can't say something; nested exception is com.mongodb.MongoException$Network: can't say something
at org.springframework.data.mongodb.core.MongoExceptionTranslator.translateExceptionIfPossible(MongoExceptionTranslator.java:56)
at org.springframework.data.mongodb.core.MongoTemplate.potentiallyConvertRuntimeException(MongoTemplate.java:1828)
at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:409)
at org.springframework.data.mongodb.core.MongoTemplate.insertDBObject(MongoTemplate.java:893)
at org.springframework.data.mongodb.core.MongoTemplate.doInsert(MongoTemplate.java:713)
at org.springframework.data.mongodb.core.MongoTemplate.insert(MongoTemplate.java:668)
at org.springframework.data.mongodb.core.MongoTemplate.insert(MongoTemplate.java:659)
at net.okdi.o2o.core.helper.ExceptionHelper.afterThrow(ExceptionHelper.java:71)
at sun.reflect.GeneratedMethodAccessor438.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
...
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Caused by: com.mongodb.MongoException$Network: can't say something
at com.mongodb.DBTCPConnector.say(DBTCPConnector.java:194)
at com.mongodb.DBTCPConnector.say(DBTCPConnector.java:155)
at com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:249)
at com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:205)
at com.mongodb.DBCollection.insert(DBCollection.java:57)
at com.mongodb.DBCollection.insert(DBCollection.java:100)
at org.springframework.data.mongodb.core.MongoTemplate$8.doInCollection(MongoTemplate.java:898)
at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:407)
... 44 more
Caused by: java.io.IOException: couldn't connect to [mongodb.xxx.com/192.168.1.22:27017] bc:java.net.SocketTimeoutException: connect timed out
at com.mongodb.DBPort._open(DBPort.java:214)
at com.mongodb.DBPort.go(DBPort.java:107)
at com.mongodb.DBPort.go(DBPort.java:88)
at com.mongodb.DBPort.findOne(DBPort.java:143)
at com.mongodb.DBPort.runCommand(DBPort.java:148)
at com.mongodb.DBPort.checkAuth(DBPort.java:307)
at com.mongodb.DBTCPConnector.say(DBTCPConnector.java:180)
... 51 more

解决: 异常最后很明确的提示了 connect timed out 连接超时的问题,我们可以将 connectTimeout 连接超时属性适当扩大,如果是提示 read timed out,原因是在进行数据操作时过长时间没有返回结果,此时要修改 socketTimeout 属性了。

参考文章

------本文结束------
0%