一、前言
在以前的博客中,小編使用過spring cloud stream 結合rabbitmq,rabbitmq是自己搭建的,沒有用阿里雲的。這次結合前面的博客,小編要使用阿里雲的kafka,所以就想通過spring cloud stream kafka,來完成調用。但是這樣就有一些配置不太一樣了。通過對比阿里雲的kafka的github網站,找到了相關的demo。這裏小編總結一些。
二、spring cloud stream kafka
本文借鑑與https://github.com/AliwareMQ/aliware-kafka-demos/tree/master/kafka-spring-stream-demo。
注意:本Demo僅適用於Spring Cloud Camden.SR5版本,其它版本的配置略有差異,請參考官方文檔進行調整
Demo跑起來
1.將項目導入IDE(如MyEclipse, IntelliJ)中
2.添加自己的AccessKey,SecretKey到src/main/resources/kafka_client_jaas.conf中
3.請參考文檔創建資源 創建Topic和ConsumerGroup
4.將Topic與ConsumerGroup添加到src/main/resources/application.properties
5.spring.cloud.stream.kafka.binder.brokers請參考獲取接入點
6.修改src/main/resources/application.properties中的kafka.ssl.truststore.location爲自己的路徑
7.執行KafkaDemoApplication.main,以啓動消息消費的監聽器,將直接打印消息內容
8.執行MessageOutputTest.testSend測試發送,看Console中是否打印"Hello Aliyun Kafka"
2.1 maven依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-kafka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
<version>1.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-kafka</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.aliyun.openservices</groupId>
<artifactId>ons-sasl-client</artifactId>
<version>0.1</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-kafka</artifactId>
<version>1.1.1.RELEASE</version>
</dependency>
2.2 配置文件
###下面三項請改成自己的值
kafka.consumer.group=XXXXXXXXXXXXXX
kafka.topic.name=XXXXXXXXXXXXXX
kafka.ssl.truststore.location=G:/kafka/kafka.client.truststore.jks
spring.cloud.stream.kafka.binder.autoCreateTopics=false
spring.cloud.stream.bindings.kafka_input.destination=${kafka.topic.name}
spring.cloud.stream.bindings.kafka_input.contentType=application/json
spring.cloud.stream.bindings.kafka_input.group=${kafka.consumer.group}
spring.cloud.stream.bindings.kafka_input.consumer.concurrency=5
spring.cloud.stream.bindings.kafka_output.destination=${kafka.topic.name}
spring.cloud.stream.bindings.kafka_output.contentType=application/json
spring.cloud.stream.bindings.kafka_output.group=${kafka.consumer.group}
spring.cloud.stream.bindings.kafka_output.producer.sync=true
spring.cloud.stream.kafka.binder.brokers=SASL_SSL:/XXXXXXXXXXX.aliyun.com:8080
spring.cloud.stream.kafka.binder.configuration.security.protocol=SASL_SSL
spring.cloud.stream.kafka.binder.configuration.sasl.mechanism=ONS
spring.cloud.stream.kafka.binder.configuration.ssl.truststore.location=${kafka.ssl.truststore.location}
spring.cloud.stream.kafka.binder.configuration.ssl.truststore.password=KafkaOnsClient
這裏需要說明的是:阿里雲配置kafka需要兩個文件:kafka.client.truststore.jks 和 kafka.client.truststore.jks,其中kafka.client.truststore.jks是放到了classpath下了,kafka.client.truststore.jks小編是通過jvm參數來配置放的位置。
2.3 通道
public interface KafkaMessageSource {
String KAFKA_INPUT = "kafka_input";
String KAFKA_OUTPUT = "kafka_output";
@Input(KafkaMessageSource.KAFKA_INPUT)
SubscribableChannel inputNoticeMessage();
@Output(KafkaMessageSource.KAFKA_OUTPUT)
SubscribableChannel outputNoticeMessage();
}
2.4 發送與接收
發送:
@Autowired
private KafkaMessageSource kafkaMessageSource;
flag = kafkaMessageSource.outputNoticeMessage().send(MessageBuilder.withPayload(appNotificationAddBO).build());
if (flag) {
DushuLogger.info("批量添加通知到kafka完成");
resultBO.setStatus(CommonResponseCodeEnum.SUCCESS.getCode());
resultBO.setData(true);
} else {
DushuLogger.info("批量添加通知到kafka失敗");
resultBO.setStatus(CommonResponseCodeEnum.ERROR.getCode());
resultBO.setData(false);
}
接收:
@EnableBinding(KafkaMessageSource.class)
public class NoticeListener {
/**
* 通知接口監聽-王雷-2018年11月9日10:28:40
* @param message 讀取kafka的內容信息
*/
@StreamListener(KafkaMessageSource.KAFKA_INPUT)
public void receiveMethod(Message message) {
DushuLogger.info("監聽kafka消息");
....
}
}
三、生產環境部署問題
1.SASL配置系統變量
Aliyun Kafka採用SASL機制對通道進行鑑權,在此之前,需要配置JVM屬性java.security.auth.login.config 首先將src/main/resources/kafka_client_jaas.conf(注意配置自己的AccessKey,SecretKey)放置在某個路徑下,如/home/admin; 然後可以採用以下方式配置(二選一,建議採用第二種)
1.1 jvm配置方式
jvm啓動時加上 -Djava.security.auth.login.config=/home/admin/kafka_client_jaas.conf
1.2 設置Spring的啓動監聽器
編寫自己類實現ApplicationListener,可以參考Demo工程中的KafkaConfigListener,只是記得要把路徑改成自己的; 然後在src/main/resources/META-INF/spring.factories中配置類的全稱,參考demo: org.springframework.context.ApplicationListener=com.alibaba.cloud.KafkaConfigListener
2.SSL配置Kafka屬性
將src/main/resources/kafka.client.truststore.jks放在某個目錄下,然後參考 application.properties進行配置
報錯“Failed to send SSL close message”
該錯誤後面通常還會跟“connection reset by peer”或“broken pipe”。該錯誤可以忽略,不影響使用。服務端是VIP網絡環境,會主動掐掉空閒連接。 你可以通過修改日誌級別來避免該錯誤,以log4j爲例,加上下面這行配置:
log4j.logger.org.apache.kafka.common.network.SslTransportLayer=ERROR
如果是logback,添加下面配置:
<!--關閉kafka主動掐掉空閒連接日誌-->
<logger name="org.apache.kafka.common.network" level="OFF">
</logger>
四、小結
通過這次配置阿里雲kafka,更加熟悉了kafka,從kafka的配置也很好的用到了。可以在以後的學習中,更進一步。