一、SpringCloudAlibaba介绍
1、SpringCloudAlibaba致力于提供微服务开发的一站式解决方案,此项目包含分布式应用微服务的必须组件,方便开发者通过SpringCloud编程模型轻松使用这些组件来开发分布式应用服务。开发者只需要添加一些注解和少量配置,就可以将SpringCloud应用接入阿里微服务解决方案,通过阿里中间件迅速搭建分布式应用系统。
2、主要功能

1、==服务限流降级==:默认支持WebServlet、WebFlux、OpenFeign、RestTemplate、
SpringCloudGateway、Zuul、Dubbo、RocketMQ限流降级功能的接入,可以在运行时通过控制台实时
修改限流降级规则,还支持限流降级Metircs监控。
2、服务注册与发现:适配SpringCloud服务注册与发现,默认集成Ribbon的支持
3、分布式配置管理:支持分布式系统中的外部化配置,配置更改时自动刷新
4、消息驱动能力:基于Spring Cloud Stream为微服务应用构建消息驱动能力
5、分布式事务:使用@GlobalTransactional注解,高效且对业务零侵入的解决分布式事务问题。
6、阿里云对象存储:阿里云提供海量、安全、低成本、高可靠的云存储服务,支持任何应用,任何时间,
任何地点存储和访问任意类型的数据
7、分布式任务调度:提供秒级,精准、高可靠、高可用(cron表达式)任务调度服务,同时提供分布式任务模型,
如网格任务,网格任务支持海量子任务均匀分配到所有的Worker上执行
8、阿里云短信服务

3、主要组件

1、Sentinel:吧流量作为切入点,从流量控制,熔断降级,系统负载保护等多个维度保护服务的稳定性。
2、Nacos:构建云原生态的服务发现,配置管理,和服务管理平台。
3、RocketMQ:开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的,
高可靠的消息发布与订阅服务。
4、Dubbo:Apache Dubbo 高性能RPC框架
5、Seata:高性能微服务分布式事务解决方案
6、Alibaba Cloud ACM:分布式架构环境中对应用配置集中管理和推送的应用配置中心产品(收费)
7、Alibaba Cloud OSS:阿里云对象存储服务(收费)
8、Alibaba Cloud SchedulerX:分布式任务调度服务(收费)
9、Alibaba Cloud SMS:短信服务(收费)

本项目以电商项目中的商品、订单、用户为例,简述各个组件的使用方式。
二、 环境搭建
1、技术选型
maven:3.3.9
数据库:Mysql5.7
持久层:SpringData Jpa
其他:SpringCloudAlibaba
2、模块设计
springcloud-alibaba 父工程
shop-common 公共模块
shop-user 用户微服务【端口807x
shop-product 商品微服务【端口808x
shop-order 订单微服务 【端口809x
3、创建父工程 springcloud-alibaba-chenchen

<?xml version="1.0" encoding="UTF-8"?>
<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>com.chenchen</groupId>
    <artifactId>springcloud-alibaba-chenchen</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>shop-common</module>
    </modules>
    <!--指定父依赖-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.3.RELEASE</version>
    </parent>
    <!--依赖版本锁定-->
    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
        <spring-cloud.alibaba.version>2.1.0.RELEASE</spring-cloud.alibaba.version>
    </properties>
    <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>
            <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>
        </dependencies>
    </dependencyManagement>
</project>

4、创建公共模块 shop-common,添加实体User、Order、Product

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <parent>
        <artifactId>springcloud-alibaba-chenchen</artifactId>
        <groupId>com.chenchen</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>shop-common</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.56</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
    </dependencies>
</project>

公共模块代码层级

springcloudalibaba seata失效 springcloudalibaba服务调用_spring boot


实体Order

package com.chenchen.entity;

import lombok.Data;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity(name = "shop_order")
@Data
public class Order {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer oid;
    private Integer uid;
    //商品名称
    private String username;

    private Integer pid;
    //商品名称
    private String pname;
    //商品价格
    private Double pprice;
    //购买数量
    private Integer number;
}

实体User

package com.chenchen.entity;

import lombok.Data;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity(name = "shop_user")
@Data
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)//数据库自增
    private Integer uid;
    //用户名
    private String username;
    //密码
    private String password;
    //手机号
    private String telephone;
}

实体Product

package com.chenchen.entity;

import lombok.Data;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity(name = "shop_product")
@Data
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer pid;
    //商品名称
    private String pname;
    //商品价格
    private Double pprice;
    //库存
    private Integer stock;
}

5、依次创建shop-user、shop-order、shop-product三个子工程
5.1 shop-user

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <parent>
        <artifactId>springcloud-alibaba-chenchen</artifactId>
        <groupId>com.chenchen</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>shop-user</artifactId>
    <packaging>pom</packaging>
    <modules>
        <module>../shop-order</module>
    </modules>

    <dependencies>
        <!--springboot-web 表明当前是web工程-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--引入公共模块-->
        <dependency>
            <groupId>com.chenchen</groupId>
            <artifactId>shop-common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>

启动类创建

package com.chenchen;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class UserApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserApplication.class, args);
        System.out.println("用户微服务启动成功");
    }
}

配置文件

server:
  port: 8071
spring:
  application:
    name: service-user
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/shop?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
    username: root
    password: root
  jpa:
    properties:
      hibernate:
        hbm2ddl:
          auto: update
        dialect: org.hibernate.dialect.MySQL5InnoDBDialect

包层次结构

springcloudalibaba seata失效 springcloudalibaba服务调用_spring boot_02


剩下的shop-order、shop-product工程依次类推。

注意点:服务消费者不应该有service,因为它只需要调用服务提供者

需求:模拟用户下单操作。用户查看商品生成订单

springcloudalibaba seata失效 springcloudalibaba服务调用_spring boot_03


6、编写商品微服务查询方法

6.1 controller

package com.chenchen.controller;

import com.chenchen.entity.Product;
import com.chenchen.service.IProductService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Slf4j
public class ProductController {
    @Autowired
    private IProductService productService;

    /**
     * 根据商品id查询商品
     *
     * @param id
     * @return
     */
    @RequestMapping("/findProductById/{id}")
    public Product findProductById(@PathVariable Integer id) {
        log.info("开始查询第:{}号商品",id);
        return productService.findProductById(id);
    }
}

6.2 service

package com.chenchen.service.impl;

import com.alibaba.fastjson.JSON;
import com.chenchen.entity.Product;
import com.chenchen.mapper.ProductMapper;
import com.chenchen.service.IProductService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class ProductServiceImpl implements IProductService {
    @Autowired
    private ProductMapper productMapper;

    /**
     * 根据商品id查询商品信息
     *
     * @param id
     * @return
     */
    @Override
    public Product findProductById(int id) {
        Product product = productMapper.findById(id).get();

        log.info("查询到:{}号商品信息:{}", id,  JSON.toJSONString(product));
        return product;
    }
}

6.3 浏览器测试:http://localhost:8081/findProductById/1 7、编写订单微服务,模拟下单操作.
7.1 controller

package com.chenchen.controller;


import com.chenchen.entity.Order;
import com.chenchen.service.IOrderService;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
public class OrderController {
    @Autowired
    private IOrderService orderService;

    @RequestMapping("/createOrder/{pid}")
    public Order createOrder(@PathVariable Integer pid) {
        Order order = new Order();
 
        order.setNumber(2);
        order.setUid(1);
        order.setUsername("chenchen");

        order.setPid(pid);
        order.setPname("huawei");
        order.setPprice(8888.8);
        return orderService.createOrder(order);
    }
}

7.2 service

package com.chenchen.service.impl;

import com.chenchen.entity.Order;
import com.chenchen.mapper.OrderMapper;
import com.chenchen.service.IOrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.concurrent.Executor;

/**
 *
 */
@Service
@Slf4j
public class OrderServiceImpl implements IOrderService {
    @Autowired
    private OrderMapper orderMapper;

    @Transactional
    @Override
    public Order createOrder(Order order) {
        Order entity = null;
        try {
            entity = orderMapper.save(order);
            log.info("下单成功,订单信息{}",entity.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return entity;
    }
}

浏览器测试:http://localhost:8092/createOrder/1 此时已经可以模拟下单了,但是实际情况是 我们需要调用商品微服务查询商品信息,调用方式很简单,使用模板方法RestTemplate,只需要将它放入bean容器中就好了

springcloudalibaba seata失效 springcloudalibaba服务调用_maven_04

此时我们在controller层注入restplate,使用它的内置方法getForObject()即可。

package com.chenchen.controller;
import com.chenchen.entity.Order;
import com.chenchen.entity.Product;
import com.chenchen.service.IOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;


@RestController
public class OrderController {
    @Autowired
    private IOrderService orderService;
    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping("/createOrder/{pid}")
    public Order createOrder(@PathVariable Integer pid) {
        String url="http://localhost:8081/findProductById/";
        Product product = restTemplate.getForObject(url+pid, Product.class);
        Order order = new Order();
        order.setOid(1);
        order.setNumber(2);
        order.setUid(1);
        order.setUsername("chenchen");

        order.setPid(product.getPid());
        order.setPname(product.getPname());
        order.setPprice(product.getPprice());
        return orderService.createOrder(order);
    }
}