在上一章中,我们安装了测试服务器的服务,安装了idea,创建项目并完成了maven相关项目的引用。
这一章我们将在nacos中创建基础服务模块各种配置,在创建之前,建议先在nginx中配置nacos以便我们可以在web中进行访问。
在配置基础服务模块前,先添加seata的配置
添加seata-server.properties配置
注意Group是SEATA_GROUP
transport.type=TCP
transport.server=NIO
transport.heartbeat=true
transport.enableTmClientBatchSendRequest=false
transport.enableRmClientBatchSendRequest=true
transport.enableTcServerBatchSendResponse=false
transport.rpcRmRequestTimeout=30000
transport.rpcTmRequestTimeout=30000
transport.rpcTcRequestTimeout=30000
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
transport.serialization=seata
transport.compressor=none
#Transaction routing rules configuration, only for the client
service.vgroupMapping.tx_user_group=default
service.vgroupMapping.tx_order_group=default
service.vgroupMapping.tx_marketing_group=default
service.vgroupMapping.tx_master_group=default
service.vgroupMapping.tx_delivery_group=default
service.vgroupMapping.tx_storage_group=default
#If you use a registry, you can ignore it
service.default.grouplist=xxx.com:28092
service.enableDegrade=false
service.disableGlobalTransaction=false
#Transaction rule configuration, only for the client
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=true
client.rm.tableMetaCheckerInterval=60000
client.rm.sqlParserType=druid
client.rm.reportSuccessEnable=false
client.rm.sagaBranchRegisterEnable=false
client.rm.sagaJsonParser=fastjson
client.rm.tccActionInterceptorOrder=-2147482648
client.tm.commitRetryCount=5
client.tm.rollbackRetryCount=5
client.tm.defaultGlobalTransactionTimeout=60000
client.tm.degradeCheck=false
client.tm.degradeCheckAllowTimes=10
client.tm.degradeCheckPeriod=2000
client.tm.interceptorOrder=-2147482648
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.undo.compress.enable=true
client.undo.compress.type=zip
client.undo.compress.threshold=64k
#For TCC transaction mode
tcc.fence.logTableName=tcc_fence_log
tcc.fence.cleanPeriod=1h
#Log rule configuration, for client and server
log.exceptionRate=100
#Transaction storage configuration, only for the server. The file, db, and redis configuration values are optional.
store.mode=db
store.lock.mode=db
store.session.mode=db
#These configurations are required if the `store mode` is `db`. If `store.mode,store.lock.mode,store.session.mode` are not equal to `db`, you can remove the configuration block.
store.db.datasource=druid
store.db.dbType=mysql
store.db.driverClassName=com.mysql.jdbc.Driver
store.db.url=jdbc:mysql://127.0.0.1:3333/seata?useUnicode=true&rewriteBatchedStatements=true
store.db.user=seata
store.db.password=xxxxx
store.db.minConn=5
store.db.maxConn=30
store.db.globalTable=global_table
store.db.branchTable=branch_table
store.db.distributedLockTable=distributed_lock
store.db.queryLimit=100
store.db.lockTable=lock_table
store.db.maxWait=5000
#Transaction rule configuration, only for the server
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
server.distributedLockExpireTime=10000
server.xaerNotaRetryTimeout=60000
server.session.branchAsyncQueueSize=5000
server.session.enableBranchAsyncRemove=false
server.enableParallelRequestHandle=false
#Metrics configuration, only for the server
metrics.enabled=false
metrics.registryType=compact
metrics.exporterList=prometheus
metrics.exporterPrometheusPort=9898
service.vgroupMapping,service.default.grouplist,store.db请根据您自身进行配置
修改服务器seata配置
vim seata dir/conf/application.yml
# 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.
server:
port: 7091
spring:
application:
name: seata-server
logging:
config: classpath:logback-spring.xml
file:
path: ${user.home}/logs/seata
extend:
logstash-appender:
destination: 127.0.0.1:4560
kafka-appender:
bootstrap-servers: 127.0.0.1:9092
topic: logback_to_logstash
console:
user:
username: xxxx
password: xxxx
seata:
config:
# support: nacos, consul, apollo, zk, etcd3
type: nacos #file
nacos:
# 替换成您自己的nacos配置
server-addr: localhost:18888
namespace: xxxxx-xx-xx-xx-xxxx
group: SEATA_GROUP
username: xxxx
password: xxxx
data-id: seata-server.properties
registry:
# support: nacos, eureka, redis, zk, consul, etcd3, sofa
type: nacos
nacos:
server-addr: localhost:18888
namespace: xxxx-xxx-xxx-xxxx
group: SEATA_GROUP
username: xxxx
password: xxxx
cluster: default
store:
# support: file 、 db 、 redis
mode: db
db:
datasource: druid
db-type: mysql
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3333/xxx?rewriteBatchedStatements=true&useUnicode=true
user: xxxx
password: xxxxxxxxxxxxxx
min-conn: 5
max-conn: 100
global-table: global_table
branch-table: branch_table
lock-table: lock_table
distributed-lock-table: distributed_lock
query-limit: 100
max-wait: 5000
# server:
# service-port: 28093 #If not configured, the default is '${server.port} + 1000'
security:
secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017
tokenValidityInMilliseconds: 1800000
ignore:
urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/api/v1/auth/login
配置文件中涉及IP、端口、用户名、密码等均替换成您自己的即可。
配置命名空间
在nacos中创建如图命名空间
创建multienty.yaml配置
创建multienty.yaml配置
spring:
main:
allow-bean-definition-overriding: true
cloud:
sentinel:
enabled: false
eager: true
transport:
dashboard: sentinel.xxx.cn:32465
flyway:
enabled: false
locations: classpath:db/migration
validate-on-migrate: true
clean-disabled: true
baseline-on-migrate: true
extensions:
location-prefix: classpath:db/migration/
datasource:
type: com.alibaba.druid.pool.DruidDataSource
dynamic:
strict: false
druid:
initialSize: 1
minIdle: 3
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 30000
validationQuery: select 'x'
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
# 打开PSCache,并且指定每个连接上PSCache的大小
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filters: config,stat,slf4j
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000;
# 合并多个DruidDataSource的监控数据
useGlobalDataSourceStat: true
kuta:
multi-tenant:
# 登录失败阈值
login-failure-threshold: 5
standalone-tenant-db-name-prefix: 'saas_sa_'
master-db-name: 'saas_master'
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
wechat:
third-party:
enabled: true
app-id: xxx
app-secret: xxx
message-verify-token: xxx
message-decrypt-key: xxx
auth-redirect-uri: https://merchant.xxx.com/#/wxAuthResult
required-private-infos:
- onLocationChange
algorithms:
resource-mapping:
cotenancy-tenant:
type: 'COTENANCY'
props:
use-standalone-database: false
divide-table-by-date: false
file-upload-strategy: LOCAL
enterprise-tenant:
type: 'ENTERPRISE'
props:
use-standalone-database: true
divide-table-by-date: false
file-upload-strategy: OSS
flagship-tenant:
type: 'FLAGSHIP'
props:
use-standalone-database: true
divide-table-by-date: false
file-upload-strategy: OBS
mybatis-plus:
global-config:
banner: true
db-config:
# 已删除
logic-delete-value: true
#未删除
logic-not-delete-value: false
type-aliases-package: org.example.saas.core.pojo;com.chia.multienty.core.pojo
mapperLocations: classpath*:mapper/**/*.xml
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
创建master模块配置
saasdemo-master-dev.yml
spring:
shardingSphere:
# master不开启分片
enabled: false
datasource:
type: com.alibaba.druid.pool.DruidDataSource
dynamic:
primary: ds_master
datasource:
ds_master:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://xxx.com:3333/xxxx?autoReconnect=true&useUnicode=true&allowMultiQueries=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
username: xxxx
password: xxxx
ds_root:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://kutashop.cn:3333/mysql?autoReconnect=true&useUnicode=true&allowMultiQueries=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
username: root
password: xxxx
kuta:
multi-tenant:
# 开启后此应用将可提供multienty-core中提供的基础服务
base-module-enabled: true
domain: master.xxx.com
security:
auth:
header: X-TOKEN
token-prefix: ORDER
base64-secret: 5LmQ6IGa5oxX5piv5LiA5Liq5aW957O757uf56FK5aW957O757uf6K+95sOo5oSP5LiN6KaB5Zyo5LiK6Z2i5Y+R5biD6L+d5rOV5L+h5oGv6L+Z5qC3566h55CG5ZGY5Lmf5LiN5aW95aSE55CG55qE
# 令牌持有时间(秒)
token-holding-time: 86400
# 客户持有令牌时间,-1永久
customer-token-time: 86400
# 续期时长
renew-time: 86400
# 是否支持多点登陆
multipoint-login-enabled: true
ignore-paths:
- /file/upload
rsa:
# 请根据自身情况配置
private-key: xxx
public-key: xxx==
file:
# 大写
storage-mode: LOCAL
custom:
custom-file-upload-service-impl-class: org.example.saas.core.strategy.file.impl.QNYFileUploadServiceImpl
local:
path-prefix: C:\projects\multi-tenant\store
url-prefix: https://${spring.kuta.multi-tenant.domain}/local/
idea中创建master模块
master模块pom配置
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.example</groupId>
<artifactId>SaasDemo</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>saasdemo-master</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>saasdemo-core</artifactId>
</dependency>
<dependency>
<groupId>com.chia</groupId>
<artifactId>multienty-core-mysql-resource</artifactId>
<version>${chia.multienty.verion}</version>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<jvmArguments>-Dfile.encoding=UTF-8</jvmArguments>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
创建配置和目录
注意:db.migration.master是三层目录,并非同一级目录
application.yml
spring:
profiles:
active: dev
bootstrap.yml
server:
port: 8879
spring:
application:
name: saasdemo-master
cloud:
nacos:
discovery:
server-addr: nacos.xxx.com:18848
namespace: xxxx-xxx-xxx-xxx
username: xxxx
password: xxxx
config:
server-addr: nacos.xxx.cn:18848
namespace: xxxx-xxx-xxx-xxx
username: xxx
password: xxxx
file-extension: yml
extension-configs[0]:
data-id: multienty.yml
group: DEFAULT_GROUP
refresh: true
extension-configs[1]:
data-id: redis.yml
group: DEFAULT_GROUP
refresh: true
extension-configs[2]:
data-id: rabbitmq.yml
group: DEFAULT_GROUP
refresh: true
seata:
enabled: true
application-id: seata-server
# 客户端和服务端在同一个事务组; Seata 事务组编号,用于 TC 集群名, 一定要和 config.tx(nacos) 中配置的相同
tx-service-group: tx_master_group
# 自动数据源代理
enable-auto-data-source-proxy: false
# 数据源代理模式(分布式事务方案)
data-source-proxy-mode: AT
service:
vgroup-mapping:
tx_master_group: default
config:
# support: nacos, consul, apollo, zk, etcd3, file
type: nacos
nacos:
server-addr: nacos.xxx.com:18848
namespace: xxxx-xxx-xxx-xxxx
group: SEATA_GROUP
username: xxxx
password: xxxxxx
data-id: seata-server.properties
cluster: default
registry:
# support: nacos, eureka, redis, zk, consul, etcd3, sofa
type: nacos
nacos:
server-addr: nacos.xxxx.cn:18848
namespace: xxxxx-xxx-xxx-xxxx
group: SEATA_GROUP
username: xxxx
password: xxxx
# 默认TC集群名
cluster: default
# 服务名,与服务端中registry.conf配置要一致
application: seata-server
context-path:
dubbo:
enabled: true
metadata-report:
address: nacos://xxxx.com:18848?username=${dubbo.metadata-report.username}&password=${dubbo.metadata-report.password}
username: xxxx
password: xxxxx
parameters:
namespace: 273e34a2-bc14-41bd-ac55-b8ab8ba27e4a
retry-times: 30 #重试次数,默认100
cycle-report: false #关闭定时刷新
application:
name: master-provider
# 禁用QOS同一台机器可能会有端口冲突现象
qos-enable: false
qos-accept-foreign-ip: false
service-discovery:
migration: FORCE_APPLICATION # FORCE_APPLICATION,只消费应用级地址,如无地址则报错,单订阅 3.x 地址
protocol:
name: dubbo
port: -1
scan:
base-packages: org.example.saas.master.dubbo.service.impl,com.chia.multienty.core.dubbo.service.impl
cloud:
subscribed-services: saasdemo-user #, kuta-order, kuta-delivery, kuta-marketing, kuta-storage
registry:
address: nacos://xxxx.com:xxxx?username=${dubbo.metadata-report.username}&password=${dubbo.metadata-report.password}
parameters:
namespace: 273e34a2-bc14-41bd-ac55-b8ab8ba27e4a
consumer:
check: false
创建springboot应用入口
@SpringBootApplication
@EnableDiscoveryClient
@ComponentScan(value = {
"com.chia.multienty.core",
"org.example.saas.core",
"org.example.saas.master",
})
@EnableDubbo
@MapperScan(value={"com.chia.multienty.core.mapper","org.example.saas.core.mapper"})
public class MasterApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(MasterApplication.class, args);
}
}