Schema约束下通过HTTPS向Pub/Sub Topic推送消息失败求助
问题解决:通过HTTPS推送消息到绑定Schema的Pub/Sub Topic
错误根源
你遇到的两个错误核心原因是错误地使用了attributes字段传递结构化消息体:
attributes仅支持字符串类型键值对,传递数字类型(profile_id:123)时,客户端会自动尝试用带类型标识的结构序列化,导致Pub/Sub无法识别- 将数字转为字符串后,不符合Proto2 Schema中
int64的类型定义,触发校验失败
此外,Proto2的JSON序列化规则较复杂,不适合直接通过curl手动构造消息,建议切换到更友好的Avro或Proto3 Schema。
方案一:切换到Avro Schema(推荐,适配JSON与BigQuery)
Avro的JSON格式直观,和BigQuery表结构适配性更好,适合手动构造curl请求的场景。
1. 更新Terraform Schema定义
resource "google_pubsub_schema" "my_schema_name" { name = "my_schema_name" type = "AVRO" definition = <<EOF { "type": "record", "name": "AvroMessage", "fields": [ {"name": "id", "type": "string"}, {"name": "profile_id", "type": "long"}, {"name": "address", "type": ["null", "string"]}, {"name": "date", "type": "string"} ] } EOF }
long类型对应BigQuery的Integer["null", "string"]对应BigQuery的nullable String
2. 正确的curl推送命令
将结构化JSON消息转为Base64编码后,放入data字段:
curl --location --request POST 'https://pubsub.googleapis.com/v1/projects/my-project/topics/my-topic:publish' \ --header 'Authorization: Bearer myAccessToken' \ --header 'Content-Type: application/json' \ --data-raw '{ "messages": [ { "data": "eyJpZCI6IklEMTIzIiwicHJvZmlsZV9pZCI6MTIzLCJhZGRyZXNzIjoic29tZXdoZXJlIGluIHRoZSB3b3JsZCIsImRhdGUiOiIyMDIzLTA3LTIwIn0=" } ] }'
- 上述
data值是以下JSON的Base64编码:{"id": "ID123", "profile_id": 123, "address": "somewhere in the world", "date": "2023-07-20"} - 你可以用命令行(如
echo '{"id":...}' | base64)或在线工具生成自定义的Base64字符串
方案二:切换到Proto3 Schema
如果偏好Protocol Buffer,Proto3的JSON序列化规则更简洁,避免Proto2的复杂限制。
1. 更新Terraform Schema定义
resource "google_pubsub_schema" "my_schema_name" { name = "my_schema_name" type = "PROTOCOL_BUFFER" definition = <<EOF syntax = "proto3"; message ProtocolBuffer { string id = 1; int64 profile_id = 2; optional string address = 3; string date = 5; } EOF }
- Proto3默认字段为可选,
optional显式标记address的nullable特性
2. 正确的curl推送命令
同样将Proto3对应的JSON消息Base64编码后放入data字段,curl命令与Avro方案一致,仅Schema不同。
关键注意事项
- 务必将结构化数据放入
data字段,attributes仅用于传递元数据(如消息标签、追踪ID等) - 确保Topic已关联更新后的Schema,BigQuery订阅会自动映射Avro/Proto3字段到目标表结构
- 如果需要直接传递JSON字符串(无需Base64),可在Topic配置中设置
json_schema_validation_mode为ALLOW_JSON,并指定message_format为JSON
内容的提问来源于stack exchange,提问作者Alexander Chandra
相关产品推荐
相关产品推荐

