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());
		}
	}
}
相关推荐
向宇it几秒前
【从零开始入门unity游戏开发之——C#篇24】C#面向对象继承——万物之父(object)、装箱和拆箱、sealed 密封类
java·开发语言·unity·c#·游戏引擎
小蜗牛慢慢爬行2 分钟前
Hibernate、JPA、Spring DATA JPA、Hibernate 代理和架构
java·架构·hibernate
星河梦瑾1 小时前
SpringBoot相关漏洞学习资料
java·经验分享·spring boot·安全
黄名富1 小时前
Redis 附加功能(二)— 自动过期、流水线与事务及Lua脚本
java·数据库·redis·lua
love静思冥想1 小时前
JMeter 使用详解
java·jmeter
言、雲1 小时前
从tryLock()源码来出发,解析Redisson的重试机制和看门狗机制
java·开发语言·数据库
TT哇1 小时前
【数据结构练习题】链表与LinkedList
java·数据结构·链表
Yvemil72 小时前
《开启微服务之旅:Spring Boot 从入门到实践》(三)
java
Anna。。2 小时前
Java入门2-idea 第五章:IO流(java.io包中)
java·开发语言·intellij-idea
.生产的驴2 小时前
SpringBoot 对接第三方登录 手机号登录 手机号验证 微信小程序登录 结合Redis SaToken
java·spring boot·redis·后端·缓存·微信小程序·maven