Spring 引导复位控制器陈旧参数
Spring Boot Rest Controller Stale Parameters
我已经使用 Spring Boot 2.2 实现了一个休息控制器。6.RELEASE
一天开始时,网络上的许多应用程序都会向我的控制器的单个 运行 实例发出请求。
我相信我看到来自多个应用程序的参数被合并到对控制器的一次调用中
例如,我的控制器中的业务逻辑在收到以下 URL 时抛出异常,我在调用控制器后立即记录该异常:
2021-02-19 06:31:05.551 [http-nio-9000-exec-6] [ERROR] [RefDataServerController]: http://tbaquaappc-u2:9000/refdata/exec/text/getParticipantBitCross?instance=LINEDATA&cert=0dk7lc0vyeVEPptGwVyUXc%3DNbc0FW3IujbPTF7e&cert=Hzj%2Fqu9tIw865CMmsEP076N9mgLI3J6oFwovyt1
在此 URL 中,有 2 个“&cert”参数没有应用程序发送。
两个不同的应用程序发送以下独立请求(大约同时)
http://tbaquaappc-u2:9000/refdata/exec/text/getParticipantBitCross?instance=LINEDATA&cert=Hzj%2Fqu9tIw865CMmsEP076N9mgLI3J6oFwovyt1
http://tbaquaappc-u2:9000/refdata/exec/text/getParticipantBitCross?instance=JOHN2&cert=0dk7lc0vyeVEPptGwVyUXc%3DNbc0FW3IujbPTF7e
第二次调用的 &cert 似乎与第一次调用混在一起了。
感谢“Roddy of the Frozen Peas”,问题似乎确实出在 Spring 启动应用程序和调用者之间的网络代理上。代理在原始服务器套接字(不幸的遗留)上侦听来自调用者的自定义协议请求,并将它们引导到对应用程序的 JAX-RS
请求中。代理侦听器是标准 Java ServerSocket 代码,它 block/waits 用于请求,然后在将请求转发到应用程序的新线程上调用输入处理器。在输入处理器内部,我有一个 org.apache.cxf.jaxrs.client.WebClient
的 class 成员实例,它在 run()
方法内部的每次调用之前简单地执行了一个 reset()
。我删除了共享实例并通过让每个线程在 run()
方法中创建一个新的 WebClient
实例来替换它,然后再使用它来将 http 请求转发到应用程序。这似乎解决了这个问题。可能 WebClient
不是线程安全的。
我已经使用 Spring Boot 2.2 实现了一个休息控制器。6.RELEASE
一天开始时,网络上的许多应用程序都会向我的控制器的单个 运行 实例发出请求。
我相信我看到来自多个应用程序的参数被合并到对控制器的一次调用中
例如,我的控制器中的业务逻辑在收到以下 URL 时抛出异常,我在调用控制器后立即记录该异常:
2021-02-19 06:31:05.551 [http-nio-9000-exec-6] [ERROR] [RefDataServerController]: http://tbaquaappc-u2:9000/refdata/exec/text/getParticipantBitCross?instance=LINEDATA&cert=0dk7lc0vyeVEPptGwVyUXc%3DNbc0FW3IujbPTF7e&cert=Hzj%2Fqu9tIw865CMmsEP076N9mgLI3J6oFwovyt1
在此 URL 中,有 2 个“&cert”参数没有应用程序发送。
两个不同的应用程序发送以下独立请求(大约同时)
http://tbaquaappc-u2:9000/refdata/exec/text/getParticipantBitCross?instance=LINEDATA&cert=Hzj%2Fqu9tIw865CMmsEP076N9mgLI3J6oFwovyt1
http://tbaquaappc-u2:9000/refdata/exec/text/getParticipantBitCross?instance=JOHN2&cert=0dk7lc0vyeVEPptGwVyUXc%3DNbc0FW3IujbPTF7e
第二次调用的 &cert 似乎与第一次调用混在一起了。
感谢“Roddy of the Frozen Peas”,问题似乎确实出在 Spring 启动应用程序和调用者之间的网络代理上。代理在原始服务器套接字(不幸的遗留)上侦听来自调用者的自定义协议请求,并将它们引导到对应用程序的 JAX-RS
请求中。代理侦听器是标准 Java ServerSocket 代码,它 block/waits 用于请求,然后在将请求转发到应用程序的新线程上调用输入处理器。在输入处理器内部,我有一个 org.apache.cxf.jaxrs.client.WebClient
的 class 成员实例,它在 run()
方法内部的每次调用之前简单地执行了一个 reset()
。我删除了共享实例并通过让每个线程在 run()
方法中创建一个新的 WebClient
实例来替换它,然后再使用它来将 http 请求转发到应用程序。这似乎解决了这个问题。可能 WebClient
不是线程安全的。