SpringCloud 学习(一)简介和环境搭建

1. 简介

1.1 SpringCloud

SpringCloud 基于 SpringBoot 提供了一套微服务解决方案,包括服务注册与发现,配置中心,全链路监控,服务网关,负载均衡,熔断器等组件,除了 NetFlix 的开源组件做高度抽象封装之外,还有一些选型中立的开源组件。

SpringCloud 为开发人员提供了配置管理,服务发现,断路器,路由,微代理,事件总线,全局锁,决策竞争,分布式会话等快速构建分布式系统的工具。

SpringCloud 将各个成熟的服务框架组合起来,通过 SpringBoot 风格进行再封装,屏蔽了复杂的配置和实现原理,为开发者提供一个易部署易维护的分布式系统开发工具包。

1.2 SpringBoot 与 SpringCloud 的关系

  • SpringBoot 专注于开发单个微服务。
  • SpringCloud 是关注全局的微服务协调整理治理框架。

1.3 Dubbo 和 SpringCloud 技术选型

  • 一个成熟、传统的互联网架构

  • Dubbo 和 SpringCloud 对比

    Dubbo SpringCloud
    服务注册中心 Zookeeper SpringCloud NetFilx Eureka
    服务调度方式 RPC REST API
    服务监控 Dubbo-Monitor SpringBoot Admin
    断路器 不完善 SpringCloud NetFilx Hystrix
    服务网关 SpringCloud NetFilx Zuul
    分布式配置 SpringCloud Config
    服务跟踪 SpringCloud Sleuth
    消息总线 SpringCloud Bus
    数据流 SpringCloud Stream
    批量处理 SpringCloud Task

    SpringCloud 抛弃了 Dubbo 的 RPC 通信,采用 HTTP 的 REST 方式。

    SpringCloud 能够与 Spring 项目完美融合。

1.4 下载地址

1.5 版本控制

版本说明

SpringBoot SpringCloud 关系
1.2.x Angel(天使) 兼容 Spring Boot 1.2.x
1.3.x Brixton(布里克斯顿) 兼容 Spring Boot 1.3.x,Spring Boot 1.4.x
1.4.x Camden(卡姆登) 兼容 Spring Boot 1.4.x,Spring Boot 1.5.x
1.5.x Dalston(多尔斯顿) 兼容 Spring Boot 1.5.x,不兼容 Spring Boot 2.0.x
1.5.x Edgware(埃奇韦尔) 兼容 Spring Boot 1.5.x,不兼容 Spring Boot 2.0.x
2.0.x Finchley(芬奇利) 兼容 Spring Boot 2.0.x,不兼容 Spring Boot 1.5.x
2.1.x Greenwich(格林威治)

版本关系

| spring-boot-starter-parent || spring-cloud-dependencies ||

版本号 发布日期 版本号 发布日期
1.5.2.RELEASE 2017年3月 Dalston.RC1 2017年未知月
1.5.9.RELEASE Nov.2017 Edgware.RELEASE Nov.2017
1.5.16.RELEASE Sep.2018 Edgware.SR5 Oct.2018
1.5.20.RELEASE Apr.2019 Edgware.SR5 Oct.2018
2.0.2.RELEASE May.2018 Finchley.BUILD-SNAPSHOT 2018年未知月
2.0.6.RELEASE Oct.2018 Finchley.SR2 Oct.2018
2.1.4.RELEASE Apr.2019 Greenwich.SR1 Mar.2019

2. 环境搭建

(1) 创建一个基础的 maven 项目

  • 删除 src 目录,将此项目作为父项目 springcloud

  • 管理依赖

    xml 复制代码
    <!--打包方式-->
    <packaging>pom</packaging>
    
    <!--版本控制-->
    <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>
        <lombok.version>1.16.10</lombok.version>
        <log4j.version>1.2.17</log4j.version>
    </properties>
    
    <!--依赖管理(不显示在 Libraries 中)-->
    <dependencyManagement>
        <dependencies>
            <!--springcloud-->
            <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-dependencies -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--springboot-->
            <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-dependencies -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.1.4.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--数据库-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.47</version>
            </dependency>
            <!--数据源-->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>1.1.10</version>
            </dependency>
            <!--springboot 启动器-->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>1.3.2</version>
            </dependency>
            <!--日志和测试-->
            <!--junit-->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
            </dependency>
            <!--lombok-->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
            </dependency>
            <!--log4j-->
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>${log4j.version}</version>
            </dependency>
            <!--logback-->
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-core</artifactId>
                <version>1.2.3</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

(2) 创建一个 maven 模块作为 api 服务

springcloud-api

● 导入依赖

xml 复制代码
<!--pom.xml-->
<artifactId>springcloud-api</artifactId>
<!--若是 springcloud (父项目)管理的依赖,则使用父项目的依赖,无需添加版本-->
<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
</dependencies>

● 创建数据库

● 编写实体类

java 复制代码
@Data
@NoArgsConstructor
/**
 * 链式写法
 * Dept dept = new Dept();
 * dept.setDeptNo(1).setDname("why").setDb_source("cloud01");
 */
@Accessors(chain = true)
public class Dept implements Serializable {

    // 主键
    private Long deptno;

    private String dname;

    // 数据所在数据库
    private String db_source;

    public Dept(String dname) {
        this.dname = dname;
    }
}

(3) 创建一个 maven 模块作为 provider 服务

springcloud-provider-dept-8001

● 导入依赖

xml 复制代码
<!--pom.xml-->
<artifactId>springcloud-provider-dept-8001</artifactId>

<dependencies>
    <!--api moudle-->
    <dependency>
        <groupId>org.example</groupId>
        <artifactId>springcloud-api</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-core</artifactId>
    </dependency>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
    </dependency>
    <!--test-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-test</artifactId>
    </dependency>
    <!--web-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--jetty-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jetty</artifactId>
    </dependency>
    <!--热部署工具-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
    </dependency>
</dependencies>

● 编写 mybatis 配置文件(回顾)

xml 复制代码
<!--resources/mybatis/mybatis-config.xml-->
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

<!--核心配置文件-->
<configuration>
    <settings>
        <!--开启二级缓存-->
        <setting name="cacheEnabled" value="true"/>
    </settings>
</configuration> 

● 编写应用配置文件

yaml 复制代码
# resources/application.yml
server:
  port: 8001
# mybatis
mybatis:
  type-aliases-package: com.why.springcloud.pojo
  config-location: classpath:mybatis/mybatis-config.xml
  mapper-locations: classpath:mybatis/mapper/*.xml

# spring配置
spring:
  application:
    name: springcloud-provider-dept
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: org.gjt.mm.mysql.Driver
    url: jdbc:mysql://localhost:3306/cloud01?useUnicode=true&characterEncoding=utf-8
    username: root
    password: 981030

● 编写 dao 和 service

java 复制代码
@Mapper
@Repository
public interface DeptDao {

    public boolean addDept(Dept dept);

    public Dept queryById(Long id);

    public List<Dept> queryAll();
}
java 复制代码
public interface DeptService {

    public boolean addDept(Dept dept);

    public Dept queryById(Long id);

    public List<Dept> queryAll();

}
java 复制代码
@Service
public class DeptServiceImpl implements DeptService {

    @Autowired
    DeptDao deptDao;

    @Override
    public boolean addDept(Dept dept) {
        return deptDao.addDept(dept);
    }

    @Override
    public Dept queryById(Long id) {
        return deptDao.queryById(id);
    }

    @Override
    public List<Dept> queryAll() {
        return queryAll();
    }
}

● 编写 controller 和 启动类

java 复制代码
@RestController
public class DeptController {

    @Autowired
    private DeptService deptService;

    // 此方法为 Post 请求方式,浏览器直接输入 url 方式无法访问,但是 consumer 服务可以调用并访问
    @PostMapping("/dept/add")
    public boolean addDept(@RequestBody Dept dept) {
        return deptService.addDept(dept);
    }

    @GetMapping("/dept/getDept/{id}")
    public Dept getDept(@PathVariable("id") Long id) {
        return deptService.queryById(id);
    }

    @GetMapping("/dept/list")
    public List<Dept> queryAll() {
        return deptService.queryAll();
    }
    
}
java 复制代码
@SpringBootApplication
public class DeptProvider_8001 {
    public static void main(String[] args) {
        SpringApplication.run(DeptProvider_8001.class, args);
    }
}

● 错误解决

text 复制代码
java.lang.IllegalStateException: Failed to load property source from location 'classpath:/application.yml'

Caused by: org.yaml.snakeyaml.error.YAMLException: java.nio.charset.MalformedInputException: Input length = 1

Caused by: java.nio.charset.MalformedInputException: Input length = 1

file was loaded in the wrong encoding utf-8
  • 删除 application.yml 文件,重新创建编写

(4) 创建一个 maven 模块作为 consumer 服务

springcloud-consumer-dept-80

● 导入依赖

xml 复制代码
<artifactId>springcloud-consumer-dept-80</artifactId>

<!--实体类 + web-->
<dependencies>
    <dependency>
        <groupId>org.example</groupId>
        <artifactId>springcloud-api</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
    </dependency>
</dependencies>

● 设置服务端口

yaml 复制代码
# resources/application.yml
server:
  port: 80

● 将 RestTemplate 注册到 spring 中

java 复制代码
// config
@Configuration  // spring applicationContext.xml
public class ConfigBean {

    // 注册 bean <bean></bean>
    @Bean
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
}

● 编写控制器和主类

java 复制代码
@RestController
public class DeptConsumerController {

    // 提供访问远程 http 服务的方法
    @Autowired
    private RestTemplate restTemplate;

    private static final String REST_URL_PREFIX = "http://localhost:8001";

    @RequestMapping("/consumer/dept/add")
    public boolean add(Dept dept) {
        return restTemplate.postForObject(REST_URL_PREFIX+"/dept/add", dept, Boolean.class);
    }

    @RequestMapping("/consumer/dept/getDept/{id}")
    public Dept getDept(@PathVariable("id") Long id) {
        return restTemplate.getForObject(REST_URL_PREFIX+"/dept/getDept/"+id, Dept.class);
    }

    @RequestMapping("/consumer/dept/list")
    public List<Dept> list() {
        return restTemplate.getForObject(REST_URL_PREFIX+"/dept/list", List.class);
    }


}
java 复制代码
@SpringBootApplication
public class DeptConsumer_80 {

    public static void main(String[] args) {
        SpringApplication.run(DeptConsumer_80.class, args);
    }
}
相关推荐
武子康6 分钟前
大数据-212 数据挖掘 机器学习理论 - 无监督学习算法 KMeans 基本原理 簇内误差平方和
大数据·人工智能·学习·算法·机器学习·数据挖掘
使者大牙15 分钟前
【大语言模型学习笔记】第一篇:LLM大规模语言模型介绍
笔记·学习·语言模型
As977_38 分钟前
前端学习Day12 CSS盒子的定位(相对定位篇“附练习”)
前端·css·学习
ajsbxi40 分钟前
苍穹外卖学习记录
java·笔记·后端·学习·nginx·spring·servlet
Rattenking41 分钟前
React 源码学习01 ---- React.Children.map 的实现与应用
javascript·学习·react.js
dsywws1 小时前
Linux学习笔记之时间日期和查找和解压缩指令
linux·笔记·学习
鹿屿二向箔1 小时前
基于SSM(Spring + Spring MVC + MyBatis)框架的咖啡馆管理系统
spring·mvc·mybatis
道法自然04021 小时前
Ethernet 系列(8)-- 基础学习::ARP
网络·学习·智能路由器
爱吃生蚝的于勒1 小时前
深入学习指针(5)!!!!!!!!!!!!!!!
c语言·开发语言·数据结构·学习·计算机网络·算法
NoneCoder2 小时前
Java企业级开发系列(1)
java·开发语言·spring·团队开发·开发