源码:Chapter 8 Event-driven architecture with Spring Cloud Stream
要实现的功能是:现有两个微服务,组织服务A,和许可证服务B,B用redis保存A的缓存,B产生变化的时候,用消息队列通知A数据已经变化,请刷新缓存。
一、编写简单的消息生产者和消费者
1.在组织服务里编写消息生产者
组织服务pom依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-kafka</artifactId>
</dependency>
这个就是告诉Spring Cloud Stream将服务绑定到消息代理,该服务将通过Source类上定义的一组通道与消息代理进行通信。Spring Cloud Steam上有一个默认的通道集,可以配置它们来与消息代理进行通信。但是现在还没说它要绑到哪个消息代理。
到这里还没提到要用哪个消息中间件,接下来就把它绑到kafka吧~
在这里简单贴一下Zookeeper和kafka的基本知识(学习的时候,可以先黑箱再白箱):简单了解一下kafka的集群结构。然后试着把它搭建出来,Docker比较方便,首先保证有Java环境。
然后,几条命令就可以搭建好了:
#Zookeeper
docker run -d --name zookeeper -p 2181:2181 -t wurstmeister/zookeeper
#kafka 记得改成自己的IP
docker run -d --name kafka --publish 9092:9092 --link zookeeper --env KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181 --env KAFKA_ADVERTISED_HOST_NAME=192.168.2.149 --env KAFKA_ADVERTISED_PORT=9092 --volume /etc/localtime:/etc/localtime wurstmeister/kafka:latest
#进kafka配置
docker exec -ti kafka /bin/bash
#路径 然后按配置文档操作就行了
cd opt/kafka_2.12-2.3.0/
#对了,记得开端口,Zookeeper是2181,kafka是9092
firewall-cmd --add-port=2181/tcp --permanent
firewall-cmd --add-port=9092/tcp --permanent
firewall-cmd --reload
到现在为止,绑定已经完成,然后看一下消息的实际发布在哪里:
小笔记:在消息里要放多少数据呢?比如是只放一个id,还是把一整个表的改动都放进去呢?只放一个ID的意思是,我通知你有变化了,你去源头拉取数据验证吧。全部放的意思是,直接从消息队列里就可以拿到数据。这样一看,后者少了一次请求,似乎更好?实际上不是这样的,后者不能保证数据是最新的,实际上在消息队列里,消息可能是很久之前的,而且数据可以不按顺序进行检索。所以,还是溯源一下比较好。
2.在许可证服务中编写消息消费者
pom依赖不多说。
引导类有点不同。
因为消费者只需要监听就行了,所以:
消费者组的概念:可能有多个服务,一个服务可能有多个实例,把它们编个组,那么就只让其中一个实例接收消息就可以了,意思就是小组里的人都受到了一条刷新的消息,让一个人去通知redis刷新就行了。
3.在实际操作中查看消息服务。
更改Zookeeper和kafka的host配置为实际地址,依次开启Eureka->配置服务->许可证服务->组织服务->路由服务。
然后put以下内容:
{
"contactEmail":"[email protected]",
"contactName":"week",
"contactPhone":"123456789",
"id":"e254f8c-c442-4ebe-a82a-e2fc1d1ff78a",
"name":"customer-crm-co"
}
put之后,在组织微服务就看到了一个UPDATE:
许可证服务也收到了一条消息:
二、Spring Cloud Stream用例:分布式缓存
刚才的验证阶段,许可证服务实际上是报错了的,是因为还没有配置Redis,这个问题放在这节讲述。
这里先用docker装一下redis:
#安装
docker run -p 6379:6379 -d redis:latest redis-server
#开端口
firewall-cmd --add-port=6379/tcp --permanent
firewall-cmd --reload
1.使用redis来查找缓存。
(1)pom依赖
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.7.4.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.0</version>
</dependency>
(2)构造一个到Redis服务器的数据库连接
设置在这里:
(3)定义Spring Data Redis存储库
接口实现:
(4)使用Redis和许可证服务来存储和读取组织数据
验证一下:
运行第二次就会发现:
用redisclient也能看到:
2.定义自定义通道
我们之前用的是input和output的默认通道,现在来自定义一个:
而output是这样的:
@OutputChannel(outboudOrg)
MessageChannel outboudOrg();
然后许可证服务的配置要改成这样:
再处理一下监听处理器:
以上~