绑定有点像订阅发布,但又不一样,绑定更简单,绑定输出(调用方)-绑定输入(被调用方)。

  本例是用docker compose编排,并且用rabbitMQ来支持,因为rabbitMQ支持输入和输出绑定。

  demo的目录结构:

Dapr牵手.NET学习笔记:绑定_ide

  binding.yaml,放在components目录下

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: orderupdate
spec:
type: bindings.rabbitmq
version: v1
metadata:
- name: queueName
value: bindQueue
- name: host
value: amqp://admin:!2021que@rabbitmq:5672
- name: durable
value: true
- name: deleteWhenUnused
value: false
- name: ttlInSeconds
value: 60
- name: prefetchCount
value: 0
- name: exclusive
value: false
- name: maxPriority
value: 5

B2C目录中的docker-compose.yml

version: '3.4'

services:
#┌────────────────────────────────┐
#│ ordersystem app + Dapr sidecar │
#└────────────────────────────────┘
ordersystem:
image: ${DOCKER_REGISTRY-}ordersystem
depends_on:
- redis
- placement
build:
context: ../
dockerfile: OrderSystem/Dockerfile
ports:
- "3500:3500"
volumes:
- ../OrderSystem:/OrderSystem
networks:
- b2c-dapr
ordersystem-dapr:
image: "daprio/daprd:latest"
command: [ "./daprd", "-app-id", "order", "-app-port", "80","-placement-host-address", "placement:50006","-components-path","/components"]
depends_on:
- ordersystem
network_mode: "service:ordersystem"
volumes:
- ../components:/components

#┌───────────────────────────────────┐
#│ paymentsystem1 app + Dapr sidecar │
#└───────────────────────────────────┘
paymentsystem1:
image: ${DOCKER_REGISTRY-}paymentsystem
depends_on:
- redis
- placement
- rabbitmq
build:
context: ../
dockerfile: PaymentSystem/Dockerfile
ports:
- "3601:3500"
volumes:
- ../PaymentSystem:/PaymentSystem
networks:
- b2c-dapr
paymentsystem1-dapr:
image: "daprio/daprd:latest"
command: [ "./daprd", "-app-id", "pay", "-app-port", "80","-placement-host-address", "placement:50006","-components-path","/components" ]
depends_on:
- paymentsystem1
network_mode: "service:paymentsystem1"
volumes:
- ../components:/components

#┌───────────────────────────────────┐
#│ paymentsystem2 app + Dapr sidecar │
#└───────────────────────────────────┘
paymentsystem2:
image: ${DOCKER_REGISTRY-}paymentsystem
depends_on:
- redis
- placement
- rabbitmq
build:
context: ../
dockerfile: PaymentSystem/Dockerfile
volumes:
- ../PaymentSystem:/PaymentSystem
ports:
- "3602:3500"
networks:
- b2c-dapr
paymentsystem2-dapr:
image: "daprio/daprd:latest"
command: [ "./daprd", "-app-id", "pay", "-app-port", "80" ,"-placement-host-address", "placement:50006","-components-path","/components"]
depends_on:
- paymentsystem2
network_mode: "service:paymentsystem2"
volumes:
- ../components:/components

#┌───────────────────────────────────┐
#│ noticesystem1 app + Dapr sidecar │
#└───────────────────────────────────┘
noticesystem1:
image: ${DOCKER_REGISTRY-}noticesystem
depends_on:
- redis
- placement
- rabbitmq
build:
context: ../
dockerfile: NoticeSystem/Dockerfile
ports:
- "3701:3500"
volumes:
- ../NoticeSystem:/NoticeSystem
networks:
- b2c-dapr
noticesystem1-dapr:
image: "daprio/daprd:latest"
command: [ "./daprd", "-app-id", "notice", "-app-port", "80","-placement-host-address", "placement:50006","-components-path","/components" ]
depends_on:
- noticesystem1
network_mode: "service:noticesystem1"
volumes:
- ../components:/components


#┌───────────────────────────────────┐
#│ noticesystem2 app + Dapr sidecar │
#└───────────────────────────────────┘
noticesystem2:
image: ${DOCKER_REGISTRY-}noticesystem
depends_on:
- redis
- placement
- rabbitmq
build:
context: ../
dockerfile: NoticeSystem/Dockerfile
ports:
- "3702:3500"
volumes:
- ../NoticeSystem:/NoticeSystem
networks:
- b2c-dapr
noticesystem2-dapr:
image: "daprio/daprd:latest"
command: [ "./daprd", "-app-id", "notice", "-app-port", "80","-placement-host-address", "placement:50006","-components-path","/components" ]
depends_on:
- noticesystem2
network_mode: "service:noticesystem2"
volumes:
- ../components:/components

#┌────────────────────────┐
#│ Dapr placement service │
#└────────────────────────┘
placement:
image: "daprio/dapr"
command: ["./placement", "-port", "50006"]
ports:
- "50006:50006"
networks:
- b2c-dapr

#┌───────────────────┐
#│ Redis state store │
#└───────────────────┘
redis:
image: "redis:latest"
ports:
- "6380:6379"
networks:
- b2c-dapr

#┌──────────────────────┐
#│ RabbitMQ state store │
#└──────────────────────┘
rabbitmq:
image: "rabbitmq:management"
ports:
- "15672:15672"
- "5672:5672"
environment:
- RABBITMQ_DEFAULT_USER=admin
- RABBITMQ_DEFAULT_PASS=!2021que
networks:
- b2c-dapr

networks:
b2c-dapr:

在PaymentSystem和NoticeSystem添加监听传入的事件

[HttpPost("/orderupdate")]
public async Task<IActionResult> OrderUpdate()
{
_logger.LogInformation("NoticeSystem OrderUpdate……");
using var reader = new StreamReader(Request.Body, System.Text.Encoding.UTF8);
var content = await reader.ReadToEndAsync();
_logger.LogInformation(content);
return Ok();
}

启动 docker-compose up -d

会发现所有的挎斗都失败,如下图:

Dapr牵手.NET学习笔记:绑定_ide_02

 查看日志,发现是rabbitMQ的5672没有连接成功,

Dapr牵手.NET学习笔记:绑定_docker_03

   绑过一段分析,配置和代码都没有问题 ,问题 出现在时差上,虽然在docker-compose中,配置了所有服务依赖rabbitMQ,但rabbitMQ的容器虽然启动了,但rabbitMQ服务还没有完全启动起来,这个时间挎斗连接时,就发生连接错误,可以等上一会,手动再次启动挎斗容器就可以了。(这块在生产上需要解决,不能每次都手动)

服务都启动后,可以测试了,调用绑定

http://localhost:3601/v1.0/bindings/orderupdate

需要用post一个json,来调用绑定,分别post了包含10个1 ,10个2,10个3,10个4的四个请求,四个请求会分别触发四个服务的orderupdate事件(这里orderupdate业务不太适合用绑定,应该用发布订阅,因为一个订单变是多,PaymentSystem和NoticeSystem都应该被通知到,但绑定事件不可以,这也是两者的区别)

Dapr牵手.NET学习笔记:绑定_redis_04

  想要更快更方便的了解相关知识,可以关注微信公众号

Dapr牵手.NET学习笔记:绑定_docker_05