# 165. 商品详情页动态渲染系统:依赖服务将数据变更消息写入 rabbitmq 或双写 redis
下
本次整合是在 eshop-product-service 项目中
# 整合 rabbitmq 的发送与消费
添加依赖
compile 'org.springframework.boot:spring-boot-starter-amqp'
1
自动配置
spring:
rabbitmq:
host: localhost
port: 5672
username: admin
password: 123456
1
2
3
4
5
6
2
3
4
5
6
此自动配置在 org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration.RabbitTemplateConfiguration#rabbitTemplate
中被应用,
# 生产者与消费者的 helloWord 代码如下
// 生产者
@Component
public class RabbitMQSender {
@Autowired
private AmqpTemplate rabbitTemplate;
public void send(String message) {
this.rabbitTemplate.convertAndSend("my-queue", message);
}
}
// 消费者
@Component
@RabbitListener(queues = "my-queue")
public class RabbitMQReceiver {
@RabbitHandler
public void process(String message) {
System.out.println("从my-queue队列接收到一条消息:" + message);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 业务实现
商品服务数据变更,将消息写入 rabbitmq,时效性比较低的数据,走 rabbitmq,然后后面就接着整套动态渲染系统去玩儿
封装一个生产者
package cn.mrcode.cache.eshop.productserver.rabbitmq;
@Component
public class RabbitMQSender {
@Autowired
// private AmqpTemplate amqpTemplate;
private RabbitTemplate rabbitTemplate;
public void send(String queue, String message) {
this.rabbitTemplate.convertAndSend(queue, message);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
在以下服务中添加事件发送
BrandService
CategoryService
ProductIntroService
ProductPropertyService
ProductService
ProductSpecificationService
1
2
3
4
5
6
2
3
4
5
6
先封装一个事件实体,服务中以该实体作为载体,比自己拼接 json 串方便
public class ProductEvent {
private String eventType;
private String dataType;
private Long id;
public ProductEvent(String eventType, String dataType, Long id) {
this.eventType = eventType;
this.dataType = dataType;
this.id = id;
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
这里以品牌为例:
@Service
public class BrandServiceImpl implements BrandService {
@Autowired
private BrandMapper brandMapper;
@Autowired
private RabbitMQSender rabbitMQSender;
public void add(Brand brand) {
brandMapper.add(brand);
// data_change_queue 队列名称,不会自动创建,所以需要在 ui 中手动创建
rabbitMQSender.send(RabbitMQName.DATA_CHANGE_QUEUE, JSON.toJSONString(new ProductEvent("add", "brand", brand.getId())));
}
public void update(Brand brand) {
brandMapper.update(brand);
rabbitMQSender.send(RabbitMQName.DATA_CHANGE_QUEUE, JSON.toJSONString(new ProductEvent("update", "brand", brand.getId())));
}
public void delete(Long id) {
brandMapper.delete(id);
rabbitMQSender.send(RabbitMQName.DATA_CHANGE_QUEUE, JSON.toJSONString(new ProductEvent("delete", "brand", id)));
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 整合 redis
价格服务和库存服务数据变更,直接将数据双写到 redis 中, 时效性比较高的数据,直接 mysql+redis 双写,不走动态渲染系统,写到 redis 之后,后面走 OneService 服务提供页面的 ajax 调用
添加依赖
compile 'org.springframework.boot:spring-boot-starter-data-redis'
1
添加自动配置(有关 spring-boot-starter-data-redis (opens new window) 的详细深入配置请去官网查询)
spring:
redis:
port: 6379
host: localhost
1
2
3
4
2
3
4
使用处直接使用 RedisTemplate 即可
@Autowired
private RedisTemplate<String, String> redisTemplate;
1
2
2
这里以商品价格服务来示例
@Autowired
private RedisTemplate<String, String> redisTemplate;
public void add(ProductPrice productPrice) {
productPriceMapper.add(productPrice);
redisTemplate.opsForValue().set("product_price_" + productPrice.getId(), JSON.toJSONString(productPrice));
}
public void update(ProductPrice productPrice) {
productPriceMapper.update(productPrice);
redisTemplate.opsForValue().set("product_price_" + productPrice.getId(), JSON.toJSONString(productPrice));
}
public void delete(Long id) {
productPriceMapper.delete(id);
redisTemplate.delete("product_price_" + id);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17