二、RabbitMQのあるショッピングモールプロジェクトでの使用例
41619 ワード
一、商品に対して添削して調べる時にメッセージを送る
item-serviceに
プロファイルでの関連情報の構成
GoodsServiceにメッセージを送信する方法を追加するには、amqpTemplateオブジェクトを先に注入します.ここでの
新規商品の場合、メッセージを送信する必要があります.
商品を修正する場合も、同様にメッセージを送る必要があります
二、ページ静化のマイクロサービスでメッセージを受け取り、静的ページを更新する
goods-webマイクロサービスでも同様に依存を導入し,rabbitMQの構成に関する情報は同上であるが,ここではスイッチの名前を宣言する必要はない
三、検索マイクロサービスでインデックスライブラリのデータを更新する
依存性を導入し、rabbitMQを構成し、リスニングメッセージを追加する方法
次のサービスにおけるsaveメソッドが投げ出す異常は、上の
四、ユーザー登録時にメール認証コードを送る
user-serviceマイクロサービスで
メールマイクロサービスでは,メッセージを傍受してメールを送信する方法を記述する.
item-serviceに
amqp
依存を導入:<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-amqpartifactId>
dependency>
プロファイルでの関連情報の構成
server:
port: 8081
mybatis:
type-aliases-package: com.leyou.item.pojo
spring:
datasource:
url: jdbc:mysql://localhost:3306/leyou
username: root
password: 123456
application:
name: item-service #
#
rabbitmq:
host: 192.168.248.131
virtual-host: /
username: admin
password: admin
template:
exchange: LEYOU.ITEM.EXCHANGE #
eureka:
client:
service-url:
defaultZone: http://localhost:10086/eureka
register-with-eureka: true # , true,true eureka
instance:
lease-renewal-interval-in-seconds: 5 # , 5s
lease-expiration-duration-in-seconds: 15 #
GoodsServiceにメッセージを送信する方法を追加するには、amqpTemplateオブジェクトを先に注入します.ここでの
routing key
,フォーマットはitem.*
,*
です.メッセージを送信する方法で送信されます.try{}catch(){}
を使用するのは、メッセージの送信に異常が発生することを防止し、正常なデータベース保存操作に影響を与えるためです.private void sendMsg(String type, Long id) {
try {
this.amqpTemplate.convertAndSend("item." + type, id);
} catch (AmqpException e) {
e.printStackTrace();
}
}
新規商品の場合、メッセージを送信する必要があります.
rooting key
はitem.insert
で、伝達されたパラメータはinsert
と新規商品のid
です.@Transactional// , spu, spuDetail
public void saveGoods(SpuBo spuBo) {
//1. spu,spuBo spu
//
spuBo.setId(null);
spuBo.setSaleable(true);
spuBo.setValid(true);
spuBo.setCreateTime(new Date());
spuBo.setLastUpdateTime(spuBo.getCreateTime());
this.spuMapper.insertSelective(spuBo);
//2. spuDetail
SpuDetail spuDetail = spuBo.getSpuDetail();
spuDetail.setSpuId(spuBo.getId());
this.spuDetailMapper.insertSelective(spuDetail);
//3. sku
saveSkuAndStock(spuBo);
// :item.insert, rooting key
sendMsg("insert", spuBo.getId());
}
商品を修正する場合も、同様にメッセージを送る必要があります
@Transactional
public void updateGoods(SpuBo spuBo) {
// spuId sku
Sku record = new Sku();
record.setSpuId(spuBo.getId());
List<Sku> skus = this.skuMapper.select(record);
// ,
if(!CollectionUtils.isEmpty(skus)) {
skus.forEach(sku -> {
//
this.stockMapper.deleteByPrimaryKey(sku.getId());
});
// sku
Sku sku = new Sku();
sku.setSpuId(spuBo.getId());
this.skuMapper.delete(sku);
}
// sku stock
this.saveSkuAndStock(spuBo);
// spu
spuBo.setLastUpdateTime(new Date());
spuBo.setCreateTime(null);
spuBo.setValid(null);
spuBo.setSaleable(null);
this.spuMapper.updateByPrimaryKeySelective(spuBo);
// spu
this.spuDetailMapper.updateByPrimaryKeySelective(spuBo.getSpuDetail());
// ,
sendMsg("update",spuBo.getId());
}
二、ページ静化のマイクロサービスでメッセージを受け取り、静的ページを更新する
goods-webマイクロサービスでも同様に依存を導入し,rabbitMQの構成に関する情報は同上であるが,ここではスイッチの名前を宣言する必要はない
/**
* @auther Mr.Liao
* @date 2019/5/17 10:02
*/
@Component
public class GoodsListener {
@Autowired
private GoodsHtmlService goodsHtmlService;
/**
*
* @param id
*/
@RabbitListener(bindings = @QueueBinding(
value = @Queue(value = "LEYOU.ITEM.SAVE.QUEUE", durable = "true"),
exchange = @Exchange(value = "LEYOU.ITEM.EXCHANGE", ignoreDeclarationExceptions = "true", type = ExchangeTypes.TOPIC),
key = {"item.insert","item.update"}
))
public void save(Long id){
if (id == null){
return;
}
// createHtml() , spuId
this.goodsHtmlService.createHtml(id);
}
/**
* ,
* @param id
*/
@RabbitListener(bindings = @QueueBinding(
value = @Queue(value = "LEYOU.ITEM.DELETE.QUEUE",durable = "true"),
exchange = @Exchange(value = "LEYOU.ITEM.EXCHANGE",ignoreDeclarationExceptions = "true", type = ExchangeTypes.TOPIC),
key = {"item.delete"}
))
public void delete(Long id){
if (id == null){
return;
}
this.goodsHtmlService.deleteHtml(id);
}
}
三、検索マイクロサービスでインデックスライブラリのデータを更新する
依存性を導入し、rabbitMQを構成し、リスニングメッセージを追加する方法
@Component
public class GoodsListener {
@Autowired
private SearchService searchService;
/**
* ,
* @param id
* @throws IOException
*/
@RabbitListener(bindings = @QueueBinding(
value = @Queue(value = "LEYOU.SEARCH.SAVE.QUEUE",durable = "true"),
exchange = @Exchange(value = "LEYOU.ITEM.EXCHANGE",ignoreDeclarationExceptions = "true", type = ExchangeTypes.TOPIC),
key = {"item.insert","item.update"}
))
public void save(Long id) throws IOException {
if (id == null){
return;
}
this.searchService.save(id);
}
/**
*
* @param id
* @throws IOException
*/
@RabbitListener(bindings = @QueueBinding(
value = @Queue(value = "LEYOU.SEARCH.DELETE.QUEUE",durable = "true"),
exchange = @Exchange(value = "LEYOU.ITEM.EXCHANGE",ignoreDeclarationExceptions = "true", type = ExchangeTypes.TOPIC),
key = {"item.delete"}
))
public void delete(Long id) throws IOException {
if (id == null){
return;
}
this.searchService.delete(id);
}
}
次のサービスにおけるsaveメソッドが投げ出す異常は、上の
GoodsListener
に投げ出され、ここでのsaveがまた異常を投げ出すと、springフレームワークは、異常があるか否かに応じて、メッセージを確認するか否か(手動ACK)を決定する/**
* ,
* @param id
* @throws IOException
*/
public void save(Long id) throws IOException {
// Id
Spu spu = this.goodsClient.querySpuById(id);
//
Goods goods = this.buildGoods(spu);
//
this.goodsRepository.save(goods);
}
/**
* ,
* @param id
*/
public void delete(Long id) {
this.goodsRepository.deleteById(id);
}
四、ユーザー登録時にメール認証コードを送る
user-serviceマイクロサービスで
/**
* , , redis
* @param phone
*/
public void sendVerifyCode(String phone) {
if (StringUtils.isBlank(phone)){
return;
}
//
String code = NumberUtils.generateCode(6);
// rabbitMQ, sms ,
HashMap<String, String> msg = new HashMap<>();
msg.put("phone",phone);
msg.put("code", code);
this.amqpTemplate.convertAndSend("LEYOU.SMS.EXCHANGE","verifyCode.sms", msg);
// redis
this.redisTemplate.opsForValue().set(KEY_PREFIX+phone, code, 5, TimeUnit.MINUTES);
}
メールマイクロサービスでは,メッセージを傍受してメールを送信する方法を記述する.
@Component
public class SmsListener {
@Autowired
private SmsUtils smsUtils;
@Autowired
private SmsProperties smsProperties;
/**
*
* @param msg
* @throws ClientException
*/
@RabbitListener(bindings = @QueueBinding(
value = @Queue(value = "LEYOU.SMS.QUEUE",durable = "true"),
exchange = @Exchange(value = "LEYOU.SMS.EXCHANGE",ignoreDeclarationExceptions = "true", type = ExchangeTypes.TOPIC),
key = {"verifyCode.sms"}
))
public void sendSms(Map<String, String> msg) throws ClientException {
if (CollectionUtils.isEmpty(msg)){
return;
}
String phone = msg.get("phone");
String code = msg.get("code");
if (StringUtils.isNoneBlank(phone) && StringUtils.isNoneBlank(code)){
this.smsUtils.sendSms(phone, code, this.smsProperties.getSignName(),this.smsProperties.getVerifyCodeTemplate());
}
}
}