Spring Cloud Alibaba组件:
各个组件之间版本对应关系:https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E
动态配置服务
服务发现与管理
动态DNS服务
nacos服务端程序 Releases · alibaba/nacos · GitHub ,nacos-server-x.x.x.zip
服务端程序分为单机模式和集群模式
单机模式(stanalone)启动:
解压压缩包内的bin目录 cmd命令运行 startup.cmd -m standalone即可以单机模式运行,使用内置的数据库。若要使用外置的数据库修改conf目录下的application.properties文件,
MySQL数据库创建上述application.properties配置文件中的nacos数据库,导入conf文件夹下的nacos-mysql.sql。
启动后,127.0.0.1:8848/nacos 服务端默认登录账号和密码均为nacos。
集群模式(cluster)启动:
修改cluster.conf配置集群IP
127.0.0.1:8848
127.0.0.1:8850
127.0.0.1:8852
将nacos文件夹复制几份(模拟集群),分别修改application.properties配置文件中的server.port端口为上述配置的端口,然后分别启动。
注意:nacos集群模式连续端口启动失败是因为nacos2.0之后增加gRPC通信方式,在占用主端口server.port的基础上,还会使用两个偏移量端口,偏移量固定,主端口连续会引起冲突。
startup.cmd 默认是集群模式,启动即可
①创建SpringBoot项目,导入Spring Cloud Alibaba Nacos Config 和 Discovery依赖
②resource目录下创建bootstrap.properties配置文件,添加配置信息
spring.cloud.nacos.config.server-addr=127.0.0.1:8848,127.0.0.1:8850,127.0.0.1:8852 #监听配置
spring.cloud.nacos.config.namespace=pulic
#注意:命名空间除了public,其它的命名空间必须写创建时生成的id值,例如eda318e4-953a-43ba-83b9-75ae354fc06e
spring.cloud.nacos.config.group=DEFAULT_GROUP #使用默认分组
spring.cloud.nacos.config.name=person.properties #使用nacos创建的配置文件
#group和name填写名称即可
#nacos多配置文件
#服务地址和命名空间没有不同,区别在于分组和配置名称
spring.cloud.nacos.config.extension-configs[0].group=HELLO_DEV
spring.cloud.nacos.config.extension-configs[0].data-id=hello.properties
spring.cloud.nacos.config.extension-configs[0].refresh=true
spring.cloud.nacos.config.extension-configs[1].group=DEFAULT_GROUP
spring.cloud.nacos.config.extension-configs[1].data-id=person.properties
spring.cloud.nacos.config.extension-configs[1].refresh=true
上述的配置信息都要与nacos文件夹中conf目录下application.properties、cluster.conf以及nacos配置中心中的信息一致。
controller层添加方法返回配置值
@RestController
@RefreshScope
@RequestMapping("/son2")
public class TestController {
@Value("${name}")
private String name;
@RequestMapping("/name")
public String name(){
return name;
}
}
访问localhost:${server.port}/son2/name 即可看到效果,注意需要添加@RefreshScope注解开启动态刷新,否则在nacos配置中心修改配置文件不会看到效果。
namespace - group - dataId
命名空间(namespace):dev、test、prod等,指定命名空间spring.cloud.nacos.config.namespace=uuid,通常用作环境隔离。
分组(group):指定分组spring.cloud.nacos.config.group=xxx,通常用作微服务隔离。
配置(dataId):指定配置文件spring.cloud.nacos.config.config.name=xxx
配置文件命名规范 ${prefix}-${spring.profiles.active}.${file-extension}
prefix默认是spring.application.name的值,修改可通过spring.cloud.nacos.config.prefix
spring.profiles.active是当前环境对应的profile
file-extension是配置内容的数据格式,支持properties和yaml类型
spring.profiles.active=dev
spring.application.name=son2
spring.cloud.nacos.config.prefix=${spring.application.name}
spring.cloud.nacos.config.file-extension=properties
此时nacos配置中心创建文件applicaitonName-profile.properties即可。
依赖添加spring-cloud-starter-alibaba-nacos-discovery。
配置文件添加如下信息:
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848,127.0.0.1:8850,127.0.0.1:8852
spring.cloud.nacos.discovery.cluster-name=JAVAHELLO #集群名称
spring.cloud.nacos.discovery.service=${spring.application.name} #服务名可不写,默认是应用名称
#(servicename-clustername)服务名和集群名相同,则对应有几个实例
Sentinel是面向分布式服务架构的高可用流量防护组件,主要以流量为切入点,从限流整形、熔断降级、系统负载保护、热点防护等多个维度来保护服务的稳定性。
https://github.com/alibaba/Sentinel/wiki/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8
下载控制台jar包:https://github.com/alibaba/Sentinel/releases
启动控制台程序(需要java环境):java -Dserver.port=18008 sentinel-dashboard-1.8.0.jar
登录:localhost:18008 默认账号密码都是sentinel
引入依赖 spring-cloud-starter-alibaba-sentinel(关键组件)
定义和使用限流规则,第一种:代码侵入式对资源埋点①try-catch SphU ②if-else SphO,第二种:使用注解@SentinelResource注解定义资源并配置blockHandler和fallback函数来进行限流之后的处理。
硬编码定义限流规则:
@PostConstruct //用来修饰一个非静态void方法,会在服务器加载Servlet的时候运行,并且只会被执行一次
public void initFlowRules(){
List rules = new ArrayList<>(); //定义限流规则集合
FlowRule rule = new FlowRule(); //定义限流规则
rule.setResource("helloworld"); //定义限流资源
rule.setGrade(RuleConstant.FLOW_GRADE_QPS); //定义限流规则类型
rule.setCount(2); //定义QPS阈值,每秒最多通过的请求个数
rules.add(rule); //添加规则到集合
FlowRuleManager.loadRules(rules); //加载规则集合
}
①抛出异常try-catch方式使用:
@RequestMapping("/helloworld2")
public String helloworld2(){
try(Entry entry = SphU.entry("helloworld2")){
//entry("资源名")
return "helloworld2"+System.currentTimeMillis();
}catch(BlockException ex){
return "系统繁忙,请稍后再试!";
}
}
②注解@SentinelResource方式使用:
@RequestMapping("/helloworld")
@SentinelResource(value = "helloworld",blockHandler = "failBlockHandler")
public String helloworld(){
return "helloWorld"+System.currentTimeMillis();
}
public String failBlockHandler(BlockException be){
return "系统繁忙,请稍后再试!";
}
引入依赖:sentinel-transport-simple-http(接入Dashboard可视化管理组件)、sentinel-datasource-nacos(配置持久化nacos组件)
启动控制台程序,配置文件添加配置信息
spring.cloud.sentinel.transport.dashboard=localhost:18008
spring.cloud.sentinel.eager=true
spring.cloud.sentinel.transport.client-ip=localhost
开源的分布式事务解决方案,提供AT、TCC、SAGA和XA事务模式。
AT模式:均由Seata完成,无侵入式方案0成本
TCC模式:(try-confirm-cancel) 高性能
Saga模式:每个参与者都有正向和反向服务,适合长事务
XA模式:数据库提供,事务粒度大,强一致性,性能差
①下载运行seata server,下载中心
seata-server conf目录下的配置文件file.conf和registry.conf,可指定文件或数据库存储事务信息。
②seata-server指定文件存储
修改file.conf store{ mode="file" ... },修改registry{ type="file" file{name="file.conf"} } config{ type="file" file{name="file.conf"}}。使用文件存储,seata-server的file.conf配置文件中需要添加service块,service块样例:
service{
vgroupMapping.hhhh = "default"
default.grouplist = "127.0.0.1:8091"
enableDegrade = false
disable = false
max.commit.retry.timeout = "-1"
max.commit.retry.timeout = "-1"
}
②seata-server指定数据库存储
修改file.conf配置文件 store{ mode="db" db{...} },配置对应的数据库信息和用到的表,添加global_table和branch_table和loca_table表。建表SQL文件:seata/mysql.sql at develop · seata/seata · GitHub
③使用nacos作为服务注册中心和配置中心(nacos要提前添加命名空间,如下文提到的namespace="f1ac4..." 就是自己创建的命名空间)
第一步:修改registry.conf配置文件
#注册中心
registry{
type="nacos"
nacos{
application="seata-server" #注册到nacos的服务名
serverAddr="127.0.0.1:8848" #nacos注册中心地址
group="SEATA_SERVER_GROUP"#注册到nacos的分组名
namespace="f1ac4fb0-2ff2-4d96-a5b8-4411b13b3e44" #注册到指定命名空间,""代表public
cluster="default" #集群名称
}
}
#配置中心
config{
type="nacos"
nacos{
serverAddr="127.0.0.1:8848" #从nacos获取配置
namespace="f1ac4fb0-2ff2-4d96-a5b8-4411b13b3e44"
group="SEATA_SERVER_GROUP"
}
}
第二步:下载配置文件和配置脚本放置指定位置并修改
配置脚本(放置在conf目录里):https://github.com/seata/seata/blob/develop/script/config-center/nacos/nacos-config.sh
配置文件(放置在seata-server目录里):https://github.com/seata/seata/blob/develop/script/config-center/config.txt
配置文件中区分开了服务端配置和客户端配置,因此根据提示将配置文件划分成服务端配置和客户端配置(config-server.txt 和 config-client.txt)。配置文件中需要修改的地方有:
同理,将脚本也复制分为两个脚本(nacos-config-server.sh 和 nacos-config-client.sh)。脚本需要修改成对应的执行的配置文件名称,如图
第三步:启动nacos,执行脚本向nacos添加配置信息
windows端执行需要安装git,在脚本目录鼠标右键git bash here,执行命令 sh xxx.sh即可。若懒得指定参数可在脚本中直接修改地址、端口、分组、命名空间,如图。
启动服务端,执行bin目录下的seata-server.bat。
至此,seata服务端的配置已经完毕,访问nacos应该在对应的命名空间下能看到注册上去的服务名seata-server
①引入依赖(Spring Cloud环境),参与事务的每个项目(微服务 RM)都要添加seata配置信息
com.alibaba.cloud
spring-cloud-starter-alibaba-seata
2021.1
io.seata
seata-spring-boot-starter
②application.properties配置文件内容
#微服务相关
spring.application.name=seata-order
server.port=18102
#数据库连接相关
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=l1018
spring.datasource.url=jdbc:mysql://localhost:3306/seata?useUnicode=true&characterEncoding=utf8
#将本项目作为服务独立注册到nacos上
spring.cloud.nacos.discovery.enabled=true
spring.cloud.nacos.discovery.namespace=f1ac4fb0-2ff2-4d96-a5b8-4411b13b3e44
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
spring.cloud.nacos.discovery.group=SEATA_CLIENT_GROUP
spring.cloud.nacos.discovery.cluster-name=default
#本服务分组与映射集群
seata.tx-service-group=hhhh
seata.service.vgroup-mapping.hhhh=default
#将本服务注册到服务端(TC)
seata.registry.type=nacos
seata.registry.nacos.application=seata-server
seata.registry.nacos.server-addr=127.0.0.1:8848
seata.registry.nacos.namespace=f1ac4fb0-2ff2-4d96-a5b8-4411b13b3e44
seata.registry.nacos.group=SEATA_SERVER_GROUP
seata.registry.nacos.cluster=default
#本服务的seata配置从nacos上拿取
seata.config.nacos.server-addr=127.0.0.1:8848
seata.config.nacos.namespace=f1ac4fb0-2ff2-4d96-a5b8-4411b13b3e44
seata.config.nacos.group=SEATA_CLIENT_GROUP
#本服务seata配置
seata.service.disable-global-transaction=false
seata.service.enable-degrade=false
注意服务分组和映射集群要跟上文添加到nacos的配置相同,或使用文件模式要跟file.conf配置文件中的service块相对应。
使用注解@GlobalTrancational,标注在事务发起方法(TM)上即可。
@RestController
@RequestMapping("/shop")
public class BuyController {
@Autowired
private AccountFeignService accountFeignService;
@Resource
private OrderFeignService orderFeignService;
@RequestMapping("/buy")
@GlobalTransactional
public String buy(String id,String payMoney) throws Exception {
int userid = Integer.valueOf(id);
BigDecimal money = BigDecimal.valueOf(Double.valueOf(payMoney));
int i2 = orderFeignService.createOrder(userid,money); //生成订单
int i1 = accountFeignService.decrease(userid,money); //扣余额
int i = 1;
if(i==1) {throw new Exception("custom");} //模拟异常
return "success";
}
}
一、使用spring-cloud-starter-alibaab-nacos-discovery依赖包会添加netfliex-ribbon依赖导致@Feign注解指定url失效,若要指定url请求使用nacos-client依赖。
二、全局事务出现异常,上文使用样例代码中orderFeignService中会向数据库中添加一条数据,按理说会回滚撤销添加的内容,但是没有回滚。原因是insert语句中指定了自增主键属性值为0。
@Mapper
public interface SorderMapper extends BaseMapper {
@Insert("insert into sorder(`id`,`userId`,`payMoney`) values (0,#{userId},#{payMoney})")
public int addOrder(@Param("userId") int userId, @Param("payMoney")BigDecimal payMoney);
}
代码中sql语句中的id字段是自增主键,指定了其值为0,而这个字段不需要为其赋值。解决方法是修改sql语句,insert into sorder(`userId`,`payMoney`) values (#{userId},#{payMoney})。只能说代码写的并不规范,用起来仅仅是懂操作不懂原理。
三、nacos非常容易坏,莫名奇妙就启动不了,可以多复制几份备用。简单使用也只是修改一下配置文件的事。
主要用途:限流削峰,异步解耦,数据收集
安装与环境搭建:下载rocketmq (http://rocketmq.apache.org),学习使用修改bin目录下的runserver.sh 和 runbroker.sh文件,将-Xms -Xmx -Xmn参数值改小。
快速启动:Quick Start - Apache RocketMQ
云服务器单机部署:broker.conf需要添加nameserver和brokerIP配置,启动时指定使用该配置文件。nohup sh bin/mqbroker -c conf/broker.conf &
brokerClusterName = DefaultCluster
brokerName = broker-a
brokerId = 0
deleteWhen = 04
fileReservedTime = 48
brokerRole = ASYNC_MASTER
flushDiskType = ASYNC_FLUSH
namesrvAddr = x.x.x.x:9876
brokerIP1 = x.x.x.x
模拟集群环境:修改conf目录下的broker配置文件
brokerClusterName=DefaultCluster #指定整个broker集群的名称(RocketMQ集群名称)
brokerName=broker-a #指定master-salve集群名称,一个RocketMQ集群可以包含多个master-slave集群
brokerId=0 #指定master的borkerId,非0即为slave
deleteWhen=04 #指定过期消息的删除时间
fileReservedTime=48 #指定未更新消息删除时间48小时
brokerRole=ASYNC_MASTER #指定异步master
flushDiskType=ASYNC_FLUSH #指定异步刷盘
namesrvAddr=x.x.x.x:9876;x.x.x.x:9876 #指定nameserver地址
#以下时slave需要添加的配置
listenPort=11911 #指定Broker对外提供服务的端口,即Broker与producer和consumer通信的端口,由于master已经占用默认10911端口
#修改slave存储路径
storePathRootDir=~/store-s
storePathCommitLog=~/store-s/commitlog
storePathConsumeQueue=~/store-s/comsumequeue
storePathIndex=~/store-s/index
storeCheckpoint=~/store-s/checkpoint
abortFile=~/store-s/abort
启动Broker的master和slave:
nohup sh bin/mqbroker -c conf/2m-2s-async/broker-x.properties &
nohup sh bin/mqbroker -c conf/2m-2s-async/borker-x1-s.properties &
快速应用:
Simple Message Example - Apache RocketMQ
本文记录Spring Cloud Alibaba各个组件快速搭建上手的学习过程,仅供参考。简单学习并没有深入应用,难免出现错误,如果有误导的地方请批评指正。