我的 FeignClient 为服务器响应保持连接打开但服务器在返回任何内容之前等待我的客户端关闭连接
My FeignClient keeps the connection open for the server response BUT the server waits my client to close connection before returning anything
我正在开发一个 java 微服务,它具有来自和到 jBPM 服务器的内部调用。在我的微服务中,我实现了一个@FeignClient (org.springframework.cloud.openfeign.FeignClient) 来调用 jBPM 服务器,特别是第一次调用必须启动 jBPM 进程。
我的“startProcess”API:
@FeignClient(name = "${resource.jbpmService.name}",
url = "${resource.jbpmService.url}",
path = "${resource.jbpmService.path}",
configuration = com.my.MsClientErrorDecoder.class)
public interface JbpmServiceResource {
@PostMapping(path = "/server/containers/{containerID}/processes/{processID}/instances",
consumes = "application/json",
produces = "application/json")
public Long startProcess(
@RequestHeader("Authorization") String authHeader,
@PathVariable(name = "containerID") String containerID,
@PathVariable(name = "processID") String processID,
@RequestBody(required = true) StartProcessBody idRequest);
}
当“startProcess”调用开始时,我的客户端成功联系了 jBPM 服务器。
此时,jBPM 在完成上述请求之前,必须调用我的微服务的 API 来检索它需要的基本信息。
然而,@FeignClient 似乎在“startProcess”完成之前不接受任何传入请求,同时 jBPM 服务器等待。
在等待我的“startProcess”的读取超时后,我的@FeignClient 超时并抛出异常:
feign.RetryableException: Read timed out executing POST http://xx.yy.zz.ww:8080/kie-server/services/rest/server/containers/jBPMContainerName/processes/jBPMProcessName/instances
at feign.FeignException.errorExecuting(FeignException.java:84) ~[feign-core-10.1.0.jar!/:?]
at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:113) ~[feign-core-10.1.0.jar!/:?]
at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:78) ~[feign-core-10.1.0.jar!/:?]
at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103) ~[feign-core-10.1.0.jar!/:?]
at com.sun.proxy.$Proxy215.startProcess(Unknown Source) ~[?:?]
[JbpmServiceResource#startProcess] <--- ERROR SocketTimeoutException: Read timed out (10005ms)
“startProcess”因此 returns HTTP 500 错误并关闭调用。
只有在这一点 jBPM 服务器注意到连接是免费的,并调用我的微服务 API “getRequestInfo” 来检索基本信息信息。
最后,jBPM 服务器 returns processInstanceID 预期作为“startProcess”的输出。
我的“getRequestInfo”API:
@Service
@RestController
@Validated
@RequestMapping(BASEURL)
public class UawJbpmService {
@GetMapping("/get-request-info/{idRequest}")
public UawRequestInfoJBPM getRequestInfo(@PathVariable @NotNull int idRequest) {
return uawJbpmComponent.getRequestInfo(idRequest);
}
}
此调用在几毫秒内正常运行 (HTTP 200)。
对于每个单独的调用,我的微服务和 jBPM 之间没有可达性问题。
问题是我的微服务似乎不接受多个连接(特别是 to/from jBPM)。
另一件事是对 jBPM 的初始调用使用内部 jBPM 逻辑,我们无法修改它。
我怎样才能完成这项工作?
我已经尝试过的东西
- 我尝试将输出类型从“startProcess”更改为 String,然后更改为 void 但这些都不起作用。
- 我试过增加 feign connect-timeout 和 read-timeout 但效果不佳。
- 我尝试创建第二个微服务作为我的初始微服务和 jBPM 之间的中间件。这个想法是调用中间件,然后它会调用 jBPM 来启动它的流程。在这种情况下,我的初始微服务保持与中间件的连接打开,jBPM 等待连接关闭。只有在超时之后,jBPM 才调用“getRequestInfo”,但是我的微服务已经返回了 HTTP 500。情况仍然和以前一样。
我们与我的团队一起解决了这个问题。
我们的微服务部署在 Kubernetes 上,我们有 1 个 POD。
结果是 POD 过载,无法处理更多请求。
解决方案是在 kubernetes 上创建我们的 POD 的副本。
我正在开发一个 java 微服务,它具有来自和到 jBPM 服务器的内部调用。在我的微服务中,我实现了一个@FeignClient (org.springframework.cloud.openfeign.FeignClient) 来调用 jBPM 服务器,特别是第一次调用必须启动 jBPM 进程。
我的“startProcess”API:
@FeignClient(name = "${resource.jbpmService.name}",
url = "${resource.jbpmService.url}",
path = "${resource.jbpmService.path}",
configuration = com.my.MsClientErrorDecoder.class)
public interface JbpmServiceResource {
@PostMapping(path = "/server/containers/{containerID}/processes/{processID}/instances",
consumes = "application/json",
produces = "application/json")
public Long startProcess(
@RequestHeader("Authorization") String authHeader,
@PathVariable(name = "containerID") String containerID,
@PathVariable(name = "processID") String processID,
@RequestBody(required = true) StartProcessBody idRequest);
}
当“startProcess”调用开始时,我的客户端成功联系了 jBPM 服务器。 此时,jBPM 在完成上述请求之前,必须调用我的微服务的 API 来检索它需要的基本信息。 然而,@FeignClient 似乎在“startProcess”完成之前不接受任何传入请求,同时 jBPM 服务器等待。 在等待我的“startProcess”的读取超时后,我的@FeignClient 超时并抛出异常:
feign.RetryableException: Read timed out executing POST http://xx.yy.zz.ww:8080/kie-server/services/rest/server/containers/jBPMContainerName/processes/jBPMProcessName/instances at feign.FeignException.errorExecuting(FeignException.java:84) ~[feign-core-10.1.0.jar!/:?] at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:113) ~[feign-core-10.1.0.jar!/:?] at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:78) ~[feign-core-10.1.0.jar!/:?] at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103) ~[feign-core-10.1.0.jar!/:?] at com.sun.proxy.$Proxy215.startProcess(Unknown Source) ~[?:?]
[JbpmServiceResource#startProcess] <--- ERROR SocketTimeoutException: Read timed out (10005ms)
“startProcess”因此 returns HTTP 500 错误并关闭调用。 只有在这一点 jBPM 服务器注意到连接是免费的,并调用我的微服务 API “getRequestInfo” 来检索基本信息信息。 最后,jBPM 服务器 returns processInstanceID 预期作为“startProcess”的输出。
我的“getRequestInfo”API:
@Service
@RestController
@Validated
@RequestMapping(BASEURL)
public class UawJbpmService {
@GetMapping("/get-request-info/{idRequest}")
public UawRequestInfoJBPM getRequestInfo(@PathVariable @NotNull int idRequest) {
return uawJbpmComponent.getRequestInfo(idRequest);
}
}
此调用在几毫秒内正常运行 (HTTP 200)。 对于每个单独的调用,我的微服务和 jBPM 之间没有可达性问题。 问题是我的微服务似乎不接受多个连接(特别是 to/from jBPM)。 另一件事是对 jBPM 的初始调用使用内部 jBPM 逻辑,我们无法修改它。
我怎样才能完成这项工作?
我已经尝试过的东西
- 我尝试将输出类型从“startProcess”更改为 String,然后更改为 void 但这些都不起作用。
- 我试过增加 feign connect-timeout 和 read-timeout 但效果不佳。
- 我尝试创建第二个微服务作为我的初始微服务和 jBPM 之间的中间件。这个想法是调用中间件,然后它会调用 jBPM 来启动它的流程。在这种情况下,我的初始微服务保持与中间件的连接打开,jBPM 等待连接关闭。只有在超时之后,jBPM 才调用“getRequestInfo”,但是我的微服务已经返回了 HTTP 500。情况仍然和以前一样。
我们与我的团队一起解决了这个问题。
我们的微服务部署在 Kubernetes 上,我们有 1 个 POD。 结果是 POD 过载,无法处理更多请求。
解决方案是在 kubernetes 上创建我们的 POD 的副本。