使用消費組實現消息消費的負載均衡
需要JAVA Spring Cloud大型企業分佈式微服務雲構建的B2B2C電子商務平臺源碼:壹零叄八柒柒肆六二六
通常在生產環境,我們的每個服務都不會以單節點的方式運行在生產環境,當同一個服務啓動多個實例的時候,這些實例都會綁定到同一個消息通道的目標主題(Topic)上。
默認情況下,當生產者發出一條消息到綁定通道上,這條消息會產生多個副本被每個消費者實例接收和處理,但是有些業務場景之下,我們希望生產者產生的消息只被其中一個實例消費,這個時候我們需要爲這些消費者設置消費組來實現這樣的功能,實現的方式非常簡單,我們只需要在服務消費者端設置spring.cloud.stream.bindings.input.group屬性即可,比如我們可以這樣實現:
先創建一個消費者應用SinkReceiver,實現了greetings主題上的輸入通道綁定,它的實現如下:
@EnableBinding(value = {Sink.class})
public class SinkReceiver {
private static Logger logger = LoggerFactory.getLogger(SinkReceiver.class);
@StreamListener(Sink.INPUT)
public void receive(User user) {
logger.info("Received: " + user);
}
}
爲了將SinkReceiver的輸入通道目標設置爲greetings主題,以及將該服務的實例設置爲同一個消費組,做如下設置:
spring.cloud.stream.bindings.input.group=Service-A
spring.cloud.stream.bindings.input.destination=greetings
通過spring.cloud.stream.bindings.input.group屬性指定了該應用實例都屬於Service-A消費組,而spring.cloud.stream.bindings.input.destination屬性則指定了輸入通道對應的主題名。
完成了消息消費者之後,我們再來實現一個消息生產者應用SinkSender,具體如下:
@EnableBinding(value = {Source.class})
public class SinkSender {
private static Logger logger = LoggerFactory.getLogger(SinkSender.class);
@Bean
@InboundChannelAdapter(value = Source.OUTPUT, poller = @Poller(fixedDelay = "2000"))
public MessageSource<String> timerMessageSource() {
return () -> new GenericMessage<>("{\"name\":\"didi\", \"age\":30}");
}
}
爲消息生產者SinkSender做一些設置,讓它的輸出通道綁定目標也指向greetings主題,具體如下:
spring.cloud.stream.bindings.output.destination=greetings
到這裏,對於消費分組的示例就已經完成了。分別運行上面實現的生產者與消費者,其中消費者我們啓動多個實例。通過控制檯,我們可以發現每個生產者發出的消息,會被啓動的消費者以輪詢的方式進行接收和輸出。