Apache Seata、GaussDB、ServiceComb分布式事务功能集成验证
Apache Seata是由阿里巴巴捐献给Apache基金会的项目,目前是分布式事务领域应用比较广泛的组件,在国内也有很好的口碑和传播度。 本文通过集成Apache Seata、GaussDB、ServiceComb,演示在微服务架构下使用分布式事务。
验证方案设计
本文采用了Apache Seata提供的官网例子:https://seata.apache.org/docs/user/quickstart#step-4-start-server 来演示分布式事务。 具体部署图如下:
与官网的例子的对应关系为:
authentication-server : Account
admin-service: Storage
resource-server: Order
business-server: Business
本文涉及的代码和例子参考: https://gitcode.com/HuaweiCloudDeveloper/opensource-demo-seata-241119/overview 。 可以参考开源 for Huawei 提供的官方指导(https://gitcode.com/HuaweiCloudDeveloper/OpenSourceForHuaweiWiki/overview )部署这个例子。
适配方案介绍
GaussDB适配和问题
由于Seata官网只支持PostgreSQL,并不支持OpenGauss 和 GaussDB数据库,因此我们在设计验证方案的时候,是使用 GaussDB 兼容 PostgreSQL的JDBC驱动。即 https://gitcode.com/HuaweiCloudDeveloper/OpenSourceForHuaweiWiki/issues/23 里面描述的方案二来验证。 使用这个方案,需要本地集成GaussDB的商业驱动。
<dependency>
<groupId>com.huawei</groupId>
<artifactId>gsjdbc4</artifactId>
<scope>system</scope>
<version>1.0</version>
<systemPath>${project.basedir}/../lib/gsjdbc4.jar</systemPath>
</dependency>
同时需要配置Spring Boot Maven Plugin,增加includeSystemScope否则默认不会将驱动打包。
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot-maven-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
数据源按照PostgreSQL兼容的方式进行配置即可:
spring.datasource.driverClassName=org.postgresql.Driver
spring.datasource.url=${DB_URL:jdbc:postgresql://127.0.0.1:8000/postgres?currentSchema=seata}
spring.datasource.username=${DB_USERNAME:root}
spring.datasource.password=${DB_PASSWORD:root}
在适配的时候,发现Seata提供的DEMO使用了MySQL的语法使用Spring JDBCTemplate,和PostgreSQL存在不兼容,问题记录在: https://gitcode.com/HuaweiCloudDeveloper/OpenSourceForHuaweiWiki/issues/28
与ServiceComb的集成
根据Seata官网介绍,与微服务框架的集成,需要提供事务传播机制: https://seata.apache.org/docs/user/microservice 。 使用 ServiceComb 的请求上下文机制,能够方便的解决事务传播问题:
public class SeataContextConsumerFilter extends AbstractFilter implements ConsumerFilter {
@Override
public int getOrder() {
return 0;
}
@Override
public String getName() {
return "seata-consumer";
}
@Override
public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {
String xid = RootContext.getXID();
if (xid != null) {
invocation.addContext(RootContext.KEY_XID, xid);
}
return nextNode.onFilter(invocation);
}
}
public class SeataContextProviderFilter extends AbstractFilter implements ProviderFilter {
@Override
// after schedule and only work in blocking mode
public int getOrder() {
return ProviderFilter.PROVIDER_SCHEDULE_FILTER_ORDER + 10;
}
@Override
public String getName() {
return "seata-provider";
}
@Override
public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {
String context = invocation.getContext(RootContext.KEY_XID);
if (context != null) {
RootContext.bind(context);
}
return nextNode.onFilter(invocation).whenComplete((r, e) -> RootContext.unbind());
}
}
验证结果和总结
验证之前,需要给数据库准备数据:
insert into account_tbl(user_id, MONEY ) VALUES ('U100001', 2000);
insert into stock_tbl(commodity_code, count ) VALUES ('C00321', 20);
通过DEMO提供的测试界面,能够方便的测试事务提交和事务回滚两个场景。
执行事务的时候,可以通过数据库查询数据库数据是否始终处于一致的状态。
经过上述验证,说明通过使用兼容PostgreSQL的驱动,可以完成Seata官网例子的体验,事务功能都正常,因此这个方案是可行的。
但是也可以看到,Seata在官网并没有支持OpenGauss和GaussDB,那么在未来发展的过程中,可能会引入一些不兼容的问题。如果需要解决持续演进的问题,那么通过给Seata贡献代码,官网支持OpenGauss和GaussDB将是更好的方案。
- 点赞
- 收藏
- 关注作者
评论(0)