搭建基础的springcloud alibaba项目练习

1、新建maven项目

在cloud-test pom.xml文件中导入基础包

xml 复制代码
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  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>

  <groupId>org.example</groupId>
  <artifactId>cloud-test</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>pom</packaging>

  <name>cloud-test</name>
  <url>http://maven.apache.org</url>
  <modules>
    <module>order-server</module>
    <module>product-server</module>
    <module>model</module>
  </modules>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.4</version>
    <relativePath/>
  </parent>

  <properties>
    <maven.complier.source>17</maven.complier.source>
    <maven.complier.target>17</maven.complier.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <spring-cloud.version>2021.0.5</spring-cloud.version>
    <spring-cloud-alibaba.version>2021.0.5.0</spring-cloud-alibaba.version>
  </properties>

  <dependencyManagement>
    <dependencies>
      <!--这些是cloud基础包-->
      <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>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-alibaba-dependencies</artifactId>
        <version>${spring-cloud-alibaba.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
      <!--这些是cloud基础包-->
      <dependency>
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-all</artifactId>
        <version>5.8.35</version>
      </dependency>
      <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus</artifactId>
        <version>3.4.2</version>
      </dependency>
      <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.4.2</version>
      </dependency>
      <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.32</version>
      </dependency>
      <dependency>
        <groupId>com.alibaba.fastjson2</groupId>
        <artifactId>fastjson2</artifactId>
        <version>2.0.43</version>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.1</version>
        <configuration>
          <source>17</source>
          <target>17</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

2、配置nacos注册中心

2.1、启动nacos服务

nacos下载地址

启动文件startup.cmd下

bash 复制代码
#默认cluster 集群版,standalone单机版
set MODE="standalone"

3、product-server服务

导入需要maven

xml 复制代码
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         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.example</groupId>
        <artifactId>cloud-test</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>product-server</artifactId>
    <packaging>jar</packaging>

    <name>product-server</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</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>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

application.yml

yaml 复制代码
server:
  port: 8078

spring:
  application:
    name: product-server

  #指定了nacos配置管理中数据源的配置文件
  config:
    import:
      - nacos:database.yml?group=order

  cloud:
    #配置nacos
    nacos:
      server-addr: 127.0.0.1:8848
      config:
        # 指定命名空间
        namespace: dev

controller

java 复制代码
@RequestMapping("/product")
@RestController
public class ProductController {
    @Autowired
    private ProductService productService;

    @Value("${server.port}")
    private String port;

    @RequestMapping("getById")
    public String getById(@RequestParam("id") Integer id) {
        System.out.println("当前服务端口号: " + port);
        ProductDo productById = productService.getProductById(id);
        return productById.toString()+"==端口号:"+port;
    }
}

4、order-server服务

pom.xml

xml 复制代码
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         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.example</groupId>
        <artifactId>cloud-test</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>order-server</artifactId>
    <packaging>jar</packaging>

    <name>order-server</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</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>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

application.yml

yaml 复制代码
server:
  port: 8077

spring:
  application:
    name: order-server

  cloud:
    nacos:
      server-addr: 127.0.0.1:8848

ProductFeign

java 复制代码
package org.example.feign;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@FeignClient(value = "product-server", path = "product")
public interface ProductFeign {

    @RequestMapping("getById")
    String getById(@RequestParam("id") Integer id);
}

OrderController

java 复制代码
@RequestMapping("/api/order")
@RestController
public class OrderController {

    @Autowired
    private ProductFeign productFeign;

    @RequestMapping("create")
    public String create(@RequestParam(value = "uId", required = false) Integer uId,
                       @RequestParam(value = "pId", required = false) Integer pId) {
        return productFeign.getById(pId);
    }
}

注意启动文件上必须加上@EnableFeignClients注解

java 复制代码
@EnableFeignClients
@SpringBootApplication
public class OrderApplication
{
    public static void main( String[] args )
    {
        SpringApplication.run(OrderApplication.class, args);
    }
}

到这步就可以先实现openfeign调用nacos服务实例了(openfeign默认轮询负载均衡)

5、order-server整合Sentinel

在order-server服务中添加依赖

xml 复制代码
<dependency>
   <groupId>com.alibaba.cloud</groupId>
   <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
   <groupId>com.alibaba.csp</groupId>
   <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

nacos中新增Sentinel限流配置

bash 复制代码
[
  {
    "resource": "orderCreate",        // 资源名(要限流的方法名/接口名)
    "limitApp": "default",            // 限制的调用方(default=不区分调用方,所有应用都限制)
    "grade": 1,                       // 限流阈值类型(0=线程数,1=QPS)
    "count": 1,                       // 单机阈值(每秒最多允许 1 个请求)
    "strategy": 0,                    // 调用关系限流策略(0=直接,1=根据调用方,2=根据链路)
    "controlBehavior": 0,             // 流控效果(0=快速失败,1=预热,2=排队等待)
    "clusterMode": false              // 是否集群限流(false=单机限流)
  }
]

nacos中新增Sentinel降级配置

配置application.yml 将Sentinel持久化到nacos中

yaml 复制代码
spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080
      datasource:
        # 流控规则数据源
        flow:
          nacos:
            server-addr: 127.0.0.1:8848  # Nacos 地址
            dataId: service-order-flow-rules
            groupId: DEFAULT_GROUP
            rule-type: flow
            data-type: json
        # 熔断规则数据源
        degrade:
          nacos:
            server-addr: 127.0.0.1:8848  # Nacos 地址
            dataId: service-order-degrade-rules
            groupId: DEFAULT_GROUP
            rule-type: degrade
            data-type: json

启动order-server服务之后,调用接口,就自动配置到Sentinel中了。

6、整合seata

启动seata服务

在order-server和product-server服务中引入依赖

xml 复制代码
 <dependency>
    <groupId>com.alibaba.cloud</groupId>
     <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
 </dependency>

在cloud_product表和cloue_order表中 新增一个undo_log表

bash 复制代码
CREATE TABLE `undo_log` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `branch_id` bigint(20) NOT NULL,
  `xid` varchar(100) NOT NULL,
  `context` varchar(128) NOT NULL,
  `rollback_info` longblob NOT NULL,
  `log_status` int(11) NOT NULL,
  `log_created` datetime NOT NULL,
  `log_modified` datetime NOT NULL,
  `ext` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

新建seata数据库

bash 复制代码
-- -------------------------------- The script used when storeMode is 'db' --------------------------------
-- the table to store GlobalSession data
CREATE TABLE IF NOT EXISTS `global_table`
(
    `xid`                       VARCHAR(128) NOT NULL,
    `transaction_id`            BIGINT,
    `status`                    TINYINT      NOT NULL,
    `application_id`            VARCHAR(32),
    `transaction_service_group` VARCHAR(32),
    `transaction_name`          VARCHAR(128),
    `timeout`                   INT,
    `begin_time`                BIGINT,
    `application_data`          VARCHAR(2000),
    `gmt_create`                DATETIME,
    `gmt_modified`              DATETIME,
    PRIMARY KEY (`xid`),
    KEY `idx_status_gmt_modified` (`status` , `gmt_modified`),
    KEY `idx_transaction_id` (`transaction_id`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4;

-- the table to store BranchSession data
CREATE TABLE IF NOT EXISTS `branch_table`
(
    `branch_id`         BIGINT       NOT NULL,
    `xid`               VARCHAR(128) NOT NULL,
    `transaction_id`    BIGINT,
    `resource_group_id` VARCHAR(32),
    `resource_id`       VARCHAR(256),
    `branch_type`       VARCHAR(8),
    `status`            TINYINT,
    `client_id`         VARCHAR(64),
    `application_data`  VARCHAR(2000),
    `gmt_create`        DATETIME(6),
    `gmt_modified`      DATETIME(6),
    PRIMARY KEY (`branch_id`),
    KEY `idx_xid` (`xid`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4;

-- the table to store lock data
CREATE TABLE IF NOT EXISTS `lock_table`
(
    `row_key`        VARCHAR(128) NOT NULL,
    `xid`            VARCHAR(128),
    `transaction_id` BIGINT,
    `branch_id`      BIGINT       NOT NULL,
    `resource_id`    VARCHAR(256),
    `table_name`     VARCHAR(32),
    `pk`             VARCHAR(36),
    `status`         TINYINT      NOT NULL DEFAULT '0' COMMENT '0:locked ,1:rollbacking',
    `gmt_create`     DATETIME,
    `gmt_modified`   DATETIME,
    PRIMARY KEY (`row_key`),
    KEY `idx_status` (`status`),
    KEY `idx_branch_id` (`branch_id`),
    KEY `idx_xid` (`xid`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4;

CREATE TABLE IF NOT EXISTS `distributed_lock`
(
    `lock_key`       CHAR(20) NOT NULL,
    `lock_value`     VARCHAR(20) NOT NULL,
    `expire`         BIGINT,
    primary key (`lock_key`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4;

INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('AsyncCommitting', ' ', 0);
INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('RetryCommitting', ' ', 0);
INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('RetryRollbacking', ' ', 0);
INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('TxTimeoutCheck', ' ', 0);

在order-server和product-server 中application.yml新增配置

yaml 复制代码
spring:
    alibaba:
      seata:
        tx-service-group: default_tx_group

seata:
  registry:
    type: nacos
    nacos:
      server-addr: 127.0.0.1:8848
      application: seata-server
      group: SEATA_GROUP
  config:
    type: nacos
    nacos:
      server-addr: 127.0.0.1:8848
      application: seata-server
      group: SEATA_GROUP

测试分布式事务

加上 @GlobalTransactional注解:

java 复制代码
@RequestMapping("/api/order")
@RestController
public class OrderController {

    @Autowired
    private OrderService orderService;

    @RequestMapping("create")
    @SentinelResource(value = "orderCreate", blockHandler = "createBlockHandler")
    public String create(@RequestParam(value = "uId", required = false) Integer uId,
                         @RequestParam(value = "pId", required = false) Integer pId) {
        return orderService.createOrder(uId, pId, 1);
    }

    public String createBlockHandler(Integer uId, Integer pId, BlockException e) {
        return "新增order被限流,uId=" + uId;
    }
}
java 复制代码
@Slf4j
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, OrderDo> implements OrderService {

    @Resource
    private ProductFeign productFeign;

    @Override
    @GlobalTransactional
    @Transactional
    public String createOrder(Integer userId, Integer pid, Integer total) {
        OrderDo order = new OrderDo();
        order.setCount(total);
        order.setStorageId(pid);
        baseMapper.insert(order);
//
        log.info("扣减余额:"+Thread.currentThread().getName());

        productFeign.deduct(pid, total);
        int i = 1/0;
        return "新增订单成功";

    }

}

最终结果cloue_order表未新增,cloud_product表未修改。

7、整合gateway

新建gateway项目。

导入依赖

xml 复制代码
<dependencies>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

修改application.yml

yaml 复制代码
server:
  port: 8055

spring:
  application:
    name: gateway-server

  cloud:
    nacos:
      server-addr: 127.0.0.1:8848
    gateway:
      routes:
        - id: order-api
          uri: lb://order-server
          predicates:
            - Path=/api/order/**
        - id: product-api
          uri: lb://product-server
          predicates:
            - Path=/api/product/**

在order-server服务Controller中,新增一个方法

java 复制代码
@RequestMapping("/api/order")
@RestController
public class OrderController {

    @Autowired
    private OrderService orderService;

    @RequestMapping("getOrder")
    public String getOrder() {
        return "getorder";
    }

访问http://localhost:8055/api/order/getOrder。

相关推荐
IT_陈寒1 小时前
React性能优化踩的坑,这个错你可能也会犯
前端·人工智能·后端
zhangxingchao1 小时前
AI应用开发三:RAG技术与应用
前端·人工智能·后端
多敲代码防脱发2 小时前
Spring进阶(容器实现)
java·开发语言·后端·spring
可视之道2 小时前
工业物联网前端技术栈选型与性能优化实战
后端
星辰_mya2 小时前
彩云之上——[特殊字符]的架构师
java·后端·微服务·面试·架构
Full Stack Developme2 小时前
Spring-Core 解析
java·spring·rpc
LucianaiB3 小时前
参加高德 AI 发布会的一点感受:地图,正在变成 AI 的行动入口
后端
属于自己的天空3 小时前
一个文件让 Claude Code 理解你的项目:CLAUDE.md 从入门到精通
后端
jiangbo_dev3 小时前
还在手搓分布式事务?我把 Saga + Outbox 模板化后,新服务接入从 5 天压到 1 天
后端