向微服务发送异步消息
Send Async message to microservice
我有一个 BE 服务 A,它使用 Feign 客户端向微服务 B 发送 Rest JSON 消息:
@FeignClient(name = "mail-service")
@LoadBalancerClient(name = "mail-service", configuration = LoadBalancerConfiguration.class)
public interface EmailClient {
@RequestMapping(method = RequestMethod.POST, value = "/engine/emails/register")
void setUserRegistration(CreateUserDTO createUserDTO);
}
端点:
@RestController
@RequestMapping("/emails")
public class EmailController {
@RequestMapping(method = RequestMethod.POST, value = "/register", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> register(@Valid @RequestBody CreateUserDTO createUserDTO) {
emailRestService.processCreateUserMessage(createUserDTO);
// Implementation of service to send mail to AWS SES
return new ResponseEntity<>(HttpStatus.OK);
}
}
Rest Endpoint 正在向 AWS Ses 邮件或其他邮件提供商发送邮件。
问题是 Feign 的拳头调用可能需要 5 秒或更长时间。我需要让它异步,以便 FE 客户端不等待邮件发送。
我如何才能使从 Feign Async 发出的 Rest 调用没有预期的 HTTP 响应 OK 等待时间?有没有更好的解决方案来实现这个?
AFAIK,Feign 不允许非阻塞 IO,它是 work in progress。
但是您可以实现 EmailRestService
异步。考虑以下代码(我不知道 processCreateUserMessage
是否也负责发送电子邮件,但建议的解决方案应在必要时在功能上扩展到该代码):
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
//...
@Service
public class EmailRestServiceImpl implements EmailRestService {
//...
@Async
public void processCreateUserMessage(CreateUserDTO createUserDTO) {
// Implementation of service to send mail to AWS SES
// ...
}
}
请注意 @Async
注释定义。
要启用 Spring 异步处理,您需要在主配置或特定配置中定义 @EnableAsync
注释:
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
@Configuration
@EnableAsync
public class AsyncConfiguration {
}
无需更改 Controller
,但如果您愿意,可以 return 更方便的 HTTP 状态代码:
@RestController
@RequestMapping("/emails")
public class EmailController {
@RequestMapping(method = RequestMethod.POST, value = "/register", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> register(@Valid @RequestBody CreateUserDTO createUserDTO) {
// Will be executed asynchronously and return immediately
emailRestService.processCreateUserMessage(createUserDTO);
return new ResponseEntity<>(HttpStatus.ACCEPTED);
}
}
我有一个 BE 服务 A,它使用 Feign 客户端向微服务 B 发送 Rest JSON 消息:
@FeignClient(name = "mail-service")
@LoadBalancerClient(name = "mail-service", configuration = LoadBalancerConfiguration.class)
public interface EmailClient {
@RequestMapping(method = RequestMethod.POST, value = "/engine/emails/register")
void setUserRegistration(CreateUserDTO createUserDTO);
}
端点:
@RestController
@RequestMapping("/emails")
public class EmailController {
@RequestMapping(method = RequestMethod.POST, value = "/register", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> register(@Valid @RequestBody CreateUserDTO createUserDTO) {
emailRestService.processCreateUserMessage(createUserDTO);
// Implementation of service to send mail to AWS SES
return new ResponseEntity<>(HttpStatus.OK);
}
}
Rest Endpoint 正在向 AWS Ses 邮件或其他邮件提供商发送邮件。
问题是 Feign 的拳头调用可能需要 5 秒或更长时间。我需要让它异步,以便 FE 客户端不等待邮件发送。
我如何才能使从 Feign Async 发出的 Rest 调用没有预期的 HTTP 响应 OK 等待时间?有没有更好的解决方案来实现这个?
AFAIK,Feign 不允许非阻塞 IO,它是 work in progress。
但是您可以实现 EmailRestService
异步。考虑以下代码(我不知道 processCreateUserMessage
是否也负责发送电子邮件,但建议的解决方案应在必要时在功能上扩展到该代码):
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
//...
@Service
public class EmailRestServiceImpl implements EmailRestService {
//...
@Async
public void processCreateUserMessage(CreateUserDTO createUserDTO) {
// Implementation of service to send mail to AWS SES
// ...
}
}
请注意 @Async
注释定义。
要启用 Spring 异步处理,您需要在主配置或特定配置中定义 @EnableAsync
注释:
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
@Configuration
@EnableAsync
public class AsyncConfiguration {
}
无需更改 Controller
,但如果您愿意,可以 return 更方便的 HTTP 状态代码:
@RestController
@RequestMapping("/emails")
public class EmailController {
@RequestMapping(method = RequestMethod.POST, value = "/register", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> register(@Valid @RequestBody CreateUserDTO createUserDTO) {
// Will be executed asynchronously and return immediately
emailRestService.processCreateUserMessage(createUserDTO);
return new ResponseEntity<>(HttpStatus.ACCEPTED);
}
}