我有google cloud pubsub订阅者应用程序(问题与pubsub无关,我相信与jms监听器有相同的行为)。 它不需要像tomcat或其他这样的网络容器(有很多问题,问题是缺少容器依赖,这里我不需要webcontainer)。它应该启动并处理消息。问题:它在启动后停止。
应用程序非常简单,这里是build.gradle
文件:
buildscript {
ext {
springBootVersion = '1.5.8.RELEASE'
}
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
compile 'org.springframework.boot:spring-boot-starter'
}
这是应用程序启动器:
@SpringBootApplication
public class CommunicationApplication {
public static void main(String[] args) throws IOException {
SpringApplication.run(CommunicationApplication.class, args);
//waiting data from system input to prevent stop after start
//System.in.read();
}
}
这是pubsub manager bean(它创建了pubsub监听器)
@Component
public class PubsubManager {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private MessageReceiver messageReceiver;
private Subscriber subscriber;
@PostConstruct
protected void start() throws Exception {
createTopic();
createSubscriber();
}
private void createTopic() throws Exception {
TopicName topic = TopicName.of(ServiceOptions.getDefaultProjectId(), "COMMUNICATION_TOPIC_NAME");
try (TopicAdminClient topicAdminClient = TopicAdminClient.create()) {
topicAdminClient.createTopic(topic);
logger.info("Topic {}:{} created", topic.getProject(), topic.getTopic());
} catch (ApiException e) {
if (e.getStatusCode().getCode() == StatusCode.Code.ALREADY_EXISTS) {
logger.info("Topic {}:{} already exist", topic.getProject(), topic.getTopic());
} else {
logger.error("Error create topic: {}", e.getStatusCode().getCode());
}
logger.info("isRetryable: {}", e.isRetryable());
}
}
private void createSubscriber() throws Exception {
SubscriptionName subscriptionName = SubscriptionName.of(ServiceOptions.getDefaultProjectId(),
MessagingConstants.COMMUNICATION_SUBSCRIPTION_NAME);
// create a subscriber bound to the asynchronous message receiver
try (SubscriptionAdminClient subscriptionAdminClient = SubscriptionAdminClient.create()) {
TopicName topicName = TopicName.of(ServiceOptions.getDefaultProjectId(),
"COMMUNICATION_TOPIC_NAME");
Subscription subscription = subscriptionAdminClient.createSubscription(
subscriptionName, topicName, PushConfig.getDefaultInstance(), 0);
} catch (Exception e) {
logger.info("subscription already created:", e);
}
subscriber = Subscriber.newBuilder(subscriptionName, messageReceiver).build();
subscriber.startAsync().awaitRunning();
logger.info("subscriber start receiving messages");
}
@PreDestroy
protected void close() throws Exception {
logger.info("subscriber stop receiving messages");
subscriber.stopAsync();
}
}
如果我取消注释System.in.read();
- 它适用于本地环境,但在云端它不起作用。你能建议正确的解决方法吗?感谢。
答案 0 :(得分:1)
如果您只想创建PubSub Listener,以下内容对我有用:
git clone https://github.com/spring-guides/gs-messaging-gcp-pubsub
cd gs-messaging-gcp-pubsub/complete
cd gs-messaging-gcp-pubsub/complete/src/main/resources
进入后,您可以删除静态文件夹。的build.gradle:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.5.9.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
jar {
baseName = 'gs-spring-cloud-gcp'
version = '0.1.0'
}
repositories {
mavenCentral()
maven {
url "http://repo.spring.io/snapshot"
}
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
compile("org.springframework.cloud:spring-cloud-gcp-starter-pubsub:1.0.0.BUILD-SNAPSHOT")
compile("org.springframework.cloud:spring-integration-gcp:1.0.0.BUILD-SNAPSHOT")
}
pubSubApplication.java
package hello;
import java.io.IOException;
import com.google.cloud.pubsub.v1.AckReplyConsumer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.gcp.pubsub.core.PubSubOperations;
import org.springframework.cloud.gcp.pubsub.core.PubSubTemplate;
import org.springframework.cloud.gcp.pubsub.support.GcpHeaders;
import org.springframework.context.annotation.Bean;
import org.springframework.integration.annotation.MessagingGateway;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.gcp.pubsub.AckMode;
import org.springframework.integration.gcp.pubsub.inbound.PubSubInboundChannelAdapter;
import org.springframework.integration.gcp.pubsub.outbound.PubSubMessageHandler;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
@SpringBootApplication
public class PubSubApplication {
private static final Log LOGGER = LogFactory.getLog(PubSubApplication.class);
public static void main(String[] args) throws IOException {
SpringApplication.run(PubSubApplication.class, args);
}
@Bean
public MessageChannel pubsubInputChannel() {
return new DirectChannel();
}
@Bean
public PubSubInboundChannelAdapter messageChannelAdapter(
@Qualifier("pubsubInputChannel") MessageChannel inputChannel,
PubSubOperations pubSubTemplate) {
PubSubInboundChannelAdapter adapter =
new PubSubInboundChannelAdapter(pubSubTemplate, "testSubscription");
adapter.setOutputChannel(inputChannel);
adapter.setAckMode(AckMode.MANUAL);
return adapter;
}
@Bean
@ServiceActivator(inputChannel = "pubsubInputChannel")
public MessageHandler messageReceiver() {
return message -> {
LOGGER.info("Message arrived! Payload: " + message.getPayload());
AckReplyConsumer consumer =
(AckReplyConsumer) message.getHeaders().get(GcpHeaders.ACKNOWLEDGEMENT);
consumer.ack();
};
}
}
更改“testSubscription”to the Subscription you are using
现在在文件夹gs-messaging-gcp-pubsub / complete中,如果运行./gradlew bootRun,应用程序hello.PubSubApplication应该在本地运行。您发布到订阅主题的任何消息都应显示在运行应用程序的位置。
如果您在凭据/认证方面遇到问题,请更改以下参数:
GS-消息传递的GCP-发布订阅/完整/ SRC /主/资源/ application.properties