在springboot+dubbo+zookeeper+seata框架整合时,需要将seata的配置信息写入到zookeeper中,发现在zookeeper创建节点,写入的数据前几位一直是乱码,困扰了很久,最终完美解决。
所有的节点下面的值都有这个问题。
seata配置信息
transport.type=TCP
transport.server=NIO
transport.heartbeat=true
transport.enableClientBatchSendRequest=false
transport.threadFactory.bossThreadPrefix=NettyBoss
transport.threadFactory.workerThreadPrefix=NettyServerNIOWorker
transport.threadFactory.serverExecutorThreadPrefix=NettyServerBizHandler
transport.threadFactory.shareBossWorker=false
transport.threadFactory.clientSelectorThreadPrefix=NettyClientSelector
transport.threadFactory.clientSelectorThreadSize=1
transport.threadFactory.clientWorkerThreadPrefix=NettyClientWorkerThread
transport.threadFactory.bossThreadSize=1
transport.threadFactory.workerThreadSize=default
transport.shutdown.wait=3
service.vgroupMapping.doushanglai-service_tx_group=default
service.default.grouplist=127.0.0.1:8091
service.enableDegrade=false
service.disableGlobalTransaction=false
client.rm.asyncCommitBufferLimit=10000
client.rm.lock.retryInterval=10
client.rm.lock.retryTimes=30
client.rm.lock.retryPolicyBranchRollbackOnConflict=true
client.rm.reportRetryCount=5
client.rm.tableMetaCheckEnable=false
client.rm.sqlParserType=druid
client.rm.reportSuccessEnable=false
client.rm.sagaBranchRegisterEnable=false
client.tm.commitRetryCount=5
client.tm.rollbackRetryCount=5
client.tm.degradeCheck=false
client.tm.degradeCheckAllowTimes=10
client.tm.degradeCheckPeriod=2000
store.mode=db
store.file.dir=file_store/data
store.file.maxBranchSessionSize=16384
store.file.maxGlobalSessionSize=512
store.file.fileWriteBufferCacheSize=16384
store.file.flushDiskMode=async
store.file.sessionReloadReadSize=100
store.db.datasource=hikari
store.db.dbType=mysql
store.db.driverClassName=com.mysql.jdbc.Driver
store.db.url=jdbc:mysql://localhost:3306/seata?useUnicode=true
store.db.user=root
store.db.password=123456
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
store.redis.host=127.0.0.1
store.redis.port=6379
store.redis.maxConn=10
store.redis.minConn=1
store.redis.database=0
store.redis.password=null
store.redis.queryLimit=100
server.recovery.committingRetryPeriod=1000
server.recovery.asynCommittingRetryPeriod=1000
server.recovery.rollbackingRetryPeriod=1000
server.recovery.timeoutRetryPeriod=1000
server.maxCommitRetryTimeout=-1
server.maxRollbackRetryTimeout=-1
server.rollbackRetryTimeoutUnlockEnable=false
client.undo.dataValidation=true
client.undo.logSerialization=jackson
client.undo.onlyCareUpdateColumns=true
server.undo.logSaveDays=7
server.undo.logDeletePeriod=86400000
client.undo.logTable=undo_log
client.log.exceptionRate=100
transport.serialization=seata
transport.compressor=none
metrics.enabled=false
metrics.registryType=compact
metrics.exporterList=prometheus
metrics.exporterPrometheusPort=9898
在zookeeper中创建节点和写入数据的方法
package com.xqc.seata;
import org.I0Itec.zkclient.ZkClient;
import org.apache.zookeeper.CreateMode;
import org.springframework.util.ResourceUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.Set;
public class SeataRegisterZookeeper {
private static volatile ZkClient zkClient;
public static void main(String[] args) {
if (zkClient == null) {
zkClient = new ZkClient("127.0.0.1:2181", 6000, 2000);
}
if (!zkClient.exists("/seata")) {
zkClient.createPersistent("/seata", true);
}
//获取key对应的value值
Properties properties = new Properties();
// 使用ClassLoader加载properties配置文件生成对应的输入流
// 使用properties对象加载输入流
try {
File file = ResourceUtils.getFile("classpath:seata-config.properties");
InputStream in = new FileInputStream(file);
properties.load(in);
Set<Object> keys = properties.keySet();//返回属性key的集合
for (Object key : keys) {
boolean b = putConfig(key.toString(),properties.getProperty(String.valueOf(key)));
System.out.println(key.toString() + "=" + properties.get(key));
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static boolean putConfig(final String dataId, final String content) {
Boolean flag = false;
String path = "/seata/" + dataId;
if (!zkClient.exists(path)) {
zkClient.create(path, content, CreateMode.PERSISTENT);
flag = true;
} else {
zkClient.writeData(path, content);
flag = true;
}
return flag;
}
}
用上面的方法写入数据一直乱码。
解决方法:
先创建序列化类
package com.xqc.seata;
import org.I0Itec.zkclient.exception.ZkMarshallingError;
import org.I0Itec.zkclient.serialize.ZkSerializer;
import java.nio.charset.Charset;
public class XqcZkSerializer implements ZkSerializer{
@Override
public byte[] serialize(Object object) throws ZkMarshallingError {
return ((String)object).getBytes(Charset.forName("UTF-8"));
}
@Override
public Object deserialize(byte[] bytes) throws ZkMarshallingError {
return new String(bytes, Charset.forName("UTF-8"));
}
}
在往zookeeper节点写入数据之前加上下面的代码。
执行完毕,再看写入的数据,已经没有乱码了