全部产品
云市场

SOFABoot 常见问题

更新时间:2019-09-20 20:47:34

说明:有关 SOFABoot 各版本的已知问题列表,请查看 限制与已知问题

升级相关问题


其他常见问题


升级相关问题

升级前有哪些环节准备

在升级前,必须安装 JDK 7 和 Maven 3.2.5。具体安装步骤,可参考文档 配置 SOFABoot 环境


如何激活不同环境配置

当您需要在不同环境下(如开发环境、测试环境、预发布环境、生产环境)提供不同的配置时,可以在启动 SOFABoot 应用时加上以下 JVM 启动参数:

  1. -Dspring.profiles.active=${workspace_name}

更多信息,见 工程配置解决方案


完成编译后,如何在本地运行

在工程根目录下执行下列命令:

  1. mvn clean install
  2. java -jar ./target/${file.name}-executable.jar (使用 java -jar 命令运行一个 Fat Jar,在 SOFAStack 上部署应用也是这种方式)

当然本地开发时,可以直接使用 main 函数启动整个应用。

更多信息,参见 本地编译运行


如何使用占位符

可以通过配置文件统一管控所有的普通 bean 的配置。

以 SOFARPC 中间件为例,支持对 test-url 进行占位符配置,如下所示:

  1. <sofa:reference id="sampleRpcService"
  2. interface="com.alipay.sofalite2.serverone.facade.rpc.SampleRpcService">
  3. <sofa:binding.tr>
  4. <sofa:global-attrs test-url="${test.url}"/>
  5. </sofa:binding.tr>
  6. </sofa:reference>

SOFABoot 与 SOFALite 1.0 是否兼容,是否支持间接引入

  • SOFABoot 和 SOFALite 1.0 不能相互依赖,两者依赖的底层中间件一致,但选择上层框架时,只能选择其一。两者是完全独立的框架,不可混用。
  • 同时,也要注意间接依赖引入的情况,使用 SOFABoot 就只能依赖 sofaboot-enterprise-dependencies,不能再间接引入 SOFALite 1.0 的 slite-dependencies

日志中出现 StackOverFlow 错误

问题描述

您可能在日志中看到以下堆栈错误:

  1. Detected both log4j-over-slf4j.jar AND slf4j-log4j12.jar on the class path, preempting StackOverflowError:
  2. Exception in thread java.lang.StackOverflowError
  3. at java.util.Hashtable.containsKey(Hashtable.java:306)
  4. at org.apache.log4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:36)
  5. at org.apache.log4j.LogManager.getLogger(LogManager.java:39)
  6. at org.slf4j.impl.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:73)
  7. at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:249)
  8. at org.apache.log4j.Category.<init>(Category.java:53)
  9. at org.apache.log4j.Logger..<init>(Logger.java:35)
  10. at org.apache.log4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:39)
  11. at org.apache.log4j.LogManager.getLogger(LogManager.java:39)
  12. at org.slf4j.impl.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:73)
  13. at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:249)
  14. at org.apache.log4j.Category..<init>(Category.java:53)
  15. at org.apache.log4j.Logger..<init>(Logger.java:35)
  16. at org.apache.log4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:39)
  17. at org.apache.log4j.LogManager.getLogger(LogManager.java:39)
  18. subsequent lines omitted...

原因

这是由于 org.slf4j:log4j-over-slf4jlog4j:log4j 存在冲突而导致的。

解决方法

在 ClassPath 中删除 log4j-over-slf4j 依赖即可解决该问题。


SOFABoot 的依赖与 Embedded-SOFA 模式的依赖混用

虽然提供了两种模式的中间件使用方法,但是应用只能选择其中的一种模式使用。

也就是说在升级 SOFABoot 的过程中,只应该引入 SOFABoot 相关的依赖,具体的依赖形式为:XXX-sofa-boot-starter 或者 spring-boot-starter-XXX

不要引入 Embedded-SOFA 模式下的依赖,具体形式为 XXX-spring-starter


如何引入 Spring Boot 的 Web 容器

  • 引入 spring-boot-starter-web,默认依赖并启动的 Web 容器是 Tomcat,依赖信息类似如下:

    1. <dependency>
    2. <groupId>org.springframework.boot</groupId>
    3. <artifactId>spring-boot-starter-web</artifactId>
    4. </dependency>
  • 如果要引入 Jetty 作为 Web 容器,可以参考 Spring Boot 官方文档 进行配置。


在 SOFABoot 工程中如何处理自定义 filter

SOFABoot 工程中没有 Spring 工程的 web.xml,如果原 Spring MVC 或 SOFALite Web 工程的 web.xml 配置文件有自定义配置 filter,可以参考 SpringBoot 官方迁移 Servlets、Filters、listeners 的方法,也可以参考 中文配置案例


日志中出现 ConverterRegistry.addConverter 报错

问题描述

在日志中出现如下记录:

  1. Caused by:java.lang.NoSuchMethodError:org.springframework.core.convert.converter.ConverterRegistry.addConverter(Ljava/lang/Class;Ljava/lang/Class;Lorg/springframework/core/convert/converter/Converter;)

原因

这是由于 Spring 版本冲突所导致。

解决方法

目前的 Spring 统一版本为 4.3.4.RELEASE,删除间接引入的其他版本即可解决该问题。


日志中出现 LoggerSpaceManager.getLoggerBySpace 报错

问题描述

在日志中出现如下记录:

  1. Caused by:java.lang.NoSuchMethodError: com.alipay.sofa.common.log.LoggerSpaceManager.getLoggerBySpace(Ljava/lang/String;Lcom/alipay/sofa/common/log/SpaceId;Ljava/util/Map;)Lorg/slf4j/Logger;

原因

从 2.2.X 版本后,由于 ArtifactId sofa-middleware-log 升级为 sofa-common-tools,所以当使用 SOFABoot(原 SOFALite) 2.2.X 的版本时,保证 classpath 依赖的是 sofa-common-tools(版本已经管控不需要用户显示添加版本) 同时排除掉 sofa-middleware-log 依赖即可以解决冲突问题。

解决方法

删除以下间接依赖:

  1. <dependency>
  2. <groupId>com.alipay.sofa.common.log</groupId>
  3. <artifactId>sofa-middleware-log</artifactId>
  4. </dependency>

并引入以下依赖:

  1. <dependency>
  2. <groupId>com.alipay.sofa.common</groupId>
  3. <artifactId>sofa-common-tools</artifactId>
  4. </dependency>

如何访问默认关闭的敏感端点(Sensitive Endpoints)

SOFABoot 2.5.0 及以上版本解决了因 Endpoints 信息暴露过多而导致的安全问题,默认关闭一些具备安全风险的 Endpoints。如果您需要开启相应的 Endpoints,请参考 Spring Boot 使用文档

SOFABoot 是否支持分布式 Session

SOFABoot 不支持分布式 Session。

在原有的 SOFALite 框架中,分布式 Session 这一层逻辑很轻量。在升级为 SOFABoot 框架后,建议由用户在 Spring Boot 基础上自主进行 Session 的管理和维护。存储方案可继续使用 OCS。


其他常见问题

SOFABoot 与 SOFALite 兼容性问题

  • SOFABoot 和 SOFALite 1.0 不能同时被一个工程依赖,且选择框架时,只能两者选其一。
  • 需注意间接依赖引入的情况,若使用 SOFABoot,则只能依赖 sofaboot-enterprise-dependencies,不能再间接引入 SOFALite 1.0 的 slite-dependencies

如何显示自动配置的详细信息

加上 JVM 运行参数 -Ddebug,可以显示启动过程中的详细信息,并通过 Debug 级别的日志显示已启动的自动配置的 bean 服务。


如何使用 dependencyManagement 添加 SOFABoot 依赖

  • 工程原型中是用 parent 标签引入 SOFABoot 的间接依赖。

  • 也可以使用 dependencyManagement 添加依赖,如下所示:

    1. <dependencyManagement>
    2. <dependencies>
    3. <!-- SOFABoot dependencies -->
    4. <dependency>
    5. <groupId>com.alipay.sofa</groupId>
    6. <artifactId>sofaboot-enterprise-dependencies</artifactId>
    7. <version>2.3.1</version>
    8. <type>pom</type>
    9. <scope>import</scope>
    10. </dependency>

使用 DEV 模式进行 RPC 调用时提示找不到服务

检查电脑用户主目录下是否存在名为 localFileRegisty 的目录以及 localFileRegisty 目录下是否存在名为 localRegistry.reg 的文件。

  • 如果存在,则检查其中是否存在需要调用的服务的元数据信息。同时,请保证 DEV 模式下发布服务的应用使用的是 SOFALite 1.0.0 版本或者 SOFABoot 2.1.3 及以上的版本.
  • 如果不存在,将服务发布端应用的 SOFABoot 升级到 2.1.3 及以上版本。

SOFABoot 是否支持 iBATIS

  • iBATIS 可以在 SOFABoot 中使用。但 SOFABoot 使用的是 Spring 4,而 Spring 4 不支持 iBATIS,在使用过程中可能会遇到类似“SqlMapClientDAOSupport 类找不到”的问题。

    因此,您可以在对应的 pom.xml 中添加如下 iBATIS 提供的依赖:

    1. <dependency>
    2. <groupId>org.mybatis</groupId>
    3. <artifactId>mybatis-2-spring</artifactId>
    4. <version>1.0.3</version>
    5. </dependency>
  • iBATIS 社区已经不支持运维,为了以后长期的发展与业务稳定,建议升级到 MyBatis。配置方法可遵照 MyBatis 官网文档 - 如何接入 Spring Boot

Unsupported major.minor version 51.0 异常

问题描述

当编译工程时,收到以下报错:

  1. Exception in thread "main" java.lang.UnsupportedClassVersionError :
  2. Unsupported major.minor version 51.0

解决方法

使用 JDK 7 或以上版本来运行工程(推荐使用 JDK 8)。


Tracer 类转换异常

问题描述

出现如下错误:

原因

DummyContextUtil 的 create 操作和 clear 操作必须要配合使用。如果调用 create 操作时,当前 Tracer 上下文(即 ThreadLocal 中)不为空,便会出现 Tracer 类转换异常的错误。

解决方法

在调用 create 操作时,与 clear 操作配合使用即可。


Spring 配置解析错误

问题描述

Spring 在解析配置文件时出现如下错误:

  1. Caused by: org.xml.sax.SAXParseException; lineNumber: 240; columnNumber: 58; 对实体 "v" 的引用必须以 ';' 分隔符结尾。
  2. at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:203)
  3. at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:177)
  4. at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:400)
  5. at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:327)
  6. at com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1472)
  7. at com.sun.org.apache.xerces.internal.impl.XMLScanner.scanAttributeValue(XMLScanner.java:913)
  8. at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanAttribute(XMLNSDocumentScannerImpl.java:447)
  9. at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:250)
  10. at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2784)
  11. at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:602)
  12. at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:112)
  13. at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:505)
  14. at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:841)
  15. at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:770)
  16. at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
  17. at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:243)
  18. at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:339)
  19. at org.springframework.beans.factory.xml.DefaultDocumentLoader.loadDocument(DefaultDocumentLoader.java:76)
  20. at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadDocument(XmlBeanDefinitionReader.java:429)
  21. at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:391)
  22. ... 56 more

原因

配置文件中出现 & 字符,如 p=1&v=4.0

解决方法

将配置的字符 & 换为转义字符 &amp; 进行配置即可。如:将 p=1&v=4.0 替换为 p=1&amp;v=4.0


sofa-lite-web(Jetty) 如何获取业务真实访问地址

需求背景

sofa-lite-web 技术栈中使用的 web 容器为 Jetty 服务,前端业务走 SLB 进来后在 Jetty 的 request log 中记录的来源 IP 都会显示为 SLB 的 Proxy 地址,而且技术栈中的 jetty 服务配置文件比较简单并且固定,用户无法实现定制化服务,导致用户需要获取 jetty 真实的 request log 的需求无法实现,以下方案针对 sofa-lite-web 技术栈下 Jetty 容器获取真实 IP 地址的方法。

解决方法

  1. 定制 jetty.xml 配置文件。sofa-lite-web 技术栈 jetty.xml 配置文件路径为 WEB-INF/classes/etc/jetty.xml,找到 jetty.xml 配置文件中加入 x-forwarded 参数,具体代码如下;

    1. Call name="addConnector">
    2. <Arg>
    3. <New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
    4. <Set name="forwarded">true</Set>
  2. 加入 x-forwarded 后完整的 jetty 的代码如下,如还有其他需求需要特殊化订正的,也可以同时加到配置文件中。

    1. <?xml version="1.0"?>
    2. <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
    3. <!-- =============================================================== -->
    4. <!-- Configure the Jetty Server -->
    5. <!-- -->
    6. <!-- Documentation of this file format can be found at: -->
    7. <!-- http://wiki.eclipse.org/Jetty/Reference/jetty.xml_syntax -->
    8. <!-- -->
    9. <!-- Additional configuration files are available in $JETTY_HOME/etc -->
    10. <!-- and can be mixed in. For example: -->
    11. <!-- java -jar start.jar etc/jetty-ssl.xml -->
    12. <!-- -->
    13. <!-- See start.ini file for the default configuraton files -->
    14. <!-- =============================================================== -->
    15. <Configure id="Server" class="org.eclipse.jetty.server.Server">
    16. <!-- =========================================================== -->
    17. <!-- Server Thread Pool -->
    18. <!-- =========================================================== -->
    19. <Set name="ThreadPool">
    20. <!-- Default queued blocking threadpool -->
    21. <New class="org.eclipse.jetty.util.thread.QueuedThreadPool">
    22. <Set name="minThreads">10</Set>
    23. <Set name="maxThreads">200</Set>
    24. <Set name="detailedDump">false</Set>
    25. </New>
    26. </Set>
    27. <!-- =========================================================== -->
    28. <!-- Set connectors -->
    29. <!-- =========================================================== -->
    30. <Call name="addConnector">
    31. <Arg>
    32. <New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
    33. <Set name="forwarded">true</Set>
    34. <Set name="host"><Property name="jetty.host" /></Set>
    35. <Set name="port"><Property name="jetty.port" default="8080"/></Set>
    36. <Set name="maxIdleTime">300000</Set>
    37. <Set name="Acceptors">2</Set>
    38. <Set name="statsOn">false</Set>
    39. <Set name="confidentialPort">8443</Set>
    40. <Set name="lowResourcesConnections">20000</Set>
    41. <Set name="lowResourcesMaxIdleTime">5000</Set>
    42. </New>
    43. </Arg>
    44. </Call>
    45. <!-- =========================================================== -->
    46. <!-- Set handler Collection Structure -->
    47. <!-- =========================================================== -->
    48. <Set name="handler">
    49. <New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
    50. <Set name="handlers">
    51. <Array type="org.eclipse.jetty.server.Handler">
    52. <Item>
    53. <New id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>
    54. </Item>
    55. </Array>
    56. </Set>
    57. </New>
    58. </Set>
    59. <!-- =========================================================== -->
    60. <!-- extra options -->
    61. <!-- =========================================================== -->
    62. <Set name="stopAtShutdown">true</Set>
    63. <Set name="sendServerVersion">true</Set>
    64. <Set name="sendDateHeader">true</Set>
    65. <Set name="gracefulShutdown">1000</Set>
    66. <Set name="dumpAfterStart">false</Set>
    67. <Set name="dumpBeforeStop">false</Set>
    68. <Set name="handler">
    69. <New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
    70. <Set name="handlers">
    71. <Array type="org.eclipse.jetty.server.Handler">
    72. <Item>
    73. <New id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>
    74. </Item>
    75. <Item>
    76. <New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>
    77. </Item>
    78. <Item>
    79. <New id="RequestLog" class="org.eclipse.jetty.server.handler.RequestLogHandler"/>
    80. </Item>
    81. </Array>
    82. </Set>
    83. </New>
    84. </Set>
    85. <Ref id="RequestLog">
    86. <Set name="requestLog">
    87. <New id="RequestLogImpl" class="org.eclipse.jetty.server.NCSARequestLog">
    88. <Arg><SystemProperty name="jetty.logs" default="./logs"/>/yyyy_mm_dd.request.log</Arg>
    89. <Set name="retainDays">90</Set>
    90. <Set name="append">true</Set>
    91. <Set name="extended">false</Set>
    92. <Set name="LogTimeZone">GMT</Set>
    93. </New>
    94. </Set>
    95. </Ref>
    96. </Configure>
  3. jetty.xml 定制化完成后开始进行打包,将打好的 war 包上传到发布部署服务上进行发布。

    说明
    • 如果 sofa-lite-web 技术栈的版本为 1.0.2 或以上,直接发布即可。
    • 如果 sofa-lite-web 技术栈版本低于 1.0.2 的,请根据下面的方法在发布之前先升级技术栈。
  4. sofa-lite-web 技术栈版本低于 1.0.2 的请根据下面方法进行操作

    1. 新建发布单时选择 编辑高级信息,如下图:

      sofa-lite-web

    2. 启用 升级/降级 技术栈,目标版本选择 1.0.2 或以上版本即可。

      1.0.2

  5. 验证 x-forwarded 是否生效,看日志中打印的访问里请求是否包含了真实的 IP。

    服务发布完成以后 jetty 服务就会使用定制的 jetty.xml 配置文件来进行启动,同时 jetty.xml 配置文件中定制的参数都会生效,同时在服务器的 /opt/software/install/jetty-8.1.17/logs/ 下会有对应的 request.log 日志文件,比如下方图示中的 request.log 的文件为 2017_04_13.request.log,可以直接查看里面的真实 IP 地址。

    jetty


Maven 打包时出现规则检查错误

问题描述

Maven 打包时出现如下提示:

  1. Please check rules in your project:
  2. 1. SOFATracer dependencies should be com.alipay.sofa:tracer-core and com.alipay.sofa:tracer-extensions !!!
  3. 2. SOFALookout dependency should be com.alipay.sofa.lookout:lookout-api !!!

原因

SOFABoot 2.4.0 及以上版本更新了 SOFATracer 及 SOFALookout 的依赖,并强制执行规则检查。未更新的依赖会导致 Maven 编译失败。

解决方法

更新 SOFATracer 及 SOFALookout 依赖如下:

  1. <dependency>
  2. <groupId>com.alipay.sofa</groupId>
  3. <artifactId>tracer-core</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>com.alipay.sofa</groupId>
  7. <artifactId>tracer-extensions</artifactId>
  8. </dependency>
  9. <dependency>
  10. <groupId>com.alipay.sofa.lookout</groupId>
  11. <artifactId>lookout-api</artifactId>
  12. </dependency>