Spring Cloud + Nacos + Seata整合过程(分布式事务解决方案)
Spring Cloud是一个基于Spring Boot的微服务框架,它提供了一系列的组件和工具,用于构建分布式系统。Nacos是一个开源的服务发现、配置管理和动态DNS解析系统,它提供了一种简单而有效的方式来管理和路由微服务请求。Seata是一个开源的分布式事务解决方案,它提供了一种简单而有效的方式来处理分布式事务。
在本攻略中,我们将详细介绍Spring Cloud + Nacos + Seata的整合过程,并提供两个示例说明。
设计
在设计分布式系统时,需要考虑几个方面:
- 服务注册和发现:使用服务注册和发现系统来管理和路由微服务请求。
- 配置管理:使用配置管理系统来管理微服务的配置信息。
- 分布式事务:使用分布式事务解决方案来处理分布式事务。
在本攻略中,我们将使用Spring Cloud + Nacos + Seata来实现一个简单的分布式系统,包括服务注册和发现、配置管理和分布式事务。
实现
服务注册和发现
我们可以使用Spring Cloud和Nacos来实现服务注册和发现。以下是一个示例:
- 创建一个名为provider的Spring Boot项目,并添加以下依赖:
<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-discovery</artifactId>
</dependency>
- 在provider项目中创建一个名为HelloController的控制器,并添加以下代码:
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "Hello, World!";
}
}
- 在provider项目中创建一个名为application.yml的文件,并将以下内容复制到文件中:
spring:
application:
name: provider
cloud:
nacos:
discovery:
server-addr: localhost:8848
- 创建一个名为consumer的Spring Boot项目,并添加以下依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
- 在consumer项目中创建一个名为HelloService的服务接口,并添加以下代码:
@FeignClient("provider")
public interface HelloService {
@GetMapping("/hello")
String hello();
}
- 在consumer项目中创建一个名为HelloController的控制器,并添加以下代码:
@RestController
public class HelloController {
@Autowired
private HelloService helloService;
@GetMapping("/hello")
public String hello() {
return helloService.hello();
}
}
- 在consumer项目中创建一个名为application.yml的文件,并将以下内容复制到文件中:
spring:
application:
name: consumer
cloud:
nacos:
discovery:
server-addr: localhost:8848
- 启动provider项目和consumer项目,并访问http://localhost:8080/hello,确保服务已注册和发现。
配置管理
我们可以使用Nacos来实现配置管理。以下是一个示例:
- 在Nacos控制台中创建一个名为config的配置集,并添加以下配置:
spring:
datasource:
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456
- 创建一个名为config的Spring Boot项目,并添加以下依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.23</version>
</dependency>
- 在config项目中创建一个名为DataSourceConfig的配置类,并添加以下代码:
@Configuration
@RefreshScope
public class DataSourceConfig {
@Value("${spring.datasource.url}")
private String url;
@Value("${spring.datasource.username}")
private String username;
@Value("${spring.datasource.password}")
private String password;
@Bean
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
}
- 在config项目中创建一个名为application.yml的文件,并将以下内容复制到文件中:
spring:
application:
name: config
cloud:
nacos:
config:
server-addr: localhost:8848
file-extension: yaml
group: DEFAULT_GROUP
refreshable-dataids: config.yaml
- 启动config项目,并访问http://localhost:8080/druid,确保数据源已配置成功。
分布式事务
我们可以使用Seata来实现分布式事务。以下是一个示例:
- 创建一个名为order的Spring Boot项目,并添加以下依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-all</artifactId>
<version>1.4.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.23</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
- 在order项目中创建一个名为Order的实体类,并添加以下代码:
@Data
public class Order {
private Long id;
private Long userId;
private Long productId;
private Integer count;
private BigDecimal money;
private Integer status;
}
- 在order项目中创建一个名为OrderMapper的Mapper接口,并添加以下代码:
@Mapper
public interface OrderMapper {
void create(Order order);
void update(@Param("userId") Long userId, @Param("status") Integer status);
}
- 在order项目中创建一个名为OrderService的服务接口,并添加以下代码:
public interface OrderService {
void create(Order order);
}
- 在order项目中创建一个名为OrderServiceImpl的服务实现类,并添加以下代码:
@Service
@Slf4j
public class OrderServiceImpl implements OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private RestTemplate restTemplate;
@Override
@GlobalTransactional(name = "create-order", rollbackFor = Exception.class)
public void create(Order order) {
log.info("------->开始新建订单");
orderMapper.create(order);
log.info("------->订单微服务开始调用库存,做扣减Count");
restTemplate.postForObject("http://localhost:8081/decrease", order, String.class);
log.info("------->订单微服务开始调用账户,做扣减Money");
restTemplate.postForObject("http://localhost:8082/decrease", order, String.class);
log.info("------->修改订单状态开始");
orderMapper.update(order.getUserId(), 0);
log.info("------->修改订单状态结束");
log.info("------->下订单结束了,O(∩_∩)O哈哈~");
}
}
- 在order项目中创建一个名为OrderController的控制器,并添加以下代码:
@RestController
@Slf4j
public class OrderController {
@Autowired
private OrderService orderService;
@PostMapping("/create")
public CommonResult create(@RequestBody Order order) {
orderService.create(order);
return new CommonResult(200, "订单创建成功");
}
}
- 在order项目中创建一个名为application.yml的文件,并将以下内容复制到文件中:
spring:
application:
name: order
cloud:
nacos:
discovery:
server-addr: localhost:8848
datasource:
url: jdbc:mysql://localhost:3306/seata_order?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456
seata:
enabled: true
application-id: order
tx-service-group: my_test_tx_group
mybatis:
mapper-locations: classpath:mapper/*.xml
- 创建一个名为storage的Spring Boot项目,并添加以下依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-all</artifactId>
<version>1.4.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.23</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
- 在storage项目中创建一个名为Storage的实体类,并添加以下代码:
@Data
public class Storage {
private Long id;
private Long productId;
private Integer total;
private Integer used;
private Integer residue;
}
- 在storage项目中创建一个名为StorageMapper的Mapper接口,并添加以下代码:
@Mapper
public interface StorageMapper {
void decrease(@Param("productId") Long productId, @Param("count") Integer count);
}
- 在storage项目中创建一个名为StorageService的服务接口,并添加以下代码:
public interface StorageService {
void decrease(Long productId, Integer count);
}
- 在storage项目中创建一个名为StorageServiceImpl的服务实现类,并添加以下代码:
@Service
@Slf4j
public class StorageServiceImpl implements StorageService {
@Autowired
private StorageMapper storageMapper;
@Override
@GlobalTransactional(name = "decrease-storage", rollbackFor = Exception.class)
public void decrease(Long productId, Integer count) {
log.info("------->扣减库存开始");
storageMapper.decrease(productId, count);
log.info("------->扣减库存结束");
}
}
- 在storage项目中创建一个名为StorageController的控制器,并添加以下代码:
@RestController
@Slf4j
public class StorageController {
@Autowired
private StorageService storageService;
@PostMapping("/decrease")
public CommonResult decrease(@RequestBody Storage storage) {
storageService.decrease(storage.getProductId(), storage.getCount());
return new CommonResult(200, "扣减库存成功");
}
}
- 在storage项目中创建一个名为application.yml的文件,并将以下内容复制到文件中:
spring:
application:
name: storage
cloud:
nacos:
discovery:
server-addr: localhost:8848
datasource:
url: jdbc:mysql://localhost:3306/seata_storage?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456
seata:
enabled: true
application-id: storage
tx-service-group: my_test_tx_group
mybatis:
mapper-locations: classpath:mapper/*.xml
- 创建一个名为account的Spring Boot项目,并添加以下依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-all</artifactId>
<version>1.4.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.23</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
- 在account项目中创建一个名为Account的实体类,并添加以下代码:
@Data
public class Account {
private Long id;
private Long userId;
private BigDecimal total;
private BigDecimal used;
private BigDecimal residue;
}
- 在account项目中创建一个名为AccountMapper的Mapper接口,并添加以下代码:
@Mapper
public interface AccountMapper {
void decrease(@Param("userId") Long userId, @Param("money") BigDecimal money);
}
- 在account项目中创建一个名为AccountService的服务接口,并添加以下代码:
public interface AccountService {
void decrease(Long userId, BigDecimal money);
}
- 在account项目中创建一个名为AccountServiceImpl的服务实现类,并添加以下代码:
@Service
@Slf4j
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountMapper accountMapper;
@Override
@GlobalTransactional(name = "decrease-account", rollbackFor = Exception.class)
public void decrease(Long userId, BigDecimal money) {
log.info("------->扣减账户开始");
accountMapper.decrease(userId, money);
log.info("------->扣减账户结束");
}
}
- 在account项目中创建一个名为AccountController的控制器,并添加以下代码:
@RestController
@Slf4j
public class AccountController {
@Autowired
private AccountService accountService;
@PostMapping("/decrease")
public CommonResult decrease(@RequestBody Account account) {
accountService.decrease(account.getUserId(), account.getMoney());
return new CommonResult(200, "扣减账户成功");
}
}
- 在account项目中创建一个名为application.yml的文件,并将以下内容复制到文件中:
spring:
application:
name: account
cloud:
nacos:
discovery:
server-addr: localhost:8848
datasource:
url: jdbc:mysql://localhost:3306/seata_account?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456
seata:
enabled: true
application-id: account
tx-service-group: my_test_tx_group
mybatis:
mapper-locations: classpath:mapper/*.xml
- 启动order项目、storage项目和account项目,并访问http://localhost:8083/create,确保分布式事务已处理成功。
总结
本攻略详细介绍了Spring Cloud + Nacos + Seata的整合过程,并提供了两个示例说明。通过本攻略的学习,我们了解了Spring Cloud、Nacos和Seata的相关技术,并掌握了一些示例。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Cloud + Nacos + Seata整合过程(分布式事务解决方案) - Python技术站