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 下载地址
-
SpringCloud 官网:Spring Cloud
-
Spring Cloud NetFlix 中文文档:Spring Cloud Netflix 中文文档 参考手册 中文版
-
Spring Cloud 中文文档:Spring Cloud Dalston 中文文档 参考手册 中文版
-
Spring Cloud 中文网:Spring Cloud中文网-官方文档中文版
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
-
管理依赖
<!--打包方式--> <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
● 导入依赖
<!--pom.xml-->
<artifactId>springcloud-api</artifactId>
<!--若是 springcloud (父项目)管理的依赖,则使用父项目的依赖,无需添加版本-->
<dependencies><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>
</dependencies>
● 创建数据库
● 编写实体类
@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
● 导入依赖
<!--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 配置文件(回顾)
<!--resources/mybatis/mybatis-config.xml-->
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><!--核心配置文件-->
<configuration><settings><!--开启二级缓存--><setting name="cacheEnabled" value="true"/></settings>
</configuration>
● 编写应用配置文件
# resources/application.yml
server:port: 8001
# mybatis
mybatis:type-aliases-package: com.why.springcloud.pojoconfig-location: classpath:mybatis/mybatis-config.xmlmapper-locations: classpath:mybatis/mapper/*.xml# spring配置
spring:application:name: springcloud-provider-deptdatasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: org.gjt.mm.mysql.Driverurl: jdbc:mysql://localhost:3306/cloud01?useUnicode=true&characterEncoding=utf-8username: rootpassword: 981030
● 编写 dao 和 service
@Mapper
@Repository
public interface DeptDao {public boolean addDept(Dept dept);public Dept queryById(Long id);public List<Dept> queryAll();
}
public interface DeptService {public boolean addDept(Dept dept);public Dept queryById(Long id);public List<Dept> queryAll();}
@Service
public class DeptServiceImpl implements DeptService {@AutowiredDeptDao deptDao;@Overridepublic boolean addDept(Dept dept) {return deptDao.addDept(dept);}@Overridepublic Dept queryById(Long id) {return deptDao.queryById(id);}@Overridepublic List<Dept> queryAll() {return queryAll();}
}
● 编写 controller 和 启动类
@RestController
public class DeptController {@Autowiredprivate 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();}}
@SpringBootApplication
public class DeptProvider_8001 {public static void main(String[] args) {SpringApplication.run(DeptProvider_8001.class, args);}
}
● 错误解决
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 = 1Caused by: java.nio.charset.MalformedInputException: Input length = 1file was loaded in the wrong encoding utf-8
- 删除 application.yml 文件,重新创建编写
(4) 创建一个 maven 模块作为 consumer 服务
springcloud-consumer-dept-80
● 导入依赖
<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>
● 设置服务端口
# resources/application.yml
server:port: 80
● 将 RestTemplate 注册到 spring 中
// config
@Configuration // spring applicationContext.xml
public class ConfigBean {// 注册 bean <bean></bean>@Beanpublic RestTemplate getRestTemplate() {return new RestTemplate();}
}
● 编写控制器和主类
@RestController
public class DeptConsumerController {// 提供访问远程 http 服务的方法@Autowiredprivate 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);}}
@SpringBootApplication
public class DeptConsumer_80 {public static void main(String[] args) {SpringApplication.run(DeptConsumer_80.class, args);}
}