一、简介
作为微服务的解决方案之一的Spring cloud Alibaba拥有众多优秀的开源框架,那么我们就使用这么框架搭建一个项目,并以此来研究一下这些优秀框架的源码。所使用到的组件如下:
1、Nacos 服务注册与发现
2、Nacos 分布式配置中心
3、Sentinel 流量控制和服务降级
4、RocketMQ 消息驱动
5、Seate 分布式事务
6、Dubbo Rpc通信
7、Oss 对象存储
二、启动nacos服务
1、下载nacos源码:git clone https://github.com/alibaba/nacos.git
2、进入nacos文件夹,如果是windows的cmd终端则使用mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U编译;如果使用的PowerShell则使用mvn -Prelease-nacos '-Dmaven.test.skip=true' clean install -U编译。
3、编译完成后进入\distribution\target\nacos-server-2.0.4\nacos\bin文件夹下,使用startup.cmd -m standalone(windows下,非集群模式)命令启动
4、启动成功后,访问http://localhost:8848/nacos,用户名:nacos,密码:nacos
5、关闭可直接双击shutdown.cmd
ps:nacos的数据存储默认使用的是Derby文件类型的数据库,在使用时会存在一定的局限性。比如无法支持多用户同时操作,在数据量大、连接数多的情况下会产生大量的连接积压,所以生产环境下我们可以使用mysql代替。
(1)在\distribution\target\nacos-server-2.0.4\nacos\conf文件夹下存在nacos-mysql.sql文件,放到mysql中执行初始化
(2)修改application.properties文件,增加mysql的配置
spring.datasource.platform=mysql db.num=1 db.url.0=jdbc:mysql://localhost:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC db.user.0=root db.password.0=123456
6、创建命名空间
7、配置管理tab,切换到新建的命名空间,新建一个配置,备用
三、配置中心与服务注册
应用以来的jar包,使用windows启动,会有grpc的错误,nacos client单独使用1.4.2版本
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <dependency> <groupId>com.alibaba.nacos</groupId> <artifactId>nacos-client</artifactId> <version>1.4.2</version> </dependency>
在resources文件夹下创建bootstrap.yml文件,配置如下:
spring: application: name: console cloud: nacos: config: server-addr: 192.168.232.207:8848 file-extension: properties namespace: 370c5370-3012-424f-8cb9-ce93c695d241
在nacos控制台,配置文件中配置注册中心的信息
server.port=9100 spring.cloud.nacos.discovery.server-addr=192.168.232.207:8848 spring.cloud.nacos.discovery.namespace=370c5370-3012-424f-8cb9-ce93c695d241
四、Sentinel的限流降级
1、控制台
(1)从git上下载sentinel-dashboard,修改配置文件application.properties
#端口号 server.port=18885 csp.sentinel.dashboard.server=localhost:18885 project.name=sentinel-dashboard # 注册中心地址 sentinel.nacos.server-addr=127.0.0.1:8848 sentinel.nacos.namespace=370c5370-3012-424f-8cb9-ce93c695d241 sentinel.nacos.group-id=sentinel
(2)规则持久化到nacos,找到pom文件的sentinel-datasource-nacos,删掉scope启动nacos
(3)修改源码,增加实例化逻辑,网上有很多的案例实践,我的已放到gitee上,地址:https://gitee.com/sglx666/sentinel-dashboard.git
2、客户端
(1)添加sentinel的jar包
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-nacos</artifactId> </dependency> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-parameter-flow-control</artifactId> </dependency>
(2)以限流为例,配置如下:
spring.cloud.sentinel.transport.dashboard=127.0.0.1:18885 nacos.address=127.0.0.1:8848 spring.cloud.sentinel.datasource.flow.nacos.server-addr=${nacos.address} spring.cloud.sentinel.datasource.flow.nacos.namespace=370c5370-3012-424f-8cb9-ce93c695d241 spring.cloud.sentinel.datasource.flow.nacos.username=nacos spring.cloud.sentinel.datasource.flow.nacos.password=nacos spring.cloud.sentinel.datasource.flow.nacos.data-id=${spring.application.name}-sentinel-flow spring.cloud.sentinel.datasource.flow.nacos.group-id=sentinel spring.cloud.sentinel.datasource.flow.nacos.data-type=json spring.cloud.sentinel.datasource.flow.nacos.rule-type=flow
五、分布式事务Seata
服务端
1、下载地址https://seata.io/zh-cn/blog/download.html
2、进入到conf目录下,修改file.conf、registry.conf
3、进入到bin目录下,点击seata-server.bat启动
4、服务端配置seataServer.properties
####################公共配置######################## #client和server通信编解码方式 seata(ByteBuf)、protobuf、kryo、hession、fst,默认seata transport.serialization=seata #client和server通信数据压缩方式 none、gzip,默认none transport.compressor=none #client和server通信心跳检测开关 transport.heartbeat=true #默认file,支持file 、nacos 、eureka、redis、zk、consul、etcd3、sofa、custom registry.type=nacos #默认file,支持file、nacos 、apollo、zk、consul、etcd3、custom config.type=nacos transport.type=TCP transport.server=NIO 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 ###################server端相关配置########################### #undo保留天数 默认7天,log_status=1(附录3)和未正常清理的undo server.undo.logSaveDays=7 #undo清理线程间隔时间 默认86400000,单位毫秒 server.undo.logDeletePeriod=86400000 #单位ms,s,m,h,d,对应毫秒,秒,分,小时,天,默认毫秒。默认值-1表示无限重试。 #公式: timeout>=now-globalTransactionBeginTime,true表示超时则不再重试 #注: 达到超时时间后将不会做任何重试,有数据不一致风险,除非业务自行可校准数据,否者慎用 server.maxCommitRetryTimeout=-1 #二阶段回滚重试超时时长 同commit server.maxRollbackRetryTimeout=-1 #二阶段提交未完成状态全局事务重试提交线程间隔时间 默认1000,单位毫秒 server.recovery.committingRetryPeriod=1000 #二阶段异步提交状态重试提交线程间隔时间 默认1000,单位毫秒 server.recovery.asynCommittingRetryPeriod=1000 #二阶段回滚状态重试回滚线程间隔时间 默认1000,单位毫秒 server.recovery.rollbackingRetryPeriod=1000 #超时状态检测重试线程间隔时间 默认1000,单位毫秒,检测出超时将全局事务置入回滚会话管理器 server.recovery.timeoutRetryPeriod=1000 server.rollbackRetryTimeoutUnlockEnable=false # 存储模式为db store.mode=db #store.lock.mode=db #store.session.mode=db #store.publicKey= #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 # db模式数据源类型druid、hikari store.db.datasource=druid store.db.dbType=mysql store.db.driverClassName=com.mysql.jdbc.Driver store.db.url=jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true&characterEncoding=UTF-8&rewriteBatchedStatements=true store.db.user=root store.db.password=hhh123 #初始连接数 store.db.minConn=1 #最大连接数 store.db.maxConn=10 #db模式获取连接时最大等待时间 store.db.maxWait=5000 #db模式全局事务表名 store.db.globalTable=global_table #db模式分支事务表名 store.db.branchTable=branch_table #db模式全局锁表名 store.db.lockTable=lock_table #db模式查询全局事务一次的最大条数 store.db.queryLimit=50 #store.redis.mode=single #store.redis.single.host=127.0.0.1 #store.redis.single.port=6379 #store.redis.sentinel.masterName= #store.redis.sentinel.sentinelHosts= #store.redis.maxConn=10 #store.redis.minConn=1 #store.redis.maxTotal=100 #tore.redis.database=0 #store.redis.password= #store.redis.queryLimit=100 #是否启用Metrics 默认false关闭,在False状态下,所有与Metrics相关的组件将不会被初始化,使得性能损耗最低 metrics.enabled=false #指标注册器类型 默认为内置的compact(简易)实现 metrics.registryType=compact #指标结果Measurement数据输出器列表 默认prometheus metrics.exporterList=prometheus #prometheus输出器Client端口号 metrics.exporterPrometheusPort=9898 #####################client端配置################### #是否开启spring-boot自动装配 seata.enabled=true #是否开启数据源自动代理 seata.enableAutoDataSourceProxy=true #是否使用JDK代理作为数据源自动代理的实现方式,默认false,采用CGLIB作为数据源自动代理的实现方式 seata.useJdkProxy=false #客户端事务消息请求是否批量合并发送 默认true,false单条发送 transport.enableClientBatchSendRequest=false #日志异常输出概率 默认100,目前用于undo回滚失败时异常堆栈输出,百分之一的概率输出,回滚失败基本是脏数据,无需输出堆栈占用硬盘空间 client.log.exceptionRate=100 #事务群组 service.vgroupMapping.sale_tx_group=default #service.vgroupMapping.order_tx_group=default #service.vgroupMapping.line_tx_group=default #TC服务列表 仅注册中心为file时使用 service.default.grouplist=192.168.1.204:8901 #全局事务开关 默认false。false为开启,true为关闭 service.disableGlobalTransaction=false #降级开关 service.enableDegrade=false #默认false。业务侧根据连续错误数自动降级不走seata事务 client.tm.degradeCheck=false #升降级达标阈值 默认10 client.tm.degradeCheckAllowTimes=10 #服务自检周期 默认2000,单位ms.每2秒进行一次服务自检,来决定 client.tm.degradeCheckPeriod=2000 #一阶段全局提交结果上报TC重试次数 默认1次,建议大于1 client.tm.commitRetryCount=5 #一阶段全局回滚结果上报TC重试次数 默认1次,建议大于1 client.tm.rollbackRetryCount=5 client.tm.defaultGlobalTransactionTimeout=60000 #是否上报一阶段成功 true用于保持分支事务生命周期记录完整,false可提高不少性能 client.rm.reportSuccessEnable=false #异步提交缓存队列长度 默认10000。 二阶段提交成功,RM异步清理undo队列 client.rm.asyncCommitBufferLimit=10000 #校验或占用全局锁重试间隔 默认10,单位毫秒 client.rm.lock.retryInterval=10 #校验或占用全局锁重试次数 默认30 client.rm.lock.retryTimes=30 #分支事务与其它全局回滚事务冲突时锁策略 默认true,优先释放本地锁让回滚成功 client.rm.lock.retryPolicyBranchRollbackOnConflict=true #一阶段结果上报TC重试次数 默认5次 client.rm.reportRetryCount=5 #自动刷新缓存中的表结构 默认false client.rm.tableMetaCheckEnable=false client.rm.tableMetaCheckerInterval=60000 #sql解析类型 默认druid,可选antlr client.rm.sqlParserType=druid client.rm.sagaBranchRegisterEnable=false #二阶段回滚镜像校验 默认true开启,false关闭 client.undo.dataValidation=true #undo序列化方式 默认jackson client.undo.logSerialization=jackson #自定义undo表名 默认undo_log client.undo.logTable=undo_log #只生成被更新列的镜像 默认true client.undo.onlyCareUpdateColumns=true client.undo.compress.enable=true client.undo.compress.type=zip client.undo.compress.threshold=64k log.exceptionRate=100
客户端
1、以spring cloud框架为例,添加jar包
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-seata</artifactId> <exclusions> <exclusion> <groupId>io.seata</groupId> <artifactId>seata-spring-boot-starter</artifactId> </exclusion> <exclusion> <groupId>io.seata</groupId> <artifactId>seata-all</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>io.seata</groupId> <artifactId>seata-spring-boot-starter</artifactId> <version>1.4.2</version> </dependency> <dependency> <groupId>io.seata</groupId> <artifactId>seata-all</artifactId> <version>1.4.2</version> </dependency>
2、使用@GlobalTransactional(rollbackFor = Exception.class)
3、 配置
# 开启seata seata.enabled=true seata.application-id=${spring.application.name} seata.tx-service-group=sale_tx_group seata.service.vgroup-mapping.sale_tx_group=default # 是否自动开启数据源代理 seata.enable-auto-data-source-proxy=true # 数据源代理模式,使用AT模式 seata.data-source-proxy-mode=AT # 校验或占用全局锁重试间隔,单位ms seata.client.rm.lock.retry-interval=10 # 校验或占用全局锁重试次数 seata.client.rm.lock.retry-times=30 # 分支事务与其它全局回滚事务冲突时锁策略,true,优先释放本地锁让回滚成功 seata.client.rm.lock.retry-policy-branch-rollback-on-conflict=true # 一阶段全局提交结果上报TC重试次数 seata.client.tm.commit-retry-count=5 # 一阶段全局回滚结果上报TC重试次数 seata.client.tm.rollback-retry-count=5 # 分布式事物超时时间 ms seata.client.tm.default-global-transaction-timeout=600000 # 降级开关,false 不打开 seata.client.tm.degrade-check=false seata.client.tm.degrade-check-period=2000 seata.client.tm.degrade-check-allow-times=10 # 全局事务开关 seata.service.disable-global-transaction=false seata.support.spring.datasource-autoproxy=true # 注册中心 seata.registry.type = nacos seata.registry.nacos.application = seata-server seata.registry.nacos.server-addr = ${spring.cloud.nacos.discovery.server-addr} seata.registry.nacos.namespace = ${spring.cloud.nacos.discovery.namespace} seata.registry.nacos.group = DEFAULT_GROUP #seata.registry.nacos.cluster = default # 配置中心 seata.config.type = nacos seata.config.nacos.server-addr = ${spring.cloud.nacos.discovery.server-addr} seata.config.nacos.group = DEFAULT_GROUP seata.config.nacos.dataId = seataServer.properties seata.config.nacos.namespace = 2d8ceb51-d8a3-405c-8cfd-22519d2da8fc # 日志留存天数 seata.log.exception-rate=100
参考连接:https://blog.csdn.net/fu_huo_1993/article/details/120504020