1,簡介
由于項目功能已經開發完成,但是某些功能牽扯到的分布式事務沒有處理,而在調研了一些分布式解決方案後,最終選擇了目前比較流行,且對現有業務代碼無侵入的seata。
本項目情況:
spring boot 2.0.9.RELEASE + sprong cloudFinchley.SR3 + nacos1.3.2作為注冊中心+ oracle12C
本次內建seata 1.4.0 : 需要單獨部署TC(seata-server服務)
為防止部分資源無法下載下傳,文末會附上相關下載下傳資源
2,seata服務端安裝
仔細官方文檔,很重要,能避免後期一些坑。
2.1 seata官方文檔路徑:https://seata.io/zh-cn/index.html
2.2 seata下載下傳路徑:http://seata.io/zh-cn/blog/download.html
2.3下載下傳好1.4.0壓縮
如果沒有logs檔案夾,則建立一個logs檔案夾,并在logs檔案夾裡建立一個seata_gc.log檔案
2.4打開目錄seata/cof在README-zh.md中有一些資源github下載下傳位址
2.5建立seata-server 資料庫
本項目隻有一個資料庫所有在該項目的資料庫裡建立一個使用者,作為seata的資料庫,使用者名叫seata
腳本:
CREATE TABLE global_table
(
xid VARCHAR2(128) NOT NULL,
transaction_id NUMBER(19),
status NUMBER(3) NOT NULL,
application_id VARCHAR2(32),
transaction_service_group VARCHAR2(32),
transaction_name VARCHAR2(128),
timeout NUMBER(10),
begin_time NUMBER(19),
application_data VARCHAR2(2000),
gmt_create TIMESTAMP(0),
gmt_modified TIMESTAMP(0),
PRIMARY KEY (xid)
);
CREATE INDEX idx_gmt_modified_status ON global_table (gmt_modified, status);
CREATE INDEX idx_transaction_id ON global_table (transaction_id);
-- the table to store BranchSession data
CREATE TABLE branch_table
(
branch_id NUMBER(19) NOT NULL,
xid VARCHAR2(128) NOT NULL,
transaction_id NUMBER(19),
resource_group_id VARCHAR2(32),
resource_id VARCHAR2(256),
branch_type VARCHAR2(8),
status NUMBER(3),
client_id VARCHAR2(64),
application_data VARCHAR2(2000),
gmt_create TIMESTAMP(6),
gmt_modified TIMESTAMP(6),
PRIMARY KEY (branch_id)
);
CREATE INDEX idx_xid ON branch_table (xid);
-- the table to store lock data
CREATE TABLE lock_table
(
row_key VARCHAR2(128) NOT NULL,
xid VARCHAR2(128),
transaction_id NUMBER(19),
branch_id NUMBER(19) NOT NULL,
resource_id VARCHAR2(256),
table_name VARCHAR2(32),
pk VARCHAR2(36),
gmt_create TIMESTAMP(0),
gmt_modified TIMESTAMP(0),
PRIMARY KEY (row_key)
);
CREATE INDEX idx_branch_id ON lock_table (branch_id);
2.6建立undo_log表
說明:該表在seata服務資料庫建立一張,在相關業務庫也都要建立,如果是多個業務庫,每個業務庫都要建立。
-- Create table
create table UNDO_LOG
(
id NUMBER(19) not null,
branch_id NUMBER(19) not null,
xid VARCHAR2(128) not null,
context VARCHAR2(128) not null,
rollback_info BLOB not null,
log_status NUMBER(10) not null,
log_created TIMESTAMP(0) not null,
log_modified TIMESTAMP(0) not null
);
comment on table UNDO_LOG
is 'AT transaction mode undo table';
2.7 更改seata服務相關配置檔案
2.7.1在根目錄seata下建立config.txt檔案
service.vgroupMapping.mjkf-agility-sys-manage_tx_group=default
service.vgroup_mapping.sys_tx_group=default
service.vgroup_mapping.mjkf-agility-sys-manage-htf-group=default
service.vgroupMapping.mjkf-agility-sys-manage-htf-group=default
service.vgroupMapping.sys_tx_group=default
service.vgroupMapping.sys_group=default
service.vgroupMapping.mjkf-agility-dbmodel_tx_group=default
service.vgroupMapping.mjkf-agility-code_tx_group=default
service.default.grouplist=10.1.5.98:8091
service.disableGlobalTransaction=false
store.mode=db
store.db.datasource=druid
store.db.dbType=oracle
store.db.driverClassName=oracle.jdbc.OracleDriver
store.db.url=jdbc:oracle:thin:@10.1.5.98:1521/bxpdb
store.db.user=seata
store.db.password=seata
store.db.minConn=5
store.db.maxConn=30
store.db.globalTable=global_table
store.db.branchTable=branch_table
store.db.queryLimit=100
store.db.lockTable=lock_table
store.db.maxWait=5000
以下是需要自行更改的内容,包含資料庫連接配接資訊,自行修改
2.7.2在seata/conf/檔案夾下增加nacos-config.sh 檔案 内容如下:
#!/usr/bin/env bash
# Copyright 1999-2019 Seata.io Group.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at、
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
while getopts ":h:p:g:t:u:w:" opt
do
case $opt in
h)
host=$OPTARG
;;
p)
port=$OPTARG
;;
g)
group=$OPTARG
;;
t)
tenant=$OPTARG
;;
u)
username=$OPTARG
;;
w)
password=$OPTARG
;;
?)
echo " USAGE OPTION: $0 [-h host] [-p port] [-g group] [-t tenant] [-u username] [-w password] "
exit 1
;;
esac
done
urlencode() {
for ((i=0; i < ${#1}; i++))
do
char="${1:$i:1}"
case $char in
[a-zA-Z0-9.~_-]) printf $char ;;
*) printf '%%%02X' "'$char" ;;
esac
done
}
if [[ -z ${host} ]]; then
host=localhost
fi
if [[ -z ${port} ]]; then
port=8848
fi
if [[ -z ${group} ]]; then
group="SEATA_GROUP"
fi
if [[ -z ${tenant} ]]; then
tenant=""
fi
if [[ -z ${username} ]]; then
username=""
fi
if [[ -z ${password} ]]; then
password=""
fi
nacosAddr=$host:$port
contentType="content-type:application/json;charset=UTF-8"
echo "set nacosAddr=$nacosAddr"
echo "set group=$group"
failCount=0
tempLog=$(mktemp -u)
function addConfig() {
curl -X POST -H "${contentType}" "http://$nacosAddr/nacos/v1/cs/configs?dataId=$(urlencode $1)&group=$group&content=$(urlencode $2)&tenant=$tenant&username=$username&password=$password" >"${tempLog}" 2>/dev/null
if [[ -z $(cat "${tempLog}") ]]; then
echo " Please check the cluster status. "
exit 1
fi
if [[ $(cat "${tempLog}") =~ "true" ]]; then
echo "Set $1=$2 successfully "
else
echo "Set $1=$2 failure "
(( failCount++ ))
fi
}
count=0
for line in $(cat $(dirname "$PWD")/config.txt | sed s/[[:space:]]//g); do
(( count++ ))
key=${line%%=*}
value=${line#*=}
addConfig "${key}" "${value}"
done
echo "========================================================================="
echo " Complete initialization parameters, total-count:$count , failure-count:$failCount "
echo "========================================================================="
if [[ ${failCount} -eq 0 ]]; then
echo " Init nacos config finished, please start seata-server. "
else
echo " init nacos config fail. "
fi
2.7.3更改seata/cong檔案夾下的registry.conf,修改兩處
1注冊中心類型及注冊中西配置
2,配置中心類型及相關參數
2.7.4修改項目目錄下的file.conf檔案
更改資料庫資訊,如有redis更改redis相關配置
2.8将fonfig.txt上傳至nacos
在seata/conf檔案夾下執行如下上傳指令:
sh nacos-config.sh -h 10.1.5.88 -p 8848 -g SEATA_GROUP -t 60e39b35-0229-4733-addf-fa9eedcd8e33 -u admin -w 123456
2.9 啟動seata服務,在seataa/bin 檔案夾下執行,windows的話執行.bat linux執行.sh檔案
如下表示啟動成功,可取nacos裡去檢視
至此TC(服務端)配置啟動完成
2.9用戶端配置(自己的服務)
2.9.1 引入依賴,
注意引入依賴這一步可能會有些模範,首先官網提供了依賴版本說明
https://seata.io/zh-cn/docs/ops/deploy-guide-beginner.html
可參考官網提供的版本配置方式。
可能我項目内spring boot cloud版本比較老所有幾番嘗試之後使用了如下配置:
主項目:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.0.4.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
子項目:
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>1.4.0</version>
</dependency>
2.9.2yml配置,增加如下配置
seata:
enabled: true
application-id: mjkf-agility-sys-manage-htf
tx-service-group: mjkf-agility-sys-manage-group
data-source-proxy-mode: AT
use-jdk-proxy: true
registry:
type: nacos
nacos:
application: seata-server
server-addr: 10.1.5.88:8848
username: admin
password: 123456
config:
type: nacos
nacos:
server-addr: 10.1.5.88:8848
group: SEATA_GROUP
username: admin
password: 123456
namespace: 60e39b35-0229-4733-addf-fa9eedcd8e33
#data-id: seata.properties
#namespace: 5342dc77-dbb7-4ac7-ad72-9f65b71b1e94
service:
vgroupMapping:
mjkf-agility-sys-manage-group: default
client:
rm:
report-success-enable: false
grouplist:
default: 10.1.5.98:8091
2.10,業務代碼增加配置
@GlobalTransactional(rollbackFor = Exception.class)
注意:完成上述工作後,因為fegin調用需要綁定XID的傳遞,以下附上綁定代碼
建立一個配置類
import feign.RequestInterceptor;
import feign.RequestTemplate;
import io.seata.core.context.RootContext;
import org.apache.commons.lang.StringUtils;
import org.apache.tomcat.util.collections.CaseInsensitiveKeyMap;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
/**
* @author htf
* @description
* @date 2021-7-12 10:56
*/
@Configuration
public class FeignSupportConfig implements RequestInterceptor {
/**
* 解決服務直接調用請求頭不傳遞的問題
* @param template
*/
@Override
public void apply(RequestTemplate template) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (attributes != null) {
HttpServletRequest request = attributes.getRequest();
Enumeration<String> headerNames = request.getHeaderNames();
if (headerNames != null) {
Map<String, Collection<String>> resolvedHeaders = new CaseInsensitiveKeyMap<>();
resolvedHeaders.putAll(template.headers());
while (headerNames.hasMoreElements()) {
String name = headerNames.nextElement();
if (!resolvedHeaders.containsKey(name)) {
String values = request.getHeader(name);
List<String> headers = new ArrayList<String>();
headers.addAll(Arrays.asList(values));
resolvedHeaders.put(name, headers);
}
}
template.headers(null);
template.headers(resolvedHeaders);
}
}
String xid = RootContext.getXID();
if (StringUtils.isNotBlank(xid)) {
template.header(RootContext.KEY_XID, xid);
}
}
}
然後再feigin調用server處添加此配置類就可以
至此用戶端也配置完成。 一定要自己檢視官方文檔,避免踩空
過程中可能出現問題:
因為本人已經踩過很多坑,給出的配置檔案基本上已經是更改過的,此前出現過的一些報錯資訊及解決記錄:
1,用戶端服務一緻起不起來 一緻報錯
Could not generate CGLIB subclass of class com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceWrapper:
Common causes of this problem include using a final class or a non-visible class;
nested exception is org.springframework.cglib.core.CodeGenerationException:
java.lang.reflect.InvocationTargetException-->null
解決:yml配置檔案增加use-jdk-proxy: true 解決
2,seata服務端已啟動,用戶端還是一直報錯:
no available service found in cluster ‘default’, please make sure registry config correct and keep your seata server running
或者
can not get cluster name in registry config 'service.vgroupMapping.my_test_tx_group', please make sure registry config correct
解決:注意在nacos的seata-server服務與 nacos的配置中心分組保持一緻,都使用SEATA_GROUP
這個分組是在配置檔案裡 registry.conf配置檔案裡
關于這個報錯 還需要注意:config.txt裡的service.vgroupMapping.mjkf-agility-sys-manage-group=default(注:mjkf-agility-sys-manage-group 為自定義)這個配置即為nacos裡的配置
與yml檔案裡的這兩處一定要保持一緻,否在會此錯誤。
-----------------------------------------------------------------------------------------
相關資源:
https://download.csdn.net/download/u010185947/20065800