SpringCloud Nacos :服务发现与注册,配置管理
服务注册与发现 主模块依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 <properties> <project.build.sourceEncoding>UTF-8 </project.build.sourceEncoding> <maven.compiler.source>1.8 </maven.compiler.source> <maven.compiler.target>1.8 </maven.compiler.target> <spring-cloud.version>Hoxton.SR8</spring-cloud.version> <springboot.version>2.3 .2 .RELEASE</springboot.version> <springcloudalibaba.version>2.2 .5 .RELEASE</springcloudalibaba.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import </scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${springboot.version}</version> <type>pom</type> <scope>import </scope> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${springcloudalibaba.version}</version> <type>pom</type> <scope>import </scope> </dependency> </dependencies> </dependencyManagement>
==服务提供者==
依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 配置中心 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <!--服务注册与发现--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> </dependencies>
配置
1 2 3 4 5 6 7 8 9 10 11 12 server: port: 8082 spring: application: name: nacos-stock cloud: nacos: server-addr: 127.0 .0 .1 :8848 discovery: namespace: 793d1b0e-e601-4b41-bed1-7a8bc50768ab #指定命名空间 cluster-name: wang #集群名
主启动类
1 2 3 4 5 6 7 8 @SpringBootApplication @EnableDiscoveryClient public class NacosStockApplication { public static void main (String[] args) { SpringApplication.run(NacosStockApplication.class,args); } }
Controller
1 2 3 4 5 6 7 8 @RestController public class StockController { @RequestMapping("/stock/test") public String test (String info) { return "库存模块接收到的信息:" +info; } }
==服务消费者==
依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 配置中心 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <!--服务注册与发现--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!-- https: <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> <version>3.0 .3 </version> </dependency> </dependencies>
配置
1 2 3 4 5 6 7 8 9 10 11 12 13 server: port: 8081 spring: application: name: nacos-order #配置项目名称 cloud: nacos: server-addr: 127.0 .0 .1 :8848 #配置中心地址 discovery: namespace: 793d1b0e-e601-4b41-bed1-7a8bc50768ab #指定命名空间 相互调用的服务要在同一命名空间下 cluster-name: wang #集群名
主启动类
1 2 3 4 5 6 7 8 9 @SpringBootApplication @EnableDiscoveryClient @EnableFeignClients(basePackages = "com.wang.feign") public class NacosOrderApplication { public static void main (String[] args) { SpringApplication.run(NacosOrderApplication.class,args); } }
通过openfeign调用
1 2 3 4 5 6 7 @FeignClient("nacos-stock") public interface StockFeignService { @RequestMapping("/stock/test") String test (@RequestParam("info") String info) ; }
Controller
1 2 3 4 5 6 7 8 9 10 11 12 @RestController public class OrderController { @Autowired private StockFeignService stockFeignService; @RequestMapping("/order/test") public String test () { return stockFeignService.test("order" ); } }
配置管理 依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 配置中心 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> </dependencies>
配置
1 2 3 4 5 server: port: 8086 spring: profiles: active: info
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 spring.application.name =nacos-config-test spring.cloud.nacos.server-addr =127.0.0.1:8848,127.0.0.1:8850,127.0.0.1:8852 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.file-extension =properties spring.cloud.nacos.config.group =TEST_GROUP spring.cloud.nacos.config.namespace =793d1b0e-e601-4b41-bed1-7a8bc50768ab spring.cloud.nacos.config.extension-configs[0].data-id =mysql-common.properties spring.cloud.nacos.config.extension-configs[0].group =DEFAULT_GROUP spring.cloud.nacos.config.extension-configs[0].refresh =true spring.cloud.nacos.config.extension-configs[1].data-id =redis-common.properties spring.cloud.nacos.config.extension-configs[1].group =DEFAULT_GROUP spring.cloud.nacos.config.extension-configs[1].refresh =true spring.cloud.nacos.config.extension-configs[2].data-id =crm.properties spring.cloud.nacos.config.extension-configs[2].group =CRM_GROUP spring.cloud.nacos.config.extension-configs[2].refresh =true spring.cloud.nacos.config.extension-configs[3].data-id =oa-properties spring.cloud.nacos.config.extension-configs[3].group =OA_GROUP spring.cloud.nacos.config.extension-configs[3].refresh =true spring.cloud.nacos.config.extension-configs[4].data-id =nacos-config.properties spring.cloud.nacos.config.extension-configs[4].group =DEFAULT_GROUP spring.cloud.nacos.config.extension-configs[4].refresh =true users.name =wang users.age =10
主启动类
1 2 3 4 5 6 @SpringBootApplication public class NacosConfigApplication { public static void main (String[] args) { SpringApplication.run(NacosConfigApplication.class,args); } }
Controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 @RestController @RefreshScope public class NacosConfigController { @Value("${users.name}") private String name; @Value("${users.age}") private Integer age; @Value("${users.mysql.common}") private String mysql; @Value("${users.redis.common}") private String redis; @Value("${users.crm.config}") private String crm; @Value("${users.oa.config}") private String oa; @Value("${student.name}") private String sname; @GetMapping("/getConfigInfo") public String getConfigInfo () { return name+":" + age; } @GetMapping("/getCRMConfigInfo") public String getCRMConfigInfo () { return mysql+":" + redis+":" +crm+":" +oa; } @GetMapping("/getCRMConfigInfo1") public String getCRMConfigInfo1 () { return sname; } }
Nacos配置MySQL数据库 1.到Mysql中执行nacos-mysql.sql
2.application.properties中添加以下代码
1 2 3 4 5 spring.datasource.platform=mysql db.num=1 db.url.0 =jdbc:mysql: db.user=root db.password=123456
配置集群模式 默认是集群
单机 :standalone
配置端口号和本机ip地址
设置三个关联Nacos的端口号和ip地址
复制三个nacos,重复上面操作
Sentinel分布式系统的流量防卫兵 Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
导入依赖
1 2 3 4 5 <!--spring-cloud-alibaba-sentinel--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency>
编写配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 server: port: 8401 spring: application: name: nacos-stock4-sentinel cloud: nacos: discovery: server-addr: 127.0 .0 .1 :8848 #nacos服务注册中心地址 sentinel: transport: dashboard: 127.0 .0 .1 :8080 #sentinel地址 port: 8719 #默认8719 端口,假如被占用会自动从8719 开始依次加1 扫描,直到找到没有被占用的端口 management: endpoints: web: exposure: include: '*'
主启动类
1 2 3 4 5 6 7 @SpringBootApplication @EnableDiscoveryClient public class MainApp8401 { public static void main (String[] args) { SpringApplication.run(MainApp8401.class,args); } }
controller
1 2 3 4 5 6 7 8 9 10 11 12 @RestController public class FlowLimitController { @RequestMapping("/testA") public String testA () { return "--------------testA" ; } @RequestMapping("/testB") public String testB () { return "--------------testB" ; } }
实时监控
流量控制 QPS:每秒的响应请求数 快速失败 (RuleConstant.CONTROL_BEHAVIOR_DEFAULT
)方式是默认的流量控制方式 ,当QPS超过任意规则的阈值后,新的请求就会被立即拒绝,拒绝方式为抛出FlowException
。这种方式适用于对系统处理能力确切已知的情况下,比如通过压测确定了系统的准确水位时
QPS关联模式 如果A关联B,当B请求达到阈值,A请求会挂掉
==Warm Up(RuleConstant.CONTROL_BEHAVIOR_WARM_UP
)==方式,即预热/冷启动方式。当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过”冷启动”,让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。初始阈值为最大阈值除以3. 经过预热时长到达最大阈值
匀速排队 匀速排队(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER
)方式会严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法。
这种方式主要用于处理间隔性突发的流量,例如消息队列。想象一下这样的场景,在某一秒有大量的请求到来,而接下来的几秒则处于空闲状态,我们希望系统能够在接下来的空闲期间逐渐处理这些请求,而不是在第一秒直接拒绝多余的请求。
注意:匀速排队模式暂时不支持 QPS > 1000 的场景。
线程数
服务降级—>服务端 降级是给服务提供者准备的
除了流量控制以外,对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措施之一。一个服务常常会调用别的模块,可能是另外的一个远程服务、数据库,或者第三方 API 等。例如,支付的时候,可能需要远程调用银联提供的 API;查询某个商品的价格,可能需要进行数据库查询。然而,这个被依赖服务的稳定性是不能保证的。如果依赖的服务出现了不稳定的情况,请求的响应时间变长,那么调用服务的方法的响应时间也会变长,线程会产生堆积,最终可能耗尽业务自身的线程池,服务本身也变得不可用。
现代微服务架构都是分布式的,由非常多的服务组成。不同服务之间相互调用,组成复杂的调用链路。以上的问题在链路调用中会产生放大的效果。复杂链路上的某一环不稳定,就可能会层层级联,最终导致整个链路都不可用。因此我们需要对不稳定的弱依赖服务调用 进行熔断降级,暂时切断不稳定调用,避免局部不稳定因素导致整体的雪崩。熔断降级作为保护自身的手段,通常在客户端(调用端)进行配置。
Sentinel 提供以下几种熔断策略:
慢调用比例 (SLOW_REQUEST_RATIO
):选择以慢调用比例作为阈值,需要设置允许的慢调用 RT (即最大的响应时间),请求的响应时间大于该值则统计为慢调用。当单位统计时长(statIntervalMs
)内请求数目大于设置的最小请求数目,并且慢调用的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 RT 则会再次被熔断。
异常比例 (ERROR_RATIO
):当单位统计时长(statIntervalMs
)内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。异常比率的阈值范围是 [0.0, 1.0]
,代表 0% - 100%。
异常数 (ERROR_COUNT
):当单位统计时长内的异常数目超过阈值之后会自动进行熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。
Controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 @RestController public class FlowLimitController { @RequestMapping("/testA") public String testA () { return "--------------testA" ; } @RequestMapping("/testB") public String testB () { return "--------------testB" ; } @RequestMapping("/testC") @SentinelResource(value = "testC", blockHandler = "deal_testC") public String testC (@RequestParam(value = "p1", required = false) String p1, @RequestParam(value = "p2", required = false) String p2) { return "--------------testC" ; } public String deal_testC (String p1, String p2, BlockException exception) { return "testC-------热点限流" ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 @RestController public class RateLimitController { @GetMapping("/byResource") @SentinelResource(value = "byResource", blockHandler = "handleException") public CommonResult byResource () { return new CommonResult(200 , "按照资源限流" , new User("wang" , 10 )); } public CommonResult handleException (BlockException exception) { return new CommonResult(444 , exception.getClass().getCanonicalName()); } @GetMapping("/byResourceUrl") public CommonResult byResourceUrl () { return new CommonResult(200 , "按照Url地址限流" , new User("wang" , 10 )); } @GetMapping("/CustomerHandle") @SentinelResource(value = "CustomerHandle", blockHandlerClass = CustomerBlockHandle.class, blockHandler = "handleException1") public CommonResult CustomerHandle () { return new CommonResult(200 , "按照资源地址限流" , new User("wang" , 10 )); } }
启动类
1 2 3 4 5 6 7 @SpringBootApplication @EnableDiscoveryClient public class MainApp8401 { public static void main(String[] args) { SpringApplication.run(MainApp8401.class,args); } }
application.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 server: port: 8401 spring: application: name: nacos-stock4-sentinel cloud: nacos: discovery: server-addr: 127.0 .0 .1 :8848 sentinel: transport: dashboard: 127.0 .0 .1 :8080 port: 8719 management: endpoints: web: exposure: include: '*'
pom.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 <dependencies> <dependency> <groupId>com.wang</groupId> <artifactId>nacos-api</artifactId> <version>1.0 -SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 配置中心 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <!--服务注册与发现--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!--spring-cloud-alibaba-sentinel--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> <!-- https: <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> <version>3.0 .3 </version> </dependency> </dependencies>
服务熔断—>客户端 熔断是给服务消费者准备的
服务提供者
Controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @RestController public class PaymentController { @Value("${server.port}") private String serverPort; public static HashMap<Integer, User> hashMap = new HashMap<>(); static { hashMap.put(1 ,new User("王1" ,20 )); hashMap.put(2 ,new User("王2" ,21 )); hashMap.put(3 ,new User("王3" ,22 )); } @GetMapping("/paymentSQL/{id}") public CommonResult<User> paymentSQL (@PathVariable("id") Integer id) { User user = hashMap.get(id); CommonResult<User> result = new CommonResult(200 ,"端口" + serverPort ,user); return result; } }
application.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 server: port: 9003 spring: application: name: nacos-provider cloud: nacos: server-addr: 127.0 .0 .1 :8848 management: endpoints: web: exposure: include: '*'
依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <dependencies> <dependency> <groupId>com.wang</groupId> <artifactId>nacos-api</artifactId> <version>1.0 -SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 配置中心 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <!--服务注册与发现--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> </dependencies>
服务消费者
Controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 @RestController public class ConsumerController { @Resource private ProviderFeign providerFeign; @GetMapping("/ConsumerSQL/{id}") @SentinelResource(value = "fallback",blockHandler = "blockHandler",fallback = "handleFallback", exceptionsToIgnore = {IllegalArgumentException.class}) public CommonResult<User> fallback (@PathVariable("id") Integer id) { CommonResult<User> result = providerFeign.paymentSQL(id); if (id == 4 ){ throw new IllegalArgumentException("非法参数异常........" ); }else if (result.getData() == null ){ throw new NullPointerException("空指针异常.........." ); } return result; } public CommonResult<User> handleFallback (Integer id,Throwable e) { User user = new User("null" , null ); return new CommonResult<>(444 ,"handleFallback兜底异常" +e.getMessage(),user); } public CommonResult<User> blockHandler (Integer id, BlockException e) { User user = new User("null" , null ); return new CommonResult<>(445 ,"blockHandler兜底异常" +e.getLocalizedMessage(),user); } @GetMapping("/ConsumerSQL1/{id}") public CommonResult<User> fallback1 (@PathVariable("id") Integer id) { return providerFeign.paymentSQL(id); } }
ProviderFeign
1 2 3 4 5 6 @FeignClient(value ="nacos-provider",fallback = ProviderFeignImpl.class) public interface ProviderFeign { @GetMapping("/paymentSQL/{id}") CommonResult<User> paymentSQL (@PathVariable("id") Integer id) ; }
ProviderFeignImpl
1 2 3 4 5 6 7 @Component public class ProviderFeignImpl implements ProviderFeign { @Override public CommonResult<User> paymentSQL (Integer id) { return new CommonResult<>(444444 ,"报错了....." ,new User(null ,null )); } }
application.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 server: port: 84 spring: application: name: nacos-consumer cloud: nacos: discovery: server-addr: 127.0 .0 .1 :8848 sentinel: transport: dashboard: 127.0 .0 .1 :8080 port: 8719 feign: sentinel: enabled: true
pom.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 <dependencies> <dependency> <groupId>com.wang</groupId> <artifactId>nacos-api</artifactId> <version>1.0 -SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 配置中心 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <!--服务注册与发现--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!-- https: <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> <version>2.1 .0 .RELEASE</version> </dependency> <!--spring-cloud-alibaba-sentinel--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> <!-- https: <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-nacos</artifactId> <version>1.5 .2 </version> </dependency> </dependencies>
Seata :分布式事务解决方案Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。
全局唯一的事务ID
TC (Transaction Coordinator) - 事务协调者
维护全局和分支事务的状态,驱动全局事务提交或回滚。
TM (Transaction Manager) - 事务管理器
定义全局事务的范围:开始全局事务、提交或回滚全局事务。
RM (Resource Manager) - 资源管理器
管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。
![FEZ4$GV[OG]WWU2QE{FUX
测试 下单–>减库存–>减账户–>下单成功
订单模块 seata-order-service2001 Controller
1 2 3 4 5 6 7 8 9 10 11 12 @RestController public class T_orderController { @Resource T_orderService t_orderService; @GetMapping("/order/create") public CommonResult create (T_order t_order) { t_orderService.create(t_order); return new CommonResult(200 ,"下单成功" ); } }
实体类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @Data @AllArgsConstructor @NoArgsConstructor public class T_order { private Long id; private Long user_id; private Long product_id; private Integer count; private BigDecimal money; private Integer status; }
Mapper
1 2 3 4 5 6 7 8 9 @Mapper public interface T_orderMapper { void create (T_order tOrder) ; void update (@Param("user_id") Long user_id ,@Param("status") Integer status) ; }
service
1 2 3 4 5 public interface T_orderService { void create (T_order tOrder) ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 @Service public class T_orderServiceImpl implements T_orderService { @Resource T_orderMapper t_orderMapper; @Resource T_accountFeign t_accountService; @Resource T_storageFeign t_storageService; @Override @GlobalTransactional(name = "my_test_tx_group",rollbackFor = Exception.class) public void create (T_order tOrder) { t_orderMapper.create(tOrder); t_storageService.decrease(tOrder.getProduct_id(),tOrder.getCount()); t_accountService.decrease(tOrder.getUser_id(),tOrder.getMoney()); t_orderMapper.update(tOrder.getUser_id(),0 ); } }
OpenFeign
1 2 3 4 5 6 7 @Component @FeignClient("seata-account-service2002") public interface T_accountFeign { @PostMapping(value = "/account/decrease") public CommonResult decrease (@RequestParam("user_id") Long user_id, @RequestParam("money") BigDecimal money) ; }
1 2 3 4 5 6 7 @Component @FeignClient("seata-storage-service2003") public interface T_storageFeign { @PostMapping(value = "/storage/decrease") public CommonResult decrease (@RequestParam("product_id") Long product_id, @RequestParam("count") Integer count) ; }
启动类
1 2 3 4 5 6 7 8 @SpringBootApplication @EnableFeignClients(basePackages = "com.wang.service.openFeign") @EnableDiscoveryClient public class Order2001Application { public static void main (String[] args) { SpringApplication.run(Order2001Application.class,args); } }
xml
1 2 3 4 5 6 7 8 9 10 11 <mapper namespace="com.wang.mapper.T_orderMapper" > <insert id="create" parameterType="t_order" > insert into t_order (user_id,product_id,count,money,status) values (#{user_id},#{product_id},#{count},#{money},0 ) </insert> <update id ="update" > update t_order set status=1 where user_id=#{user_id} and status=#{status} </update> </mapper>
application.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 server: port: 2001 spring: application: name: seata-order-service2001 cloud: alibaba: seata: tx-service-group: my_test_tx_group nacos: discovery: server-addr: localhost:8848 datasource: type: com.alibaba.druid.pool.DruidDataSource url: jdbc:mysql://localhost:3306/seata_order?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC username: root password: 123456 mybatis: type-aliases-package: com.wang.entity mapper-locations: classpath:mybatis/mapper/*.xml
file.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 service { #transaction service group mapping vgroup_mapping.seata-server = "default" #only support when registry.type=file, please don't set multiple addresses default.grouplist = "127.0.0.1:8091" #disable seata disableGlobalTransaction = false } ## transaction log store, only used in seata-server store { ## store mode: file、db mode = "db" ## file store property file { ## store location dir dir = "sessionStore" } ## database store property db { ## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp) etc. datasource = "dbcp" ## mysql/oracle/h2/oceanbase etc. db-type = "mysql" driver-class-name = "com.mysql.jdbc.Driver" url = "jdbc:mysql://127.0.0.1:3306/seata" user = "root" password = "123456" } }
registry.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 registry { # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa type = "nacos" nacos { serverAddr = "localhost:8848" namespace = "" cluster = "default" } eureka { serviceUrl = "http://localhost:8761/eureka" application = "default" weight = "1" } redis { serverAddr = "localhost:6379" db = "0" } zk { cluster = "default" serverAddr = "127.0.0.1:2181" session.timeout = 6000 connect.timeout = 2000 } consul { cluster = "default" serverAddr = "127.0.0.1:8500" } etcd3 { cluster = "default" serverAddr = "http://localhost:2379" } sofa { serverAddr = "127.0.0.1:9603" application = "default" region = "DEFAULT_ZONE" datacenter = "DefaultDataCenter" cluster = "default" group = "SEATA_GROUP" addressWaitTime = "3000" } file { name = "file.conf" } } config { # file、nacos 、apollo、zk、consul、etcd3 type = "file" nacos { serverAddr = "localhost" namespace = "" } consul { serverAddr = "127.0.0.1:8500" } apollo { app.id = "seata-server" apollo.meta = "http://192.168.1.204:8801" } zk { serverAddr = "127.0.0.1:2181" session.timeout = 6000 connect.timeout = 2000 } etcd3 { serverAddr = "http://localhost:2379" } file { name = "file.conf" } }
pom.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 <dependencies> <dependency> <groupId>com.wang</groupId> <artifactId>nacos-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-seata --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-seata</artifactId> <exclusions> <exclusion> <artifactId>seata-all</artifactId> <groupId>io.seata</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>io.seata</groupId> <artifactId>seata-all</artifactId> <version>1.2.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 配置中心 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <!--服务注册与发现--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.20</version> <scope>provided</scope> </dependency> <!--spring-cloud-alibaba-sentinel--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-openfeign --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> <version>2.1.0.RELEASE</version> </dependency> <!-- 官方的--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.0</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency> </dependencies>
账户模块seata-account-service2002 Controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @RestController public class T_accountController { T_accountService t_accountService; public T_accountController (T_accountService t_accountService) { this .t_accountService = t_accountService; } @PostMapping(value = "/account/decrease") public CommonResult decrease (@RequestParam("user_id") Long user_id, @RequestParam("money") BigDecimal money) { t_accountService.decrease(user_id, money); return new CommonResult(200 ,"账户余额扣减成功,哈哈哈" ); } }
实体类
1 2 3 4 5 6 7 8 9 10 @Data @AllArgsConstructor @NoArgsConstructor public class T_account { private Long id; private Long user_id; private BigDecimal total; private BigDecimal used; private BigDecimal residue; }
Mapper
1 2 3 4 @Mapper public interface T_accountMapper { void decrease (@Param("user_id") Long user_id,@Param("money") BigDecimal money) ; }
service
1 2 3 public interface T_accountService { void decrease (@Param("user_id") Long user_id, @Param("money") BigDecimal money) ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @Service public class T_accountServiceImpl implements T_accountService { @Resource T_accountMapper t_accountMapper; @Override public void decrease (Long user_id, BigDecimal money) { t_accountMapper.decrease(user_id,money); } }
启动类
1 2 3 4 5 6 7 @SpringBootApplication @EnableDiscoveryClient public class T_account2002Application { public static void main (String[] args) { SpringApplication.run(T_account2002Application.class,args); } }
xml
1 2 3 4 5 6 7 <mapper namespace ="com.wang.mapper.T_accountMapper" > <update id ="decrease" > update t_account set used = used + #{money},residue = residue - #{money} where user_id=#{user_id} </update > </mapper >
application.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 server: port: 2002 spring: application: name: seata-account-service2002 cloud: alibaba: seata: tx-service-group: my_test_tx_group nacos: discovery: server-addr: localhost:8848 datasource: type: com.alibaba.druid.pool.DruidDataSource url: jdbc:mysql://localhost:3306/seata_account?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC username: root password: 123456 mybatis: type-aliases-package: com.wang.entity mapper-locations: classpath:mybatis/mapper/*.xml
file.conf文件
registry.conf文件
依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 <dependencies> <dependency> <groupId>com.wang</groupId> <artifactId>nacos-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-seata --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-seata</artifactId> <exclusions> <exclusion> <artifactId>seata-all</artifactId> <groupId>io.seata</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>io.seata</groupId> <artifactId>seata-all</artifactId> <version>1.2.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 配置中心 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <!--服务注册与发现--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.20</version> <scope>provided</scope> </dependency> <!--spring-cloud-alibaba-sentinel--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-openfeign --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> <version>2.1.0.RELEASE</version> </dependency> <!-- 官方的--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.0</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency> </dependencies>
库存模块seata-storage-service2003 Controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @RestController public class T_storageController { T_storageService t_storageService; public T_storageController (T_storageService t_storageService) { this .t_storageService = t_storageService; } @PostMapping(value = "/storage/decrease") public CommonResult decrease (@RequestParam("product_id") Long product_id, @RequestParam("count") Integer count) { t_storageService.decrease(product_id, count); return new CommonResult(200 ,"库存扣减成功,哈哈哈哈" ); } }
实体类
1 2 3 4 5 6 7 8 9 10 @Data @AllArgsConstructor @NoArgsConstructor public class T_storage { private Long id; private Long product_id; private Integer total; private Integer used; private Integer residue; }
Mapper
1 2 3 4 5 @Mapper public interface T_storageMapper { void decrease (@Param("product_id") Long product_id,@Param("count") Integer count) ; }
Service
1 2 3 public interface T_storageService { void decrease (@Param("product_id") Long product_id, @Param("count") Integer count) ; }
1 2 3 4 5 6 7 8 9 10 11 @Service public class T_storageServiceImpl implements T_storageService { @Resource T_storageMapper t_storageMapper; @Override public void decrease (Long product_id, Integer count) { t_storageMapper.decrease(product_id,count); } }
启动类
1 2 3 4 5 6 7 @SpringBootApplication @EnableDiscoveryClient public class T_storage2003Application { public static void main (String[] args) { SpringApplication.run(T_storage2003Application.class,args); } }
xml
1 2 3 4 5 6 7 <mapper namespace ="com.wang.mapper.T_storageMapper" > <update id ="decrease" > update t_storage set used=used+#{count},residue=residue-#{count} where product_id=#{product_id} </update > </mapper >
application.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 server: port: 2003 spring: application: name: seata-storage-service2003 cloud: alibaba: seata: tx-service-group: my_test_tx_group nacos: discovery: server-addr: localhost:8848 datasource: type: com.alibaba.druid.pool.DruidDataSource url: jdbc:mysql://localhost:3306/seata_storage?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC username: root password: 123456 mybatis: type-aliases-package: com.wang.entity mapper-locations: classpath:mybatis/mapper/*.xml
file.conf文件
registry.conf文件
依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 <dependencies> <dependency> <groupId>com.wang</groupId> <artifactId>nacos-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-seata --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-seata</artifactId> <exclusions> <exclusion> <artifactId>seata-all</artifactId> <groupId>io.seata</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>io.seata</groupId> <artifactId>seata-all</artifactId> <version>1.2.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 配置中心 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <!--服务注册与发现--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.20</version> <scope>provided</scope> </dependency> <!--spring-cloud-alibaba-sentinel--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-openfeign --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> <version>2.1.0.RELEASE</version> </dependency> <!-- 官方的--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.0</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency> </dependencies>