2.启动eureka注册服务
2.1.创建模块
2.2.添加依赖:
2.3.yml配置:
2.4.启动类添加注解@EnableEurekaServer
3.创建订单父级项目
3.1.创建一个父级项目,统一管理订单/账户/库存项目的依赖
3.2.pom文件粘贴:
4.创建子项目账目
4.1.创建子项目
4.2.修改依赖,parent继承父级
4.3.yml配置
4.4.布置项目中的类:
5.创建库存模块:
5.1.创建项目
5.2.pom.xml
5.3.yml配置
5.4.项目中的类:
6.创建订单子项目
6.1.创建项目
6.2.pom.xml
6.3.yml配置
6.4.项目中的类:
7.配置全局唯一id发号器
7.1下载项目
老师的对应CSDN
https://wanght.blog.csdn.net/article/details/107596037
2.启动eureka注册服务
2.1.创建模块
2.2.添加依赖:
2.3.yml配置:
spring:
application:
name: eureka-server
server:
port: 8761
eureka:
server:
#关闭保护模式
enable-self-preservation: false
client:
# 对单台服务器,不注册不拉取
register-with-eureka: false
fetch-registry: false
2.4.启动类添加注解@EnableEurekaServer
配置完,启动服务,并访问端口
效果:
3.创建订单父级项目
3.1.创建一个父级项目,统一管理订单/账户/库存项目的依赖
3.2.pom文件粘贴:
修改版本号:
<?xml version="1.0" encoding="UTF-8"?>
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.3.12.RELEASE
cn.tedu
order-parent
1.0-SNAPSHOT
pom
order-parent
<properties>
<mybatis-plus.version>3.3.2</mybatis-plus.version>
<druid-spring-boot-starter.version>1.1.23</druid-spring-boot-starter.version>
<seata.version>1.3.0</seata.version>
<spring-cloud-alibaba-seata.version>2.0.0.RELEASE</spring-cloud-alibaba-seata.version>
<spring-cloud.version>Hoxton.SR11</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid-spring-boot-starter.version}</version>
</dependency>
<!--<dependency>-->
<!-- <groupId>com.alibaba.cloud</groupId>-->
<!-- <artifactId>spring-cloud-alibaba-seata</artifactId>-->
<!-- <version>${spring-cloud-alibaba-seata.version}</version>-->
<!-- <exclusions>-->
<!-- <exclusion>-->
<!-- <artifactId>seata-all</artifactId>-->
<!-- <groupId>io.seata</groupId>-->
<!-- </exclusion>-->
<!-- </exclusions>-->
<!--</dependency>-->
<!--<dependency>-->
<!-- <groupId>io.seata</groupId>-->
<!-- <artifactId>seata-all</artifactId>-->
<!-- <version>${seata.version}</version>-->
<!--</dependency>-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<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>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
父项目的src没有用,删掉
4.创建子项目账目
右键点order-parent,新建模块,注意父级,别创建错误
4.1.创建子项目
不用加依赖,修改一下spring版本,下一步,注意路径正确:
4.2.修改依赖,parent继承父级
<?xml version="1.0" encoding="UTF-8"?>
order-parent
cn.tedu
1.0-SNAPSHOT
<modelVersion>4.0.0</modelVersion>
<artifactId>account</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>account</name>
<description>Demo project for Spring Boot</description>
4.3.yml配置
spring:
application:
name: account
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost/seata_account?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
username: root
password: root
8081 account
8082 storage
8083 order
server:
port: 8081
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
instance:
# 注册ip
prefer-ip-address: true
# 显示ip
instance-id:
s
p
r
i
n
g
.
c
l
o
u
d
.
c
l
i
e
n
t
.
i
p
−
a
d
d
r
e
s
s
:
{spring.cloud.client.ip-address}:
spring.cloud.client.ip−address:{spring.application.name}😒{server.port}
mybatis-plus:
mapper-locations: classpath:/mapper/*.xml
configuration:
# 驼峰命名
map-underscore-to-camel-case: true
type-aliases-package: cn.tedu.account.entity
打开sql语句执行日志
logging:
level:
cn.tedu.account.mapper: debug
#bootstrap.yml
选择网卡
spring:
cloud:
inetutils:
preferred-networks:
# 本机ip
- 172.88.13…+
4.4.布置项目中的类:
Account :
package cn.tedu.account.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Account {
private Long id;
private Long userId;
private BigDecimal total; //总金额
private BigDecimal used; //已使用
private BigDecimal residue; //可用
private BigDecimal frozen; //冻结
}
AccountMapper :
package cn.tedu.account.mapper;
import cn.tedu.account.entity.Account;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import java.math.BigDecimal;
public interface AccountMapper extends BaseMapper {
void decrease(Long userId, BigDecimal money);
}
AccountMapper.xml:
用File创建文件的时候,用/表示文件目录
package cn.tedu.account.service;
import java.math.BigDecimal;
public interface AccountService {
void decrease(Long userId, BigDecimal money);
}
package cn.tedu.account.service;
import cn.tedu.account.mapper.AccountMapper;
import org.springframework.beans.factory.annotation.Autowired;
import java.math.BigDecimal;
@Service
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountMapper accountMapper;
@Override
public void decrease(Long userId, BigDecimal money) {
accountMapper.decrease(userId,money);
}
}
package cn.tedu.account.controller;
import cn.tedu.account.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
@RestController
public class AccountController {
@Autowired
private AccountService accountService;
@GetMapping("/decrease") // /decrease?useId=1&money=100
public String decrease(Long useId, BigDecimal money){
accountService.decrease(useId, money);
return “账户扣减成功”;
}
}
效果:
5.创建库存模块:
5.1.创建项目
依赖改一下spring版本,不用加其他依赖,注意路径:
5.2.pom.xml
<?xml version="1.0" encoding="UTF-8"?>
order-parent
cn.tedu
1.0-SNAPSHOT
<modelVersion>4.0.0</modelVersion>
<artifactId>storage</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>storage</name>
<description>Demo project for Spring Boot</description>
5.3.yml配置 yml配置文件,直接复制account的两个yml,改一下(将account改为storage,四处记得改表名,改一下端口号) spring: application: name: storage datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost/seata_storage?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8 username: root password: root # 8081 account # 8082 storage # 8083 order server: port: 8082 eureka: client: service-url: defaultZone: http://localhost:8761/eureka instance: # 注册ip prefer-ip-address: true # 显示ip instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
mybatis-plus:
mapper-locations: classpath:/mapper/*.xml
configuration:
# 驼峰命名
map-underscore-to-camel-case: true
type-aliases-package: cn.tedu.storage.entity
打开sql语句执行日志
logging:
level:
cn.tedu.storage.mapper: debug
#bootstrap.yml
选择网卡
spring:
cloud:
inetutils:
preferred-networks:
# 本机ip
- 172.88.13…+
5.4.项目中的类:
package cn.tedu.storage.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Storage {
private Long id;
private Long productid;
private Integer total;
private Integer used;
private Integer residue;
private Integer frozen;
}
package cn.tedu.storage.mapper;
import cn.tedu.storage.entity.Storage;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface StorageMapper extends BaseMapper {
void decrease(Long productId,Integer count);
}
package cn.tedu.storage.service;
public interface StorageService {
void decrease(Long productId,Integer count);
}
package cn.tedu.storage.service;
import cn.tedu.storage.mapper.StorageMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class StorageServiceImpl implements StorageService {
@Autowired
private StorageMapper storageMapper;
@Override
public void decrease(Long productId, Integer count) {
storageMapper.decrease(productId, count);
}
}
启动类加注解
@MapperScan(“cn.tedu.storage.mapper”)
StorageMapper.xml:
package cn.tedu.storage.controller;
import cn.tedu.storage.service.StorageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class StorageController {
@Autowired
private StorageService storageService;
@GetMapping("/decrease") // /decrease?productId=1&count=10
public String decrease(Long productId, Integer count){
storageService.decrease(productId, count);
return “减少商品库存成功”;
}
}
效果:
6.创建订单子项目
6.1.创建项目
依赖改一下spring版本,不用加其他依赖,注意路径:
6.2.pom.xml
<?xml version="1.0" encoding="UTF-8"?>
order-parent
cn.tedu
1.0-SNAPSHOT
<modelVersion>4.0.0</modelVersion>
<artifactId>order</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>order</name>
<description>Demo project for Spring Boot</description>
6.3.yml配置 重复5.3的操作,yml配置文件,直接复制account的两个yml,改一下(将account改为order,四处记得改表名,改一下端口号)
6.4.项目中的类:
package cn.tedu.order.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Order {
private Long id;
private Long userId;
private Long productId;
private Integer count;
private BigDecimal money;
private Integer status;
}
package cn.tedu.order.mapper;
import cn.tedu.order.entity.Order;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface OrderMapper extends BaseMapper {
void create(Order order);
}
OrderMapper.xml
sql语句中,字段必须加反引号,因为在mapper里边order是关键字,所以要加反引号,后边括号里边的字段非关键字,可加可不加
package cn.tedu.order.service;
import cn.tedu.order.entity.Order;
public interface OrderService {
void create(Order order);
}
package cn.tedu.order.service;
import cn.tedu.order.entity.Order;
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;
@Override
public void create(Order order) {
// TODO:远程调用发号器生成订单id
//临时随机生成一个id,添加发号器后这行代码删除
// Math.abs()生成绝对值的方法
Long orderId= Math.abs(new Random().nextLong());
order.setId(orderId);
orderMapper.create(order);
//TODO: 远程调用库存减少商品库存
//TODO: 远程调用账户扣减账户金额
}
}
package cn.tedu.order.controller;
import cn.tedu.order.entity.Order;
import cn.tedu.order.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class OrderController {
@Autowired
private OrderService orderService;
@GetMapping("/create") // /create?userId=1&productId=1&count=10&money=100
public String create(Order order){
orderService.create(order);
return “创建订单成功”;
}
}
启动类加注解:
@MapperScan(“cn.tedu.order.mapper”)
效果:
7.配置全局唯一id发号器
分布式系统中,产生唯一流水号的服务系统俗称发号器。
有很多发号器开源项目,这里使用 EasyIdGenerator,具体项目信息请访问:
https://github.com/lookingatstarts/easyIdGenerator
项目使用非常简单,将项目下载下来稍作配置即可。
7.1下载项目
访问 https://github.com/lookingatstarts/easyIdGenerator ,下载发号器项目。
将文件解压到项目下:
7.2.导入 Module
在Maven工具窗口中点击添加按钮,选择发号器项目的 pom.xml 文件导入该项目:
注意: 如果右侧没有Maven工具标签,请按两下shift键,然后查找 “add maven projects” 就可以找到这个工具。
7.3.配置
pom.xml
修改springboot版本
发号器向 eureka 进行注册,以便其它服务发现它。
在pom.xml 中添加 Spring Cloud Eureka Client 依赖:
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.3.12.RELEASE
<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>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</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>Hoxton.SR11</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
application.yml 配置使用数据库来生成自增id 向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
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
instance:
prefer-ip-address: true
bootstrap.yml
选择网卡
spring:
cloud:
inetutils:
preferred-networks:
- 172.88.13…+
seata_order.properties 数据库配置
在 resources 目录下新建配置文件 seata_order.properties,配置 seata_order 数据库的连接信息。
jdbcUrl=jdbc:mysql://localhost:3306/seata_order?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
driverClassName=com.mysql.cj.jdbc.Driver
dataSource.user=root
dataSource.password=root
dataSource.cachePrepStmts=true
dataSource.prepStmtCacheSize=250
dataSource.prepStmtCacheSqlLimit=2048
数据表
在 db-init 项目的 order.sql 中已经创建了数据表,并插入了一个名为 order_business 的自增id条目。
项目的 schema.sql 中为示例数据表。
7.4.启动项目并访问测试
查看 eureka 中的注册信息