使用Atomikos实现微服务(Rest)分布式事务

最近在给客户做分布式事务的解决方案的时候发现Atomikos提供了一种有趣的跨服务的分布式事务解决方案,实现了微服务之间数据的强一致性。

我本人并不赞同和喜欢这种分布式事务的实现方式,我更喜欢Saga方式的分布式事务解决方案。强一致的事务需要为资源加锁,网络或者事务参与方的故障会导致大量的资源不能释放,在极端情况下可能导致应用雪崩。我的观点是在应用架构设计中要尽量避免这种强一致的分布式事务实现方式,根据不同的业务场景,设计灵活的事务补偿方案,利用Rocket MQ等中间件协调事务的各个参与方,附加自动扫描与监控机制,必要时人工干预,从而达到事务的最终一致性。

感兴趣的朋友可以访问Atomikos的网站gitub,了解这种跨服务事务的具体实现。

点击下载示例代码, 解压后使用JDK 8编译执行examples-jta-rest-jaxrs目录下的Java代码,如果使用JDK 8以上版本需要在pom中添加JAXB依赖。

实现原理


客户端配置

import com.atomikos.remoting.jaxrs.TransactionAwareRestClientFilter;

  javax.ws.rs.client.Client paymentClient = ClientBuilder.newClient();

  paymentClient.register(TransactionAwareRestClientFilter.class);

客户端拦截器会自动在客户端JVM中检测到任何活动的Atomikos事务,并通过HTTP Header将其传播到服务端,以便服务端可以加入该事务。它还从HTTP Response header中提取URL,利用这个URL向服务端发出两段提交指令。

服务器端配置

import com.atomikos.remoting.jaxrs.TransactionAwareRestContainerFilter;

  import com.atomikos.remoting.twopc.AtomikosRestPort;

  JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean(); //we used CXF for our demo

  sf.setProvider(new TransactionAwareRestContainerFilter());

  sf.setResourceProvider(new SingletonResourceProvider(new AtomikosRestPort()));

服务端的拦截器可以检测客户端的事务传播请求,并加入该事务。它还将回调URL添加到HTTP Response Header中, AtomikosRestPort侦听该URL并等待提交指令(请求)。

实验

为了更好的观察事务的实现原理,我们在客户端和服务端添加了少许Java代码以便打印HTTP Request和Response. 

在客户端添加代码,打印HTTP Response 

打印HTTP Response Headers

在服务端添加代码,打印HTTP Request

声明HTTP Request


在purchase 方法中打印HTTP Request Headers

运行EmbeddedTransactionManagerClient,查看日志

首先查看服务端日志,你会发现在客户端发送的HTTP Request中有一个Atomikos-Propagation header,客户端利用Atomikos-Propagation Header向服务端发送了一个事务传播请求,并附带了一个事务ID,172.16.73.169.tm159341106682100001到服务端。

Atomikos-Propagation: version=2019,domain=172.16.73.169.tm,timeout=9450,serial=true,recoveryCoordinatorURI=172.16.73.169.tm159341106682100001,parent=172.16.73.169.tm159341106682100001,property.com.atomikos.icatch.jta.transaction=true

继续读服务端的日志,Atomikos在服务端创建了一个子事务inventory159341106754700004 ,并对这个子事务做了提交,查看Atomikos的帮助文档可以知道,Atomikos此时并没有真正提交事务,而是把子事务的提交延迟到和父事务一起提交。

createSubTransaction(): created new SUBTRANSACTION inventory159341106754700004 for existing transaction inventory159341106739100002 with coordinatorId inventory159341106754700005

commit() done (by application) of transaction inventory159341106754700004

回过头来检查客户端日志,会发现HTTP Response中有一个Atomikos-Extent header,其中包含一个回调uri。客户端利用这个URI回调服务端,向服务端发出预提交与提交请求。

Atomikos-Extent:[version=2019,parent=172.16.73.169.tm159341106682100001,uri=http://localhost:9001/atomikos/172.16.73.169.tm159341106682100001/inventory159341106739100003,responseCount=1,direct=true]

继续检查客户端日志,客户端发出了两个Rest回调完成了两段提交

Calling prepare on http://localhost:9001/atomikos/172.16.73.169.tm159341106682100001/inventory159341106739100003

Calling commit on http://localhost:9001/atomikos/172.16.73.169.tm159341106682100001/inventory159341106739100003

总结

Atomikos这个样例代码为我们提供一种跨服务分布式事务的参考思路。Atomikos声称他们也会提供Spring Rest interceptor,但是Atomikos的这种分布式事务方案使客户端与服务端紧耦合,影响微服务的可用性,此外从Atomikos提供的示例代码中也不能检验它能否支持集群部署,即使Atomikos支持集群部署,笔者也并不赞同这种强一致的事务实现方式。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,830评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,992评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,875评论 0 331
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,837评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,734评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,091评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,550评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,217评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,368评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,298评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,350评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,027评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,623评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,706评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,940评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,349评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,936评论 2 341