Merge pull request #420 from fangjian0423/binder-dev
RocketMQ Binder integrates RocketMQ Springpull/421/head
commit
49baeff6e9
@ -0,0 +1,36 @@
|
|||||||
|
package org.springframework.cloud.alibaba.cloud.examples;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.cloud.alibaba.cloud.examples.RocketMQConsumerApplication.MySink;
|
||||||
|
import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||||
|
import org.springframework.cloud.stream.annotation.Input;
|
||||||
|
import org.springframework.messaging.SubscribableChannel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
|
||||||
|
*/
|
||||||
|
@SpringBootApplication
|
||||||
|
@EnableBinding({ MySink.class })
|
||||||
|
public class RocketMQConsumerApplication {
|
||||||
|
|
||||||
|
public interface MySink {
|
||||||
|
|
||||||
|
@Input("input1")
|
||||||
|
SubscribableChannel input1();
|
||||||
|
|
||||||
|
@Input("input2")
|
||||||
|
SubscribableChannel input2();
|
||||||
|
|
||||||
|
@Input("input3")
|
||||||
|
SubscribableChannel input3();
|
||||||
|
|
||||||
|
@Input("input4")
|
||||||
|
SubscribableChannel input4();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(RocketMQConsumerApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-alibaba-examples</artifactId>
|
||||||
|
<version>0.2.2.BUILD-SNAPSHOT</version>
|
||||||
|
<relativePath>../../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|
||||||
|
<artifactId>rocketmq-produce-example</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<description>Example demonstrating how to use rocketmq produce</description>
|
||||||
|
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-stream-rocketmq</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-deploy-plugin</artifactId>
|
||||||
|
<version>${maven-deploy-plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<skip>true</skip>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,39 @@
|
|||||||
|
package org.springframework.cloud.alibaba.cloud.examples;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
|
||||||
|
*/
|
||||||
|
public class Foo {
|
||||||
|
|
||||||
|
private int id;
|
||||||
|
private String bar;
|
||||||
|
|
||||||
|
public Foo() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Foo(int id, String bar) {
|
||||||
|
this.id = id;
|
||||||
|
this.bar = bar;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBar() {
|
||||||
|
return bar;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBar(String bar) {
|
||||||
|
this.bar = bar;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Foo{" + "id=" + id + ", bar='" + bar + '\'' + '}';
|
||||||
|
}
|
||||||
|
}
|
38
spring-cloud-alibaba-examples/rocketmq-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/RocketMQApplication.java → spring-cloud-alibaba-examples/rocketmq-example/rocketmq-produce-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/RocketMQProduceApplication.java
38
spring-cloud-alibaba-examples/rocketmq-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/RocketMQApplication.java → spring-cloud-alibaba-examples/rocketmq-example/rocketmq-produce-example/src/main/java/org/springframework/cloud/alibaba/cloud/examples/RocketMQProduceApplication.java
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.cloud.alibaba.cloud.examples;
|
||||||
|
|
||||||
|
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
|
||||||
|
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
|
||||||
|
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
|
||||||
|
import org.springframework.messaging.Message;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
|
||||||
|
*/
|
||||||
|
@RocketMQTransactionListener(txProducerGroup = "myTxProducerGroup", corePoolSize = 5, maximumPoolSize = 10)
|
||||||
|
public class TransactionListenerImpl implements RocketMQLocalTransactionListener {
|
||||||
|
@Override
|
||||||
|
public RocketMQLocalTransactionState executeLocalTransaction(Message msg,
|
||||||
|
Object arg) {
|
||||||
|
Object num = msg.getHeaders().get("test");
|
||||||
|
|
||||||
|
if ("1".equals(num)) {
|
||||||
|
System.out.println(
|
||||||
|
"executer: " + new String((byte[]) msg.getPayload()) + " unknown");
|
||||||
|
return RocketMQLocalTransactionState.UNKNOWN;
|
||||||
|
}
|
||||||
|
else if ("2".equals(num)) {
|
||||||
|
System.out.println(
|
||||||
|
"executer: " + new String((byte[]) msg.getPayload()) + " rollback");
|
||||||
|
return RocketMQLocalTransactionState.ROLLBACK;
|
||||||
|
}
|
||||||
|
System.out.println(
|
||||||
|
"executer: " + new String((byte[]) msg.getPayload()) + " commit");
|
||||||
|
return RocketMQLocalTransactionState.COMMIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RocketMQLocalTransactionState checkLocalTransaction(Message msg) {
|
||||||
|
System.out.println("check: " + new String((byte[]) msg.getPayload()));
|
||||||
|
return RocketMQLocalTransactionState.COMMIT;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
logging.level.org.springframework.cloud.stream.binder.rocketmq=DEBUG
|
||||||
|
|
||||||
|
spring.cloud.stream.rocketmq.binder.name-server=127.0.0.1:9876
|
||||||
|
|
||||||
|
spring.cloud.stream.bindings.output1.destination=test-topic
|
||||||
|
spring.cloud.stream.bindings.output1.content-type=application/json
|
||||||
|
spring.cloud.stream.rocketmq.bindings.output1.producer.group=binder-group
|
||||||
|
spring.cloud.stream.rocketmq.bindings.output1.producer.sync=true
|
||||||
|
|
||||||
|
spring.cloud.stream.bindings.output2.destination=TransactionTopic
|
||||||
|
spring.cloud.stream.bindings.output2.content-type=application/json
|
||||||
|
spring.cloud.stream.rocketmq.bindings.output2.producer.transactional=true
|
||||||
|
spring.cloud.stream.rocketmq.bindings.output2.producer.group=myTxProducerGroup
|
||||||
|
|
||||||
|
spring.application.name=rocketmq-produce-example
|
||||||
|
|
||||||
|
server.port=28081
|
||||||
|
|
||||||
|
management.endpoints.web.exposure.include=*
|
||||||
|
management.endpoint.health.show-details=always
|
@ -1,18 +0,0 @@
|
|||||||
package org.springframework.cloud.alibaba.cloud.examples;
|
|
||||||
|
|
||||||
import org.apache.rocketmq.client.producer.LocalTransactionState;
|
|
||||||
import org.apache.rocketmq.client.producer.TransactionCheckListener;
|
|
||||||
import org.apache.rocketmq.common.message.MessageExt;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
|
|
||||||
*/
|
|
||||||
public class MyTransactionCheckListener implements TransactionCheckListener {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LocalTransactionState checkLocalTransactionState(MessageExt msg) {
|
|
||||||
System.out.println("TransactionCheckListener: " + new String(msg.getBody()));
|
|
||||||
return LocalTransactionState.COMMIT_MESSAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
package org.springframework.cloud.alibaba.cloud.examples;
|
|
||||||
|
|
||||||
import org.apache.rocketmq.client.producer.LocalTransactionExecuter;
|
|
||||||
import org.apache.rocketmq.client.producer.LocalTransactionState;
|
|
||||||
import org.apache.rocketmq.common.message.Message;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
|
|
||||||
*/
|
|
||||||
public class MyTransactionExecuter implements LocalTransactionExecuter {
|
|
||||||
@Override
|
|
||||||
public LocalTransactionState executeLocalTransactionBranch(Message msg, Object arg) {
|
|
||||||
if ("1".equals(msg.getUserProperty("test"))) {
|
|
||||||
System.out.println(new String(msg.getBody()) + " rollback");
|
|
||||||
return LocalTransactionState.ROLLBACK_MESSAGE;
|
|
||||||
}
|
|
||||||
System.out.println(new String(msg.getBody()) + " commit");
|
|
||||||
return LocalTransactionState.COMMIT_MESSAGE;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.cloud.stream.binder.rocketmq;
|
||||||
|
|
||||||
|
import org.apache.rocketmq.spring.autoconfigure.RocketMQProperties;
|
||||||
|
import org.springframework.cloud.stream.binder.rocketmq.properties.RocketMQBinderConfigurationProperties;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
|
||||||
|
*/
|
||||||
|
public class RocketMQBinderUtils {
|
||||||
|
|
||||||
|
public static RocketMQBinderConfigurationProperties mergeProperties(
|
||||||
|
RocketMQBinderConfigurationProperties rocketBinderConfigurationProperties,
|
||||||
|
RocketMQProperties rocketMQProperties) {
|
||||||
|
RocketMQBinderConfigurationProperties result = new RocketMQBinderConfigurationProperties();
|
||||||
|
if (StringUtils.isEmpty(rocketMQProperties.getNameServer())) {
|
||||||
|
result.setNameServer(rocketBinderConfigurationProperties.getNameServer());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result.setNameServer(rocketMQProperties.getNameServer());
|
||||||
|
}
|
||||||
|
if (rocketMQProperties.getProducer() == null
|
||||||
|
|| StringUtils.isEmpty(rocketMQProperties.getProducer().getAccessKey())) {
|
||||||
|
result.setAccessKey(rocketBinderConfigurationProperties.getAccessKey());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result.setAccessKey(rocketMQProperties.getProducer().getAccessKey());
|
||||||
|
}
|
||||||
|
if (rocketMQProperties.getProducer() == null
|
||||||
|
|| StringUtils.isEmpty(rocketMQProperties.getProducer().getSecretKey())) {
|
||||||
|
result.setSecretKey(rocketBinderConfigurationProperties.getSecretKey());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result.setSecretKey(rocketMQProperties.getProducer().getSecretKey());
|
||||||
|
}
|
||||||
|
if (rocketMQProperties.getProducer() == null || StringUtils
|
||||||
|
.isEmpty(rocketMQProperties.getProducer().getCustomizedTraceTopic())) {
|
||||||
|
result.setCustomizedTraceTopic(
|
||||||
|
rocketBinderConfigurationProperties.getCustomizedTraceTopic());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result.setCustomizedTraceTopic(
|
||||||
|
rocketMQProperties.getProducer().getCustomizedTraceTopic());
|
||||||
|
}
|
||||||
|
if (rocketMQProperties.getProducer() != null
|
||||||
|
&& rocketMQProperties.getProducer().isEnableMsgTrace()) {
|
||||||
|
result.setEnableMsgTrace(Boolean.TRUE);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result.setEnableMsgTrace(
|
||||||
|
rocketBinderConfigurationProperties.isEnableMsgTrace());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,135 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2018 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.cloud.stream.binder.rocketmq;
|
|
||||||
|
|
||||||
import static org.springframework.cloud.stream.binder.rocketmq.RocketMQBinderConstants.ACKNOWLEDGEMENT_KEY;
|
|
||||||
import static org.springframework.cloud.stream.binder.rocketmq.RocketMQBinderConstants.ORIGINAL_ROCKET_MESSAGE;
|
|
||||||
import static org.springframework.cloud.stream.binder.rocketmq.RocketMQBinderConstants.ROCKET_FLAG;
|
|
||||||
import static org.springframework.cloud.stream.binder.rocketmq.RocketMQBinderConstants.ROCKET_SEND_RESULT;
|
|
||||||
import static org.springframework.cloud.stream.binder.rocketmq.RocketMQBinderConstants.ROCKET_TRANSACTIONAL_ARG;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.apache.rocketmq.client.producer.SendResult;
|
|
||||||
import org.apache.rocketmq.common.message.MessageConst;
|
|
||||||
import org.apache.rocketmq.common.message.MessageExt;
|
|
||||||
import org.springframework.cloud.stream.binder.rocketmq.consuming.Acknowledgement;
|
|
||||||
import org.springframework.integration.support.MutableMessage;
|
|
||||||
import org.springframework.messaging.Message;
|
|
||||||
import org.springframework.messaging.MessageHeaders;
|
|
||||||
import org.springframework.messaging.support.MessageHeaderAccessor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Timur Valiev
|
|
||||||
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
|
|
||||||
*/
|
|
||||||
public class RocketMQMessageHeaderAccessor extends MessageHeaderAccessor {
|
|
||||||
|
|
||||||
public RocketMQMessageHeaderAccessor() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
public RocketMQMessageHeaderAccessor(Message<?> message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Acknowledgement getAcknowledgement(Message message) {
|
|
||||||
return message.getHeaders().get(ACKNOWLEDGEMENT_KEY, Acknowledgement.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public RocketMQMessageHeaderAccessor withAcknowledgment(
|
|
||||||
Acknowledgement acknowledgment) {
|
|
||||||
setHeader(ACKNOWLEDGEMENT_KEY, acknowledgment);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTags() {
|
|
||||||
return (String) getMessageHeaders().getOrDefault(MessageConst.PROPERTY_TAGS, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
public RocketMQMessageHeaderAccessor withTags(String tag) {
|
|
||||||
setHeader(MessageConst.PROPERTY_TAGS, tag);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getKeys() {
|
|
||||||
return (String) getMessageHeaders().getOrDefault(MessageConst.PROPERTY_KEYS, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
public RocketMQMessageHeaderAccessor withKeys(String keys) {
|
|
||||||
setHeader(MessageConst.PROPERTY_KEYS, keys);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MessageExt getRocketMessage() {
|
|
||||||
return getMessageHeaders().get(ORIGINAL_ROCKET_MESSAGE, MessageExt.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public RocketMQMessageHeaderAccessor withRocketMessage(MessageExt message) {
|
|
||||||
setHeader(ORIGINAL_ROCKET_MESSAGE, message);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getDelayTimeLevel() {
|
|
||||||
return (Integer) getMessageHeaders()
|
|
||||||
.getOrDefault(MessageConst.PROPERTY_DELAY_TIME_LEVEL, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public RocketMQMessageHeaderAccessor withDelayTimeLevel(Integer delayTimeLevel) {
|
|
||||||
setHeader(MessageConst.PROPERTY_DELAY_TIME_LEVEL, delayTimeLevel);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getFlag() {
|
|
||||||
return (Integer) getMessageHeaders().getOrDefault(ROCKET_FLAG, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public RocketMQMessageHeaderAccessor withFlag(Integer delayTimeLevel) {
|
|
||||||
setHeader(ROCKET_FLAG, delayTimeLevel);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object getTransactionalArg() {
|
|
||||||
return getMessageHeaders().get(ROCKET_TRANSACTIONAL_ARG);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object withTransactionalArg(Object arg) {
|
|
||||||
setHeader(ROCKET_TRANSACTIONAL_ARG, arg);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SendResult getSendResult() {
|
|
||||||
return getMessageHeaders().get(ROCKET_SEND_RESULT, SendResult.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void putSendResult(MutableMessage message, SendResult sendResult) {
|
|
||||||
message.getHeaders().put(ROCKET_SEND_RESULT, sendResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, String> getUserProperties() {
|
|
||||||
Map<String, String> result = new HashMap<>();
|
|
||||||
for (Map.Entry<String, Object> entry : this.toMap().entrySet()) {
|
|
||||||
if (entry.getValue() instanceof String
|
|
||||||
&& !MessageConst.STRING_HASH_SET.contains(entry.getKey())
|
|
||||||
&& !entry.getKey().equals(MessageHeaders.CONTENT_TYPE)) {
|
|
||||||
result.put(entry.getKey(), (String) entry.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2018 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.cloud.stream.binder.rocketmq.actuator;
|
|
||||||
|
|
||||||
import static org.springframework.cloud.stream.binder.rocketmq.RocketMQBinderConstants.ENDPOINT_ID;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
|
||||||
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
|
|
||||||
import org.springframework.cloud.stream.binder.rocketmq.metrics.InstrumentationManager;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Timur Valiev
|
|
||||||
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
|
|
||||||
*/
|
|
||||||
@Endpoint(id = ENDPOINT_ID)
|
|
||||||
public class RocketMQBinderEndpoint {
|
|
||||||
|
|
||||||
@Autowired(required = false)
|
|
||||||
private InstrumentationManager instrumentationManager;
|
|
||||||
|
|
||||||
@ReadOperation
|
|
||||||
public Map<String, Object> invoke() {
|
|
||||||
Map<String, Object> result = new HashMap<>();
|
|
||||||
if (instrumentationManager != null) {
|
|
||||||
result.put("metrics",
|
|
||||||
instrumentationManager.getMetricRegistry().getMetrics());
|
|
||||||
result.put("runtime", instrumentationManager.getRuntime());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result.put("warning",
|
|
||||||
"please add metrics-core dependency, we use it for metrics");
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
18
spring-cloud-stream-binder-rocketmq/src/main/java/org/springframework/cloud/stream/binder/rocketmq/config/RocketMQBinderEndpointAutoConfiguration.java → spring-cloud-stream-binder-rocketmq/src/main/java/org/springframework/cloud/stream/binder/rocketmq/config/RocketMQBinderHealthIndicatorAutoConfiguration.java
18
spring-cloud-stream-binder-rocketmq/src/main/java/org/springframework/cloud/stream/binder/rocketmq/config/RocketMQBinderEndpointAutoConfiguration.java → spring-cloud-stream-binder-rocketmq/src/main/java/org/springframework/cloud/stream/binder/rocketmq/config/RocketMQBinderHealthIndicatorAutoConfiguration.java
@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.cloud.stream.binder.rocketmq.config;
|
||||||
|
|
||||||
|
import org.apache.rocketmq.acl.common.AclClientRPCHook;
|
||||||
|
import org.apache.rocketmq.acl.common.SessionCredentials;
|
||||||
|
import org.apache.rocketmq.client.producer.DefaultMQProducer;
|
||||||
|
import org.apache.rocketmq.spring.autoconfigure.RocketMQAutoConfiguration;
|
||||||
|
import org.apache.rocketmq.spring.config.RocketMQConfigUtils;
|
||||||
|
import org.apache.rocketmq.spring.config.RocketMQTransactionAnnotationProcessor;
|
||||||
|
import org.apache.rocketmq.spring.config.TransactionHandlerRegistry;
|
||||||
|
import org.apache.rocketmq.spring.core.RocketMQTemplate;
|
||||||
|
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
|
import org.springframework.cloud.stream.binder.rocketmq.RocketMQBinderConstants;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@AutoConfigureAfter(RocketMQAutoConfiguration.class)
|
||||||
|
@ConditionalOnMissingBean(DefaultMQProducer.class)
|
||||||
|
public class RocketMQComponent4BinderAutoConfiguration {
|
||||||
|
|
||||||
|
private final Environment environment;
|
||||||
|
|
||||||
|
public RocketMQComponent4BinderAutoConfiguration(Environment environment) {
|
||||||
|
this.environment = environment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean(DefaultMQProducer.class)
|
||||||
|
public DefaultMQProducer defaultMQProducer() {
|
||||||
|
DefaultMQProducer producer;
|
||||||
|
String configNameServer = environment.resolveRequiredPlaceholders(
|
||||||
|
"${spring.cloud.stream.rocketmq.binder.name-server:${rocketmq.producer.name-server:}}");
|
||||||
|
String ak = environment.resolveRequiredPlaceholders(
|
||||||
|
"${spring.cloud.stream.rocketmq.binder.access-key:${rocketmq.producer.access-key:}}");
|
||||||
|
String sk = environment.resolveRequiredPlaceholders(
|
||||||
|
"${spring.cloud.stream.rocketmq.binder.secret-key:${rocketmq.producer.secret-key:}}");
|
||||||
|
if (!StringUtils.isEmpty(ak) && !StringUtils.isEmpty(sk)) {
|
||||||
|
producer = new DefaultMQProducer(RocketMQBinderConstants.DEFAULT_GROUP,
|
||||||
|
new AclClientRPCHook(new SessionCredentials(ak, sk)));
|
||||||
|
producer.setVipChannelEnabled(false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
producer = new DefaultMQProducer(RocketMQBinderConstants.DEFAULT_GROUP);
|
||||||
|
}
|
||||||
|
producer.setNamesrvAddr(configNameServer);
|
||||||
|
return producer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean(destroyMethod = "destroy")
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
public RocketMQTemplate rocketMQTemplate(DefaultMQProducer mqProducer,
|
||||||
|
ObjectMapper objectMapper) {
|
||||||
|
RocketMQTemplate rocketMQTemplate = new RocketMQTemplate();
|
||||||
|
rocketMQTemplate.setProducer(mqProducer);
|
||||||
|
rocketMQTemplate.setObjectMapper(objectMapper);
|
||||||
|
return rocketMQTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnBean(RocketMQTemplate.class)
|
||||||
|
@ConditionalOnMissingBean(TransactionHandlerRegistry.class)
|
||||||
|
public TransactionHandlerRegistry transactionHandlerRegistry(
|
||||||
|
RocketMQTemplate template) {
|
||||||
|
return new TransactionHandlerRegistry(template);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean(name = RocketMQConfigUtils.ROCKETMQ_TRANSACTION_ANNOTATION_PROCESSOR_BEAN_NAME)
|
||||||
|
@ConditionalOnBean(TransactionHandlerRegistry.class)
|
||||||
|
public static RocketMQTransactionAnnotationProcessor transactionAnnotationProcessor(
|
||||||
|
TransactionHandlerRegistry transactionHandlerRegistry) {
|
||||||
|
return new RocketMQTransactionAnnotationProcessor(transactionHandlerRegistry);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,98 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2018 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.cloud.stream.binder.rocketmq.consuming;
|
|
||||||
|
|
||||||
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
|
|
||||||
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
|
|
||||||
import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyContext;
|
|
||||||
import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyStatus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Timur Valiev
|
|
||||||
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
|
|
||||||
*/
|
|
||||||
public class Acknowledgement {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* for {@link ConsumeConcurrentlyContext} using
|
|
||||||
*/
|
|
||||||
private ConsumeConcurrentlyStatus consumeConcurrentlyStatus = ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
|
|
||||||
/**
|
|
||||||
* Message consume retry strategy<br>
|
|
||||||
* -1,no retry,put into DLQ directly<br>
|
|
||||||
* 0,broker control retry frequency<br>
|
|
||||||
* >0,client control retry frequency
|
|
||||||
*/
|
|
||||||
private Integer consumeConcurrentlyDelayLevel = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* for {@link ConsumeOrderlyContext} using
|
|
||||||
*/
|
|
||||||
private ConsumeOrderlyStatus consumeOrderlyStatus = ConsumeOrderlyStatus.SUCCESS;
|
|
||||||
private Long consumeOrderlySuspendCurrentQueueTimeMill = -1L;
|
|
||||||
|
|
||||||
public Acknowledgement setConsumeConcurrentlyStatus(
|
|
||||||
ConsumeConcurrentlyStatus consumeConcurrentlyStatus) {
|
|
||||||
this.consumeConcurrentlyStatus = consumeConcurrentlyStatus;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConsumeConcurrentlyStatus getConsumeConcurrentlyStatus() {
|
|
||||||
return consumeConcurrentlyStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConsumeOrderlyStatus getConsumeOrderlyStatus() {
|
|
||||||
return consumeOrderlyStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Acknowledgement setConsumeOrderlyStatus(
|
|
||||||
ConsumeOrderlyStatus consumeOrderlyStatus) {
|
|
||||||
this.consumeOrderlyStatus = consumeOrderlyStatus;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getConsumeConcurrentlyDelayLevel() {
|
|
||||||
return consumeConcurrentlyDelayLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setConsumeConcurrentlyDelayLevel(Integer consumeConcurrentlyDelayLevel) {
|
|
||||||
this.consumeConcurrentlyDelayLevel = consumeConcurrentlyDelayLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getConsumeOrderlySuspendCurrentQueueTimeMill() {
|
|
||||||
return consumeOrderlySuspendCurrentQueueTimeMill;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setConsumeOrderlySuspendCurrentQueueTimeMill(
|
|
||||||
Long consumeOrderlySuspendCurrentQueueTimeMill) {
|
|
||||||
this.consumeOrderlySuspendCurrentQueueTimeMill = consumeOrderlySuspendCurrentQueueTimeMill;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Acknowledgement buildOrderlyInstance() {
|
|
||||||
Acknowledgement acknowledgement = new Acknowledgement();
|
|
||||||
acknowledgement.setConsumeOrderlyStatus(ConsumeOrderlyStatus.SUCCESS);
|
|
||||||
return acknowledgement;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Acknowledgement buildConcurrentlyInstance() {
|
|
||||||
Acknowledgement acknowledgement = new Acknowledgement();
|
|
||||||
acknowledgement
|
|
||||||
.setConsumeConcurrentlyStatus(ConsumeConcurrentlyStatus.CONSUME_SUCCESS);
|
|
||||||
return acknowledgement;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,137 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2018 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.cloud.stream.binder.rocketmq.consuming;
|
|
||||||
|
|
||||||
import java.util.AbstractMap;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
|
|
||||||
import org.apache.rocketmq.client.exception.MQClientException;
|
|
||||||
import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.cloud.stream.binder.ExtendedConsumerProperties;
|
|
||||||
import org.springframework.cloud.stream.binder.rocketmq.metrics.ConsumerGroupInstrumentation;
|
|
||||||
import org.springframework.cloud.stream.binder.rocketmq.metrics.InstrumentationManager;
|
|
||||||
import org.springframework.cloud.stream.binder.rocketmq.properties.RocketMQBinderConfigurationProperties;
|
|
||||||
import org.springframework.cloud.stream.binder.rocketmq.properties.RocketMQConsumerProperties;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Timur Valiev
|
|
||||||
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
|
|
||||||
*/
|
|
||||||
public class ConsumersManager {
|
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
|
||||||
|
|
||||||
private final Map<String, DefaultMQPushConsumer> consumerGroups = new HashMap<>();
|
|
||||||
private final Map<String, Boolean> started = new HashMap<>();
|
|
||||||
private final Map<Map.Entry<String, String>, ExtendedConsumerProperties<RocketMQConsumerProperties>> propertiesMap = new HashMap<>();
|
|
||||||
private final RocketMQBinderConfigurationProperties rocketBinderConfigurationProperties;
|
|
||||||
|
|
||||||
private InstrumentationManager instrumentationManager;
|
|
||||||
|
|
||||||
public ConsumersManager(InstrumentationManager instrumentationManager,
|
|
||||||
RocketMQBinderConfigurationProperties rocketBinderConfigurationProperties) {
|
|
||||||
this.instrumentationManager = instrumentationManager;
|
|
||||||
this.rocketBinderConfigurationProperties = rocketBinderConfigurationProperties;
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized DefaultMQPushConsumer getOrCreateConsumer(String group,
|
|
||||||
String topic,
|
|
||||||
ExtendedConsumerProperties<RocketMQConsumerProperties> consumerProperties) {
|
|
||||||
propertiesMap.put(new AbstractMap.SimpleEntry<>(group, topic),
|
|
||||||
consumerProperties);
|
|
||||||
|
|
||||||
Optional.ofNullable(instrumentationManager).ifPresent(manager -> {
|
|
||||||
ConsumerGroupInstrumentation instrumentation = manager
|
|
||||||
.getConsumerGroupInstrumentation(group);
|
|
||||||
instrumentationManager.addHealthInstrumentation(instrumentation);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (consumerGroups.containsKey(group)) {
|
|
||||||
return consumerGroups.get(group);
|
|
||||||
}
|
|
||||||
|
|
||||||
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(group);
|
|
||||||
consumer.setNamesrvAddr(rocketBinderConfigurationProperties.getNamesrvAddr());
|
|
||||||
consumerGroups.put(group, consumer);
|
|
||||||
started.put(group, false);
|
|
||||||
consumer.setConsumeThreadMax(consumerProperties.getConcurrency());
|
|
||||||
consumer.setConsumeThreadMin(consumerProperties.getConcurrency());
|
|
||||||
if (consumerProperties.getExtension().getBroadcasting()) {
|
|
||||||
consumer.setMessageModel(MessageModel.BROADCASTING);
|
|
||||||
}
|
|
||||||
logger.info("RocketMQ consuming for SCS group {} created", group);
|
|
||||||
return consumer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void startConsumers() throws MQClientException {
|
|
||||||
for (String group : getConsumerGroups()) {
|
|
||||||
start(group);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void startConsumer(String group) throws MQClientException {
|
|
||||||
start(group);
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void stopConsumer(String group) {
|
|
||||||
stop(group);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void stop(String group) {
|
|
||||||
if (consumerGroups.get(group) != null) {
|
|
||||||
consumerGroups.get(group).shutdown();
|
|
||||||
started.put(group, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private synchronized void start(String group) throws MQClientException {
|
|
||||||
if (started.get(group)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ConsumerGroupInstrumentation groupInstrumentation = null;
|
|
||||||
if (Optional.ofNullable(instrumentationManager).isPresent()) {
|
|
||||||
groupInstrumentation = instrumentationManager
|
|
||||||
.getConsumerGroupInstrumentation(group);
|
|
||||||
instrumentationManager.addHealthInstrumentation(groupInstrumentation);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
consumerGroups.get(group).start();
|
|
||||||
started.put(group, true);
|
|
||||||
Optional.ofNullable(groupInstrumentation)
|
|
||||||
.ifPresent(g -> g.markStartedSuccessfully());
|
|
||||||
}
|
|
||||||
catch (MQClientException e) {
|
|
||||||
Optional.ofNullable(groupInstrumentation)
|
|
||||||
.ifPresent(g -> g.markStartFailed(e));
|
|
||||||
logger.error("RocketMQ Consumer hasn't been started. Caused by "
|
|
||||||
+ e.getErrorMessage(), e);
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized Set<String> getConsumerGroups() {
|
|
||||||
return consumerGroups.keySet();
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,419 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.cloud.stream.binder.rocketmq.consuming;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.apache.rocketmq.acl.common.AclClientRPCHook;
|
||||||
|
import org.apache.rocketmq.acl.common.SessionCredentials;
|
||||||
|
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
|
||||||
|
import org.apache.rocketmq.client.consumer.MessageSelector;
|
||||||
|
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
|
||||||
|
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
|
||||||
|
import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyContext;
|
||||||
|
import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyStatus;
|
||||||
|
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
|
||||||
|
import org.apache.rocketmq.client.consumer.listener.MessageListenerOrderly;
|
||||||
|
import org.apache.rocketmq.client.consumer.rebalance.AllocateMessageQueueAveragely;
|
||||||
|
import org.apache.rocketmq.client.exception.MQClientException;
|
||||||
|
import org.apache.rocketmq.common.message.MessageExt;
|
||||||
|
import org.apache.rocketmq.remoting.RPCHook;
|
||||||
|
import org.apache.rocketmq.spring.annotation.ConsumeMode;
|
||||||
|
import org.apache.rocketmq.spring.annotation.MessageModel;
|
||||||
|
import org.apache.rocketmq.spring.annotation.SelectorType;
|
||||||
|
import org.apache.rocketmq.spring.core.RocketMQListener;
|
||||||
|
import org.apache.rocketmq.spring.core.RocketMQPushConsumerLifecycleListener;
|
||||||
|
import org.apache.rocketmq.spring.support.RocketMQListenerContainer;
|
||||||
|
import org.apache.rocketmq.spring.support.RocketMQUtil;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.cloud.stream.binder.ExtendedConsumerProperties;
|
||||||
|
import org.springframework.cloud.stream.binder.rocketmq.RocketMQMessageChannelBinder;
|
||||||
|
import org.springframework.cloud.stream.binder.rocketmq.properties.RocketMQBinderConfigurationProperties;
|
||||||
|
import org.springframework.cloud.stream.binder.rocketmq.properties.RocketMQConsumerProperties;
|
||||||
|
import org.springframework.context.SmartLifecycle;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
|
||||||
|
*/
|
||||||
|
public class RocketMQListenerBindingContainer
|
||||||
|
implements InitializingBean, RocketMQListenerContainer, SmartLifecycle {
|
||||||
|
|
||||||
|
private final static Logger log = LoggerFactory
|
||||||
|
.getLogger(RocketMQListenerBindingContainer.class);
|
||||||
|
|
||||||
|
private long suspendCurrentQueueTimeMillis = 1000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Message consume retry strategy<br>
|
||||||
|
* -1,no retry,put into DLQ directly<br>
|
||||||
|
* 0,broker control retry frequency<br>
|
||||||
|
* >0,client control retry frequency.
|
||||||
|
*/
|
||||||
|
private int delayLevelWhenNextConsume = 0;
|
||||||
|
|
||||||
|
private String nameServer;
|
||||||
|
|
||||||
|
private String consumerGroup;
|
||||||
|
|
||||||
|
private String topic;
|
||||||
|
|
||||||
|
private int consumeThreadMax = 64;
|
||||||
|
|
||||||
|
private String charset = "UTF-8";
|
||||||
|
|
||||||
|
private RocketMQListener rocketMQListener;
|
||||||
|
|
||||||
|
private DefaultMQPushConsumer consumer;
|
||||||
|
|
||||||
|
private boolean running;
|
||||||
|
|
||||||
|
private final ExtendedConsumerProperties<RocketMQConsumerProperties> rocketMQConsumerProperties;
|
||||||
|
|
||||||
|
private final RocketMQMessageChannelBinder rocketMQMessageChannelBinder;
|
||||||
|
private final RocketMQBinderConfigurationProperties rocketBinderConfigurationProperties;
|
||||||
|
|
||||||
|
// The following properties came from RocketMQConsumerProperties.
|
||||||
|
private ConsumeMode consumeMode;
|
||||||
|
private SelectorType selectorType;
|
||||||
|
private String selectorExpression;
|
||||||
|
private MessageModel messageModel;
|
||||||
|
|
||||||
|
public RocketMQListenerBindingContainer(
|
||||||
|
ExtendedConsumerProperties<RocketMQConsumerProperties> rocketMQConsumerProperties,
|
||||||
|
RocketMQBinderConfigurationProperties rocketBinderConfigurationProperties,
|
||||||
|
RocketMQMessageChannelBinder rocketMQMessageChannelBinder) {
|
||||||
|
this.rocketMQConsumerProperties = rocketMQConsumerProperties;
|
||||||
|
this.rocketBinderConfigurationProperties = rocketBinderConfigurationProperties;
|
||||||
|
this.rocketMQMessageChannelBinder = rocketMQMessageChannelBinder;
|
||||||
|
this.consumeMode = rocketMQConsumerProperties.getExtension().getOrderly()
|
||||||
|
? ConsumeMode.ORDERLY
|
||||||
|
: ConsumeMode.CONCURRENTLY;
|
||||||
|
if (StringUtils.isEmpty(rocketMQConsumerProperties.getExtension().getSql())) {
|
||||||
|
this.selectorType = SelectorType.TAG;
|
||||||
|
this.selectorExpression = rocketMQConsumerProperties.getExtension().getTags();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.selectorType = SelectorType.SQL92;
|
||||||
|
this.selectorExpression = rocketMQConsumerProperties.getExtension().getSql();
|
||||||
|
}
|
||||||
|
this.messageModel = rocketMQConsumerProperties.getExtension().getBroadcasting()
|
||||||
|
? MessageModel.BROADCASTING
|
||||||
|
: MessageModel.CLUSTERING;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setupMessageListener(RocketMQListener<?> rocketMQListener) {
|
||||||
|
this.rocketMQListener = rocketMQListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy() throws Exception {
|
||||||
|
this.setRunning(false);
|
||||||
|
if (Objects.nonNull(consumer)) {
|
||||||
|
consumer.shutdown();
|
||||||
|
}
|
||||||
|
log.info("container destroyed, {}", this.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
initRocketMQPushConsumer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAutoStartup() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stop(Runnable callback) {
|
||||||
|
stop();
|
||||||
|
callback.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start() {
|
||||||
|
if (this.isRunning()) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"container already running. " + this.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
consumer.start();
|
||||||
|
}
|
||||||
|
catch (MQClientException e) {
|
||||||
|
throw new IllegalStateException("Failed to start RocketMQ push consumer", e);
|
||||||
|
}
|
||||||
|
this.setRunning(true);
|
||||||
|
|
||||||
|
log.info("running container: {}", this.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stop() {
|
||||||
|
if (this.isRunning()) {
|
||||||
|
if (Objects.nonNull(consumer)) {
|
||||||
|
consumer.shutdown();
|
||||||
|
}
|
||||||
|
setRunning(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRunning() {
|
||||||
|
return running;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setRunning(boolean running) {
|
||||||
|
this.running = running;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPhase() {
|
||||||
|
return Integer.MAX_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initRocketMQPushConsumer() throws MQClientException {
|
||||||
|
Assert.notNull(rocketMQListener, "Property 'rocketMQListener' is required");
|
||||||
|
Assert.notNull(consumerGroup, "Property 'consumerGroup' is required");
|
||||||
|
Assert.notNull(nameServer, "Property 'nameServer' is required");
|
||||||
|
Assert.notNull(topic, "Property 'topic' is required");
|
||||||
|
|
||||||
|
String ak = rocketBinderConfigurationProperties.getAccessKey();
|
||||||
|
String sk = rocketBinderConfigurationProperties.getSecretKey();
|
||||||
|
if (!StringUtils.isEmpty(ak) && !StringUtils.isEmpty(sk)) {
|
||||||
|
RPCHook rpcHook = new AclClientRPCHook(new SessionCredentials(ak, sk));
|
||||||
|
consumer = new DefaultMQPushConsumer(consumerGroup, rpcHook,
|
||||||
|
new AllocateMessageQueueAveragely(),
|
||||||
|
rocketBinderConfigurationProperties.isEnableMsgTrace(),
|
||||||
|
rocketBinderConfigurationProperties.getCustomizedTraceTopic());
|
||||||
|
consumer.setInstanceName(RocketMQUtil.getInstanceName(rpcHook, topic));
|
||||||
|
consumer.setVipChannelEnabled(false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
consumer = new DefaultMQPushConsumer(consumerGroup,
|
||||||
|
rocketBinderConfigurationProperties.isEnableMsgTrace(),
|
||||||
|
rocketBinderConfigurationProperties.getCustomizedTraceTopic());
|
||||||
|
}
|
||||||
|
|
||||||
|
consumer.setNamesrvAddr(nameServer);
|
||||||
|
consumer.setConsumeThreadMax(rocketMQConsumerProperties.getConcurrency());
|
||||||
|
consumer.setConsumeThreadMin(rocketMQConsumerProperties.getConcurrency());
|
||||||
|
|
||||||
|
switch (messageModel) {
|
||||||
|
case BROADCASTING:
|
||||||
|
consumer.setMessageModel(
|
||||||
|
org.apache.rocketmq.common.protocol.heartbeat.MessageModel.BROADCASTING);
|
||||||
|
break;
|
||||||
|
case CLUSTERING:
|
||||||
|
consumer.setMessageModel(
|
||||||
|
org.apache.rocketmq.common.protocol.heartbeat.MessageModel.CLUSTERING);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Property 'messageModel' was wrong.");
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (selectorType) {
|
||||||
|
case TAG:
|
||||||
|
consumer.subscribe(topic, selectorExpression);
|
||||||
|
break;
|
||||||
|
case SQL92:
|
||||||
|
consumer.subscribe(topic, MessageSelector.bySql(selectorExpression));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Property 'selectorType' was wrong.");
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (consumeMode) {
|
||||||
|
case ORDERLY:
|
||||||
|
consumer.setMessageListener(new DefaultMessageListenerOrderly());
|
||||||
|
break;
|
||||||
|
case CONCURRENTLY:
|
||||||
|
consumer.setMessageListener(new DefaultMessageListenerConcurrently());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Property 'consumeMode' was wrong.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rocketMQListener instanceof RocketMQPushConsumerLifecycleListener) {
|
||||||
|
((RocketMQPushConsumerLifecycleListener) rocketMQListener)
|
||||||
|
.prepareStart(consumer);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "RocketMQListenerBindingContainer{" + "consumerGroup='" + consumerGroup
|
||||||
|
+ '\'' + ", nameServer='" + nameServer + '\'' + ", topic='" + topic + '\''
|
||||||
|
+ ", consumeMode=" + consumeMode + ", selectorType=" + selectorType
|
||||||
|
+ ", selectorExpression='" + selectorExpression + '\'' + ", messageModel="
|
||||||
|
+ messageModel + '}';
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getSuspendCurrentQueueTimeMillis() {
|
||||||
|
return suspendCurrentQueueTimeMillis;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSuspendCurrentQueueTimeMillis(long suspendCurrentQueueTimeMillis) {
|
||||||
|
this.suspendCurrentQueueTimeMillis = suspendCurrentQueueTimeMillis;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDelayLevelWhenNextConsume() {
|
||||||
|
return delayLevelWhenNextConsume;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDelayLevelWhenNextConsume(int delayLevelWhenNextConsume) {
|
||||||
|
this.delayLevelWhenNextConsume = delayLevelWhenNextConsume;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNameServer() {
|
||||||
|
return nameServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNameServer(String nameServer) {
|
||||||
|
this.nameServer = nameServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getConsumerGroup() {
|
||||||
|
return consumerGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConsumerGroup(String consumerGroup) {
|
||||||
|
this.consumerGroup = consumerGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTopic() {
|
||||||
|
return topic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTopic(String topic) {
|
||||||
|
this.topic = topic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getConsumeThreadMax() {
|
||||||
|
return consumeThreadMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConsumeThreadMax(int consumeThreadMax) {
|
||||||
|
this.consumeThreadMax = consumeThreadMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCharset() {
|
||||||
|
return charset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCharset(String charset) {
|
||||||
|
this.charset = charset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RocketMQListener getRocketMQListener() {
|
||||||
|
return rocketMQListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRocketMQListener(RocketMQListener rocketMQListener) {
|
||||||
|
this.rocketMQListener = rocketMQListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DefaultMQPushConsumer getConsumer() {
|
||||||
|
return consumer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConsumer(DefaultMQPushConsumer consumer) {
|
||||||
|
this.consumer = consumer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExtendedConsumerProperties<RocketMQConsumerProperties> getRocketMQConsumerProperties() {
|
||||||
|
return rocketMQConsumerProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConsumeMode getConsumeMode() {
|
||||||
|
return consumeMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SelectorType getSelectorType() {
|
||||||
|
return selectorType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSelectorExpression() {
|
||||||
|
return selectorExpression;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MessageModel getMessageModel() {
|
||||||
|
return messageModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DefaultMessageListenerConcurrently
|
||||||
|
implements MessageListenerConcurrently {
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,
|
||||||
|
ConsumeConcurrentlyContext context) {
|
||||||
|
for (MessageExt messageExt : msgs) {
|
||||||
|
log.debug("received msg: {}", messageExt);
|
||||||
|
try {
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
rocketMQListener
|
||||||
|
.onMessage(RocketMQUtil.convertToSpringMessage(messageExt));
|
||||||
|
long costTime = System.currentTimeMillis() - now;
|
||||||
|
log.debug("consume {} cost: {} ms", messageExt.getMsgId(), costTime);
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
log.warn("consume message failed. messageExt:{}", messageExt, e);
|
||||||
|
context.setDelayLevelWhenNextConsume(delayLevelWhenNextConsume);
|
||||||
|
return ConsumeConcurrentlyStatus.RECONSUME_LATER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DefaultMessageListenerOrderly implements MessageListenerOrderly {
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public ConsumeOrderlyStatus consumeMessage(List<MessageExt> msgs,
|
||||||
|
ConsumeOrderlyContext context) {
|
||||||
|
for (MessageExt messageExt : msgs) {
|
||||||
|
log.debug("received msg: {}", messageExt);
|
||||||
|
try {
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
rocketMQListener
|
||||||
|
.onMessage(RocketMQUtil.convertToSpringMessage(messageExt));
|
||||||
|
long costTime = System.currentTimeMillis() - now;
|
||||||
|
log.info("consume {} cost: {} ms", messageExt.getMsgId(), costTime);
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
log.warn("consume message failed. messageExt:{}", messageExt, e);
|
||||||
|
context.setSuspendCurrentQueueTimeMillis(
|
||||||
|
suspendCurrentQueueTimeMillis);
|
||||||
|
return ConsumeOrderlyStatus.SUSPEND_CURRENT_QUEUE_A_MOMENT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ConsumeOrderlyStatus.SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2018 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.cloud.stream.binder.rocketmq.exception;
|
|
||||||
|
|
||||||
import org.springframework.messaging.Message;
|
|
||||||
import org.springframework.messaging.MessagingException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An exception that is the payload of an {@code ErrorMessage} when occurs send failure.
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
|
|
||||||
* @since 0.2.2
|
|
||||||
*/
|
|
||||||
public class RocketMQSendFailureException extends MessagingException {
|
|
||||||
|
|
||||||
private final org.apache.rocketmq.common.message.Message rocketmqMsg;
|
|
||||||
|
|
||||||
public RocketMQSendFailureException(Message<?> message,
|
|
||||||
org.apache.rocketmq.common.message.Message rocketmqMsg, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
this.rocketmqMsg = rocketmqMsg;
|
|
||||||
}
|
|
||||||
|
|
||||||
public org.apache.rocketmq.common.message.Message getRocketmqMsg() {
|
|
||||||
return rocketmqMsg;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return super.toString() + " [rocketmqMsg=" + this.rocketmqMsg + "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2018 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.cloud.stream.binder.rocketmq.metrics;
|
|
||||||
|
|
||||||
import com.codahale.metrics.MetricRegistry;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Timur Valiev
|
|
||||||
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
|
|
||||||
*/
|
|
||||||
public class ConsumerGroupInstrumentation extends Instrumentation {
|
|
||||||
private MetricRegistry metricRegistry;
|
|
||||||
|
|
||||||
public ConsumerGroupInstrumentation(MetricRegistry metricRegistry, String name) {
|
|
||||||
super(name);
|
|
||||||
this.metricRegistry = metricRegistry;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,60 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2018 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.cloud.stream.binder.rocketmq.metrics;
|
|
||||||
|
|
||||||
import static com.codahale.metrics.MetricRegistry.name;
|
|
||||||
|
|
||||||
import org.springframework.cloud.stream.binder.rocketmq.RocketMQBinderConstants.Metrics.Consumer;
|
|
||||||
|
|
||||||
import com.codahale.metrics.Counter;
|
|
||||||
import com.codahale.metrics.Meter;
|
|
||||||
import com.codahale.metrics.MetricRegistry;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author juven.xuxb
|
|
||||||
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
|
|
||||||
*/
|
|
||||||
public class ConsumerInstrumentation extends Instrumentation {
|
|
||||||
|
|
||||||
private final Counter totalConsumed;
|
|
||||||
private final Counter totalConsumedFailures;
|
|
||||||
private final Meter consumedPerSecond;
|
|
||||||
private final Meter consumedFailuresPerSecond;
|
|
||||||
|
|
||||||
public ConsumerInstrumentation(MetricRegistry registry, String baseMetricName) {
|
|
||||||
super(baseMetricName);
|
|
||||||
|
|
||||||
this.totalConsumed = registry
|
|
||||||
.counter(name(baseMetricName, Consumer.TOTAL_CONSUMED));
|
|
||||||
this.consumedPerSecond = registry
|
|
||||||
.meter(name(baseMetricName, Consumer.CONSUMED_PER_SECOND));
|
|
||||||
this.totalConsumedFailures = registry
|
|
||||||
.counter(name(baseMetricName, Consumer.TOTAL_CONSUMED_FAILURES));
|
|
||||||
this.consumedFailuresPerSecond = registry
|
|
||||||
.meter(name(baseMetricName, Consumer.CONSUMED_FAILURES_PER_SECOND));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void markConsumed() {
|
|
||||||
totalConsumed.inc();
|
|
||||||
consumedPerSecond.mark();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void markConsumedFailure() {
|
|
||||||
totalConsumedFailures.inc();
|
|
||||||
consumedFailuresPerSecond.mark();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2018 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.cloud.stream.binder.rocketmq.metrics;
|
|
||||||
|
|
||||||
import static com.codahale.metrics.MetricRegistry.name;
|
|
||||||
|
|
||||||
import org.springframework.cloud.stream.binder.rocketmq.RocketMQBinderConstants.Metrics.Producer;
|
|
||||||
|
|
||||||
import com.codahale.metrics.Counter;
|
|
||||||
import com.codahale.metrics.Meter;
|
|
||||||
import com.codahale.metrics.MetricRegistry;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author juven.xuxb
|
|
||||||
* @author <a href="mailto:fangjian0423@gmail.com">Jim</a>
|
|
||||||
*/
|
|
||||||
public class ProducerInstrumentation extends Instrumentation {
|
|
||||||
|
|
||||||
private final Counter totalSent;
|
|
||||||
private final Counter totalSentFailures;
|
|
||||||
private final Meter sentPerSecond;
|
|
||||||
private final Meter sentFailuresPerSecond;
|
|
||||||
|
|
||||||
public ProducerInstrumentation(MetricRegistry registry, String baseMetricName) {
|
|
||||||
super(baseMetricName);
|
|
||||||
|
|
||||||
this.totalSent = registry.counter(name(baseMetricName, Producer.TOTAL_SENT));
|
|
||||||
this.totalSentFailures = registry
|
|
||||||
.counter(name(baseMetricName, Producer.TOTAL_SENT_FAILURES));
|
|
||||||
this.sentPerSecond = registry
|
|
||||||
.meter(name(baseMetricName, Producer.SENT_PER_SECOND));
|
|
||||||
this.sentFailuresPerSecond = registry
|
|
||||||
.meter(name(baseMetricName, Producer.SENT_FAILURES_PER_SECOND));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void markSent() {
|
|
||||||
totalSent.inc();
|
|
||||||
sentPerSecond.mark();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void markSentFailure() {
|
|
||||||
totalSentFailures.inc();
|
|
||||||
sentFailuresPerSecond.mark();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,2 +1,2 @@
|
|||||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||||
org.springframework.cloud.stream.binder.rocketmq.config.RocketMQBinderEndpointAutoConfiguration
|
org.springframework.cloud.stream.binder.rocketmq.config.RocketMQComponent4BinderAutoConfiguration
|
||||||
|
Loading…
Reference in New Issue