基于Dapr Sub/Pub的K8s Deployment如何实现扩缩容后所有Pod均接收同条消息
解决方案
核心原理
Dapr Pub/Sub默认将相同dapr.io/app-id的实例归为同一个消费组,同组内单条消息仅会投递到组内一个实例。要实现全副本广播接收消息,需要让每个Pod对应独立的消费组。
具体配置修改
方案1:通过Downward API为每个Pod生成唯一app-id(适配所有Dapr版本)
修改Deployment的Pod模板注解,利用K8s内置的Downward API将Pod名称作为后缀拼接进dapr.io/app-id,保证每个副本的app-id唯一,对应独立消费组:
apiVersion: apps/v1 kind: Deployment metadata: name: webapp spec: replicas: 1 selector: matchLabels: app: webapp template: metadata: labels: app: webapp annotations: dapr.io/enabled: "true" # 用Downward API注入Pod名称作为app-id后缀,保证全局唯一 dapr.io/app-id: "webapp-$(POD_NAME)" dapr.io/app-port: "8080" spec: containers: - name: webapp image: webapp:1.0.0 ports: - containerPort: 8080 # 新增环境变量,从Pod元数据获取Pod名称 env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name
注意:Dapr注入器会自动解析Pod注解中引用的容器环境变量,无需额外修改其他Dapr配置。
方案2:修改Pub/Sub Component配置实现广播(仅支持Dapr 1.10及以上版本)
无需修改app-id,直接在Redis Pub/Sub Component的metadata中添加processingMode参数设置为broadcast,即可让同app-id的所有副本都收到消息:
apiVersion: dapr.io/v1alpha1 kind: Component metadata: name: webapp namespace: default spec: type: pubsub.redis version: v1 metadata: - name: redisHost value: redis-master.default.svc.cluster.local.:6379 - name: redisPassword value: "xxxx" - name: consumerID value: "myGroup" - name: enableTLS value: "false" # 新增广播模式配置 - name: processingMode value: "broadcast"
两种方案二选一部署后,扩容应用即可实现所有副本都能接收同一条Pub/Sub消息。
内容的提问来源于stack exchange,提问作者stackoverflow
相关产品推荐
相关产品推荐

