Spring Cloud Alibaba入门

Posted by Kaka Blog on November 27, 2020

前言

Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。

依托 Spring Cloud Alibaba,您只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接入阿里微服务解决方案,通过阿里中间件来迅速搭建分布式应用系统。

主要功能

  • 服务限流降级:默认支持 WebServlet、WebFlux, OpenFeign、RestTemplate、Spring Cloud Gateway, Zuul, Dubbo 和 RocketMQ 限流降级功能的接入,可以在运行时通过控制台实时修改限流降级规则,还支持查看限流降级 Metrics 监控。
  • 服务注册与发现:适配 Spring Cloud 服务注册与发现标准,默认集成了 Ribbon 的支持。
  • 分布式配置管理:支持分布式系统中的外部化配置,配置更改时自动刷新。
  • 消息驱动能力:基于 Spring Cloud Stream 为微服务应用构建消息驱动能力。
  • 分布式事务:使用 @GlobalTransactional 注解, 高效并且对业务零侵入地解决分布式事务问题。

快速入门

项目结构

  • producer01: 9091
  • producer02: 8091
  • consumer: 8092

创建项目框架

引入依赖:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.7.RELEASE</version>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>2.1.7.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        <version>2.1.3.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        <version>2.1.3.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</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>

创建producer01模块

创建业务代码:

@Slf4j
@RestController
public class OrderController {
    @GetMapping("order/{username}/{goodsId}/{amount}/create")
    public String createOrder(@PathVariable("username") String username, @PathVariable("goodsId") String goodsId,
                              @PathVariable("amount") String amount) {
        log.info("创建订单:" + username + ", 商品:" + goodsId + ", 价格:" + amount);
        return "success";
    }
}

创建producer02模块

创建业务代码:

@Slf4j
@RestController
public class StockController {
    @GetMapping("stock/{goodsId}/reduce")
    public String reduceStock(@PathVariable("goodsId") String goodsId) {
        log.info("库存减少:, 商品:" + goodsId );
        return "success";
    }

创建consumer模块

引入依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    <version>RELEASE</version>
</dependency>

启动类增加注解:@EnableFeignClients

feign实现接口调用:

@FeignClient(name = "producer01")
public interface OrderService {
    @GetMapping("order/{username}/{goodsId}/{amount}/create")
    String createOrder(@PathVariable("username") String username, @PathVariable("goodsId") String goodsId,
                              @PathVariable("amount") String amount);
}

@FeignClient(name = "producer02", fallback = StockFallback.class)
public interface StockService {
    @GetMapping("stock/{goodsId}/reduce")
    String reduceStock(@PathVariable("goodsId") String goodsId);
}

实现降级处理:

@Slf4j
@Component
public class StockFallback implements StockService {
    @Override
    public String reduceStock(String goodsId) {
        log.info("降级处理,记录到日志:" + goodsId);
        return "fallback";
    }
}

配置文件:

#哨兵
spring.cloud.sentinel.transport.dashboard=localhost:8080
#打开sentinel
feign.sentinel.enabled=true

实现调用:

@Slf4j
@RestController
public class CallController {
    @Autowired
    private OrderService orderService;
    @Autowired
    private StockService stockService;

    @GetMapping("buy/{username}/{goodsId}/{amount}/create")
    public String createOrder(@PathVariable("username") String username, @PathVariable("goodsId") String goodsId,
                       @PathVariable("amount") String amount) {
        orderService.createOrder(username, goodsId, amount);
        stockService.reduceStock(goodsId);
        return "success";
    }
}

下载sentinel,下载地址https://github.com/alibaba/Sentinel/releases/tag/v1.8.0

启动sentinel,用户和密码都是sentinel。

测试

1、服务都启动,访问http://localhost:8092/buy/fang/123/100/create,可以正常返回。

2、关闭procuder02服务,访问http://localhost:8092/buy/fang/123/100/create,可以正常返回。同时在控制台可以看到降级日志打印。

3、sentinel设置流量控制,访问多次后返回:** limit

4、sentinel设置熔断,当到达熔断条件时,服务在一段时间内直接走降级服务,不再调用远程服务。

总结

  • 降级:当服务不可用时,调用本地服务,可以防止雪崩,实现高可用。
  • 熔断:当服务异常达到设定的阀值时,在设定周期内不再调用远程服务,不用再消耗时间去请求接口。

参考资料