文章目录
全局唯一id发号器
- 到这里下载:
这里 - 解压到seata-at工程目录
- 文件夹改成easy-id
- pom.xml拖拽到idea,修改springboot版本
- 右击编辑区域,add as maven project
- 添加eureka client依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
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.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.2.RELEASE</version>
<relativePath/>
</parent>
<groupId>com.easy.id</groupId>
<artifactId>easy-id-generator</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
<junit.version>4.12</junit.version>
<mysql.connector.version>8.0.16</mysql.connector.version>
<com.alibaba.fastjson.version>1.2.62</com.alibaba.fastjson.version>
<lombok.version>1.18.8</lombok.version>
<curator.version>2.6.0</curator.version>
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.connector.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${com.alibaba.fastjson.version}</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>${curator.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR6</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
- 添加eureka连接配置
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
- 调整发号器的配置
修改地方之一
server:
port: 9090
easy-id-generator:
snowflake:
enable: false
zk:
connection-string: 127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183
load-worker-id-from-file-when-zk-down: true # 当zk不可访问时,从本地文件中读取之前备份的workerId
segment:
enable: true
db-list: seata_order
fetch-segment-retry-times: 3 # 从数据库获取号段失败重试次数
spring:
application:
name: easy-id-generator
修改地方之二
需要新建一个seata_order的properties文件
jdbcUrl=jdbc:mysql:///seata_order?serverTimezone=GMT%2B8&autoReconnect=true&useUnicode=true&characterEncoding=UTF-8
driverClassName=com.mysql.cj.jdbc.Driver
dataSource.user=root
dataSource.password=root
dataSource.cachePrepStmts=true
dataSource.prepStmtCacheSize=250
dataSource.prepStmtCacheSqlLimit=2048
order订单添加Feign,调用库存和账户服务
application.yml
ribbon 默认超时时间是1秒,为了方便分布式事务测试,把超时时长改为 10 秒:
spring:
application:
name: order
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost/seata_order?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
username: root
password: root
server:
port: 8083
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
instance:
prefer-ip-address: true
mybatis-plus:
type-aliases-package: cn.tedu.order.entity
mapper-locations:
- classpath:/mapper/*Mapper.xml
configuration:
map-underscore-to-camel-case: true
logging:
level:
cn.tedu.order.mapper: DEBUG
ribbon:
ReadTimeout: 10000
主程序添加注解启用Feign
package cn.tedu.order;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableFeignClients
@MapperScan("cn.tedu.order.mapper")
@SpringBootApplication
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
添加Feign声明式客户端接口
发号器的客户端接口:
package cn.tedu.order.feign;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(name = "EASY-ID-GENERATOR")
public interface EasyIdGeneratorClient {
@GetMapping("/segment/ids/next_id")
String nextId(@RequestParam String businessType);
}
库存服务的客户端接口:
package cn.tedu.order.feign;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(name = "storage")
public interface StorageClient {
@GetMapping("/decrease")
String decrease(@RequestParam Long productId, @RequestParam Integer count);
}
账户服务的客户端接口:
package cn.tedu.order.feign;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.math.BigDecimal;
@FeignClient(name = "account")
public interface AccountClient {
@GetMapping("/decrease")
String decrease(@RequestParam Long userId, @RequestParam BigDecimal money);
}
在业务代码中通过Feign客户端调用远程服务
package cn.tedu.order.service;
import cn.tedu.order.entity.Order;
import cn.tedu.order.feign.AccountClient;
import cn.tedu.order.feign.EasyIdGeneratorClient;
import cn.tedu.order.feign.StorageClient;
import cn.tedu.order.mapper.OrderMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Random;
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
EasyIdGeneratorClient easyIdGeneratorClient;
@Autowired
private AccountClient accountClient;
@Autowired
private StorageClient storageClient;
@Override
public void create(Order order) {
// 从全局唯一id发号器获得id
String s = easyIdClient.nextId("order_business");
Long orderId = Long.valueOf(s);
order.setId(orderId);
orderMapper.create(order);
// 修改库存
storageClient.decrease(order.getProductId(), order.getCount());
// 修改账户余额
accountClient.decrease(order.getUserId(), order.getMoney());
}
}
启动项目,访问测试
访问订单项目进行测试:
http://localhost:8083/create?userId=1&productId=1&count=10&money=100
查看 order、storage和account的控制台查看日志
查看三个数据库中的数据变化