SpringCloud概述和学习项目预搭建

前言:有幸看到尚硅谷3月刚发布的 Spring Cloud 教学视频,使用了spring cloud最新版本和技术,该系列为看该教学视频记录的学习笔记。

视频地址:尚硅谷2020最新版SpringCloud(H版&alibaba)框架开发教程全套完整版从入门到精通(大牛讲授spring cloud)_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili

微服务概述

微服务体系结构的思想提倡将大型软件拆分成一个个微小的服务,相对于面向服务软件架构(SOA)拆分粒度更小,最好是拆分成原子性服务,即不可以再继续拆分,服务之间的耦合度更低。不同于面向服务软件架构,微服务架构中没有企业服务总线,服务的调用流程不是在总线中固定顺序,取而代之的是一种 api 网关的方式统一编排微服务,api 网关不负责服务的调用顺序,只对客户端传来的请求进行路由,对众多的微服务接口进行聚合。

Spring Cloud

Spring Cloud 是一系列框架的有序集合。它利用 Spring Boot 的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用 Spring Boot 的开发风格做到一键启动和部署。Spring Cloud 并没有重复制造轮子,它只是将各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过 Spring Boot 风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。

  • 服务注册与发现 eureka->zookeeper/consul/nacos
  • 服务调用与负载均衡 ribbon/loadbalancer feign/openfeign
  • 服务熔断&&降级 hystrix -> resilience4j/spring alibaba sentinel
  • 服务消息队列
  • 配置中心管理 spring cloud config/nacos
  • 服务网关 netflix oss zuul/spring cloud gateway
  • 服务监控
  • 全链路追踪
  • 自动化构建部署
  • 服务定时任务调度操作

版本说明

SpringBoot

SpringBoot:截至 2020/03/19,最新版本 2.2.5

SpringCloud

Spring Cloud 采用了英国伦敦地铁站的名称来命名,并由地铁站名称字母 A-Z 依次类推的形式来发布迭代版本。

SpringCloud 是一个由许多子项目组成的综合项目,各子项目有不同的发布节奏。为了管 SpringCloud 与各子项目的版本依赖关系,发布了一个清单,其中包括了某个 SpringCloud 版本对应的子项目版本。为了避免 SpringCloud 版本号与子项目版本号混淆,SpringCloud 版本采用了名称而非版本号的命名,这些版本的名字采用了伦敦地铁站的名字,根据字母表的顺序来对应版本时间顺序。例如 Angel 是第一个版本, Brixton 是第二个版本。

最新版本是 Hoxton。

SpringBoot 和 SpringCloud 的版本对应关系查看: https://start.spring.io/actuator/info

选用版本

框架/软件 版本
spring cloud Hoxton.SR1
spring boot 2.2.2. RELEASE
spring cloud alibaba 2.1.0.RELEASE
Java Java8
Maven 3.5 及以上
Mysql 5.7 及以上

maven dependencyManagement

父 pom 通常会使用 dependencyManagement 管理子项目的版本号

<!--统一管理jar包版本-->
<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <junit.version>4.12</junit.version>
    <log4j.version>1.2.17</log4j.version>
    <lombok.version>1.16.18</lombok.version>
    <mysql.version>8.0.19</mysql.version>
    <druid.version>1.1.16</druid.version>
    <druid.spring.boot.starter.version>1.1.10</druid.spring.boot.starter.version>
    <spring.boot.version>2.2.2.RELEASE</spring.boot.version>
    <spring.cloud.version>Hoxton.SR1</spring.cloud.version>
    <spring.cloud.alibaba.version>2.1.0.RELEASE</spring.cloud.alibaba.version>
    <mybatis.spring.boot.version>1.3.0</mybatis.spring.boot.version>
</properties>

<!--子模块继承后,提供作用:锁定版本+子module不用groupId和version-->
<dependencyManagement>
    <dependencies>
        <!--springboot 2.2.2-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>{spring.boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <!--Spring cloud Hoxton.SR1-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>{spring.cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <!--Spring cloud alibaba 2.1.0.RELEASE-->
        <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>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>{mysql.version}</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>{druid.version}</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>{druid.spring.boot.starter.version}</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>{mybatis.spring.boot.version}</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>{lombok.version}</version>
        </dependency>
    </dependencies>
</dependencyManagement>

环境预搭建-订单模块

新建子模块cloud-provider-payment8001

pom

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--监控-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <!--如果没写版本,从父层面找,找到了就直接用,全局统一-->
        <version>${druid.spring.boot.starter.version}</version>
    </dependency>
    <!--mysql-connector-java-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <!--jdbc-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

建表:

create database cloud2020;
use cloud2020;
CREATE TABLE `payment`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `serial` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '支付流水号',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '支付表' ROW_FORMAT = Dynamic;

yaml配置

server:
  port: 8001
spring:
  application:
    name: cloud-payment-service
  datasource:
    # 当前数据源操作类型
    type: com.alibaba.druid.pool.DruidDataSource
    # mysql驱动类
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/cloud2020?useUnicode=true&characterEncoding=UTF-8&useSSL=false
    username: root
    password: 123456

mybatis:
  mapperLocations: classpath*:mapper/*.xml
  type-aliases-package: com.rhett.springcloud.entities

业务类

POJO

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Payment implements Serializable {
    private Long id;
    private String serial;
}

统一数据响应实体类:

/**
 * 与前端交互的统一数据响应接口
 * @param <T>
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CommonResult<T> {
    private Integer code;
    private String  message;
    private T       data;

    public CommonResult(Integer code,String message){
        this(code,message,null);
    }
}

Dao

@Mapper
public interface PaymentDao {
    public int create(Payment payment);
    public Payment getPaymentById(@Param("id") Long id);
}

mapper文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.rhett.springcloud.dao.PaymentDao">
    <insert id="create" parameterType="Payment" useGeneratedKeys="true" keyProperty="id">
        insert into payment(serial) values(#{serial});
    </insert>

    <resultMap id="BaseResultMap" type="com.rhett.springcloud.entities.Payment">
        <id column="id" property="id" jdbcType="BIGINT"/>
        <id column="serial" property="serial" jdbcType="VARCHAR"/>
    </resultMap>
    <select id="getPaymentById" parameterType="Long" resultMap="BaseResultMap">
        select * from payment where id=#{id};
    </select>
</mapper>

service

接口:

public interface PaymentService {
    public int create(Payment payment);
    public Payment getPaymentById(Long id);
}

实现:

@Service
public class PaymentServiceImpl implements PaymentService {
    @Resource
    private PaymentDao paymentDao;

    @Override
    public int create(Payment payment) {
        return paymentDao.create(payment);
    }

    @Override
    public Payment getPaymentById(Long id) {
        return paymentDao.getPaymentById(id);
    }
}

controller

@RestController
@Slf4j
public class PaymentController {
    @Resource
    private PaymentService paymentService;

    @PostMapping(value = "/payment")
    public CommonResult create(Payment payment){
        int result = paymentService.create(payment);
        log.info("****插入结果:"+result);
        if(result>0){
            return new CommonResult(200,"插入数据库成功",result);
        }else {
            return new CommonResult(500,"插入数据库失败");
        }
    }

    @GetMapping(value = "/payment/{id}")
    public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id){
        Payment payment = paymentService.getPaymentById(id);
        log.info("****插入结果:"+payment);
        if(payment!=null){
            return new CommonResult(200,"查询成功",payment);
        }else {
            return new CommonResult(500,"没有对应记录,查询ID:"+id);
        }
    }
}

热部署配置

添加依赖:

<!--热部署-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <scope>runtime</scope>
    <optional>true</optional>
</dependency>

在IDEA设置=>Compiler,勾上如下图配置

SpringCloud概述和学习项目预搭建

快捷键CTRL+SHIFT+ALT+/选择registry,勾上如下图配置

SpringCloud概述和学习项目预搭建

环境预搭建-消费者订单模块

将即将用到的模块中的公共业务类抽取到一个新的模块cloud-api-commons,使用依赖引入:

SpringCloud概述和学习项目预搭建

新建模块cloud-consumer-order80

pom

<dependencies>
    <dependency>
        <groupId>com.rhett</groupId>
        <artifactId>cloud-api-commons</artifactId>
        <version>${project.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--监控-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <!--热部署-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

yaml配置

server:
  port: 80

配置类

@Configuration
public class ApplicationContextConfig {
    @Bean
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

controller

@RestController
public class OrderController {
    public static final String PAYMENT_URL = "http://localhost:8001";

    @Resource
    private RestTemplate restTemplate;

    @PostMapping("/consumer/payment")
    public CommonResult<Payment> create(Payment payment){
        return restTemplate.postForObject(PAYMENT_URL+"/payment", payment,CommonResult.class);
    }
    @GetMapping("/consumer/payment/{id}")
    public CommonResult<Payment> getPayment(@PathVariable("id") Long id){
        return restTemplate.getForObject(PAYMENT_URL+"/payment/"+id,CommonResult.class);
    }
}

最后的项目结构:

SpringCloud概述和学习项目预搭建

这样一个简单的微服务模块就构建完成了,后面要学的eureka会基于该项目。

原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/springcloud%e6%a6%82%e8%bf%b0%e5%92%8c%e5%ad%a6%e4%b9%a0%e9%a1%b9%e7%9b%ae%e9%a2%84%e6%90%ad%e5%bb%ba/