java 连接google cloud pubsub做消息发布和消费

pom依赖

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-gcp-starter-pubsub</artifactId>
            <version>1.2.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-integration</artifactId>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>30.1-jre</version>
        </dependency>

yml配置

pubsub-secret-key.json 为谷歌云服务账号密钥,密钥生成看谷歌云文档

spring:
  cloud:
    gcp:
      pubsub:
        enabled: true
      project-id: project-ID
      credentials:
        location: classpath:pubsub-secret-key.json

java代码

import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import org.springframework.stereotype.Service;
import com.allsaints.reco.service.PubSubService;
import com.google.api.core.ApiFuture;
import com.google.api.gax.core.FixedCredentialsProvider;
import com.google.api.gax.retrying.RetrySettings;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.cloud.pubsub.v1.MessageReceiver;
import com.google.cloud.pubsub.v1.Publisher;
import com.google.cloud.pubsub.v1.Subscriber;
import com.google.cloud.pubsub.v1.stub.GrpcSubscriberStub;
import com.google.cloud.pubsub.v1.stub.SubscriberStub;
import com.google.cloud.pubsub.v1.stub.SubscriberStubSettings;
import com.google.protobuf.ByteString;
import com.google.pubsub.v1.AcknowledgeRequest;
import com.google.pubsub.v1.ProjectSubscriptionName;
import com.google.pubsub.v1.ProjectTopicName;
import com.google.pubsub.v1.PubsubMessage;
import com.google.pubsub.v1.PullRequest;
import com.google.pubsub.v1.PullResponse;
import com.google.pubsub.v1.ReceivedMessage;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.TimeUnit;
import org.threeten.bp.Duration;

@Service
@Slf4j
public class PubSubServiceImpl implements PubSubService {

	String projectId = "project-ID";
	String subscriptionId = "订阅id";

	@PostConstruct
	public void startSubscriber() throws IOException {
		ProjectSubscriptionName subscriptionName = ProjectSubscriptionName.of(projectId, subscriptionId);

		MessageReceiver receiver = (message, consumer) -> {
			// 处理接收到的消息
			log.info("Received message------------" + message.getData().toStringUtf8());

			// 确认消息已被处理
			consumer.ack();
		};
		GoogleCredentials credentials = GoogleCredentials
				.fromStream(new FileInputStream("src/main/resources/pubsub-secret-key.json"));
		Subscriber subscriber = Subscriber.newBuilder(subscriptionName, receiver).setCredentialsProvider(FixedCredentialsProvider.create(credentials)).build();
		subscriber.startAsync().awaitRunning();
		
		subscriber.stopAsync();
	}

	@Override
	public void publishMessage(String message) {
		Publisher publisher = null;
		try {
			GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream("src/main/resources/pubsub-secret-key.json"));
			ProjectTopicName topicName = ProjectTopicName.of(projectId, "topid-ID");
			FixedCredentialsProvider credentialsProvider = FixedCredentialsProvider.create(credentials);
			 Duration initialRetryDelay = Duration.ofMillis(100); // default: 100 ms
		      double retryDelayMultiplier = 2.0; // back off for repeated failures, default: 1.3
		      Duration maxRetryDelay = Duration.ofSeconds(60); // default : 60 seconds
		      Duration initialRpcTimeout = Duration.ofSeconds(1); // default: 5 seconds
		      double rpcTimeoutMultiplier = 1.0; // default: 1.0
		      Duration maxRpcTimeout = Duration.ofSeconds(600); // default: 600 seconds
		      Duration totalTimeout = Duration.ofSeconds(600); // default: 600 seconds

		      RetrySettings retrySettings =
		          RetrySettings.newBuilder()
		              .setInitialRetryDelay(initialRetryDelay)
		              .setRetryDelayMultiplier(retryDelayMultiplier)
		              .setMaxRetryDelay(maxRetryDelay)
		              .setInitialRpcTimeout(initialRpcTimeout)
		              .setRpcTimeoutMultiplier(rpcTimeoutMultiplier)
		              .setMaxRpcTimeout(maxRpcTimeout)
		              .setTotalTimeout(totalTimeout)
		              .build();
			publisher = Publisher.newBuilder(topicName).setCredentialsProvider(credentialsProvider).setRetrySettings(retrySettings).build();

			ByteString data = ByteString.copyFromUtf8(message);
			PubsubMessage pubsubMessage = PubsubMessage.newBuilder().setData(data).build();
			ApiFuture<String> res = publisher.publish(pubsubMessage);
			log.info("pubsub 发布结果 = {}",res);
			log.info("pubsub 发布结果 = {}",res.get());
//			publisher.shutdown();
//			publisher.awaitTermination(30, TimeUnit.SECONDS);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (publisher != null) {
				// When finished with the publisher, shutdown to free up resources.
				publisher.shutdown();
				try {
					publisher.awaitTermination(1, TimeUnit.MINUTES);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		 }
		
	}

	@Override
	public void pullMessages() {
		// 创建订阅名称
		ProjectSubscriptionName subscriptionName = ProjectSubscriptionName.of(projectId, subscriptionId);
		PullRequest pullRequest = PullRequest.newBuilder().setSubscription(subscriptionName.toString()).setMaxMessages(1).build();
		try {
			GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream("src/main/resources/pubsub-secret-key.json"));
			SubscriberStubSettings subscriberStubSettings = SubscriberStubSettings.newBuilder().setCredentialsProvider(() -> credentials).build();
			GrpcSubscriberStub subscriberStub = GrpcSubscriberStub.create(subscriberStubSettings);
			// 发送拉取请求并处理接收到的消息
			List<ReceivedMessage> list = subscriberStub.pullCallable().call(pullRequest).getReceivedMessagesList();
			list.forEach(message -> {
				// 处理消息逻辑
				log.info("Received message: " + message.getMessage().getData().toStringUtf8());
			});
			subscriberStub.shutdown();
		} catch (IOException e) {
			log.error("拉取pubsub消息异常 = {}",e);
		}
//		String projectId = "asofone-composer2-project";
//		String subscriptionId = "java-test-sub";
//		Integer numOfMessages = 10;
//		try {
//			subscribeSyncExample(projectId, subscriptionId, numOfMessages);
//		}catch (Exception e) {
//			log.error("{}",e);
//		}
		
	}
	

	/***************************************************/
//	public static void main(String... args) throws Exception {
//		String projectId = "asofone-composer2-project";
//		String subscriptionId = "java-test-sub";
//		Integer numOfMessages = 10;
//
//		subscribeSyncExample(projectId, subscriptionId, numOfMessages);
//	}

	public static void subscribeSyncExample(String projectId, String subscriptionId, Integer numOfMessages)
			throws IOException {
		GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream("src/main/resources/pubsub-secret-key.json"));
		// 创建 SubscriberStubSettings.Builder 对象
		SubscriberStubSettings.Builder subscriberSettingsBuilder = SubscriberStubSettings.newBuilder();

		// 将 GoogleCredentials 对象设置到 SubscriberStubSettings.Builder 中
		subscriberSettingsBuilder.setCredentialsProvider(FixedCredentialsProvider.create(credentials));

		// 构建 SubscriberStubSettings 对象
//		SubscriberStubSettings subscriberSettings = subscriberSettingsBuilder.build();
		SubscriberStubSettings subscriberStubSettings = SubscriberStubSettings.newBuilder()
				.setTransportChannelProvider(
					SubscriberStubSettings.defaultGrpcTransportProviderBuilder().setMaxInboundMessageSize(20 * 1024 * 1024).build()) // 20MB (maximum message size))
				.build();

		try (SubscriberStub subscriber = GrpcSubscriberStub.create(subscriberStubSettings)) {
			String subscriptionName = ProjectSubscriptionName.format(projectId, subscriptionId);
			PullRequest pullRequest = PullRequest.newBuilder().setMaxMessages(numOfMessages).setSubscription(subscriptionName).build();
			// Use pullCallable().futureCall to asynchronously perform this operation.
			PullResponse pullResponse = subscriber.pullCallable().call(pullRequest);

			// Stop the program if the pull response is empty to avoid acknowledging
			// an empty list of ack IDs.
			if (pullResponse.getReceivedMessagesList().isEmpty()) {
				log.info("消息列表 = {}",pullResponse.getReceivedMessagesList());
				return;
			}

			List<String> ackIds = new ArrayList<>();
			for (ReceivedMessage message : pullResponse.getReceivedMessagesList()) {
				// Handle received message
				// ...
				ackIds.add(message.getAckId());
			}

			// Acknowledge received messages.
			AcknowledgeRequest acknowledgeRequest = AcknowledgeRequest.newBuilder().setSubscription(subscriptionName)
					.addAllAckIds(ackIds).build();

			// Use acknowledgeCallable().futureCall to asynchronously perform this
			// operation.
			subscriber.acknowledgeCallable().call(acknowledgeRequest);
			System.out.println(pullResponse.getReceivedMessagesList());
		}
	}
}
相关推荐
阿乾之铭13 分钟前
spring MVC 拦截器
java·spring·mvc
码爸16 分钟前
flink 批量写clickhouse
java·clickhouse·flink
djgxfc19 分钟前
简单了解Maven与安装
java·maven
中文很快乐22 分钟前
springboot结合p6spy进行SQL监控
java·数据库·sql
丶白泽22 分钟前
重修设计模式-概览
java·设计模式
小电玩23 分钟前
谈谈你对Spring的理解
java·数据库·spring
五味香27 分钟前
C++学习,动态内存
java·c语言·开发语言·jvm·c++·学习·算法
无名之逆27 分钟前
计算机专业的就业方向
java·开发语言·c++·人工智能·git·考研·面试
爱棋笑谦34 分钟前
二叉树计算
java·开发语言·数据结构·算法·华为od·面试
狂盗一枝梅36 分钟前
深入理解Java对象结构
java