聊聊消息中间件
消息中间件概述
分布式架构通信原理
SOA架构
根据实际业务,把系统拆分成合适的、独立部署的模块,模块之间相互独立。
优点:分布式、松耦合、扩展灵活、可重用。
SOA架构系统中,使用Dubbo和Zookeeper进行服务间的远程通信。
优点:
Dubbo使用自定义的TCP协议,可以让请求报文体积更小,或者使用HTTP2协议,也可以减少报文的体积,提高传输效率。
微服务架构
SpringCloud中使用Feign解决服务之间远程通信的问题。
Feign:轻量级RESTful的HTTP服务客户端,广泛应用于Spring Cloud中。符合面向接口化的编程习惯。
本质:封装了HTTP调用流程,类似Dubbo的服务调用。
多用于同步远程调用
RPC主要基于TCP/UDP协议,HTTP协议是应用层协议,是构建在传输层协议TCP之上的,RPC效率更高,RPC长连接:不必每次通信都像HTTP一样三次握手,减少网络开销;
HTTP服务开发迭代更快:在接口不多,系统与系统之间交互比较少的情况下,HTTP就显得更加方便;相反,在接口比较多,系统与系统之间交互比较多的情况下,HTTP就没有RPC有优势。
分布式同步通信的问题
电商项目中,如果后台添加商品信息,该信息放到数据库
我们同时,需要更新搜索引擎的倒排索引,同时,假如有商品页面的静态化处理,也需要更新该页面信息
怎么解决?
方式一:可以在后台添加商品的方法中,如果数据插入数据库成功,就调用更新倒排索引的方法,接着调用更新静态化页面的方法。
代码应该是:
Long goodsId = addGoods(goods);
if (goodsId != null) {
refreshInvertedIndex(goods);
refreshStaticPage(goods);
}
问题:
假如更新倒排索引失败,该怎么办?
假如更新静态页面失败怎么办?
解决方式:
如果更新倒排索引失败,重试
如果更新静态页面失败,重试
代码应该是这样:
public Long saveGoods() {
Long goodsId = addGoods(goods);
if (goodsId != null) {
// 调用递归的方法,实现重试
boolean indexFlag = refreshInvertedIndex(goods);
// 调用递归的方法,实现重试
boolean pageFlag = refreshStaticPage(goods);
}
}
private boolean refreshInvertedIndex(Goods goods) {
// 调用服务的方法
boolean flag = indexService.refreshIndex(goods);
if (!flag) {
refreshInvertedIndex(goods);
}
}
private boolean