SpringCloud 基于 SpringBoot 提供了一套微服务解决方案,包括服务注册与发现,配置中心,全链路监控,服务网关,负载均衡,熔断器等组件,除了 NetFlix 的开源组件做高度抽象封装之外,还有一些选型中立的开源组件。
SpringCloud 为开发人员提供了配置管理,服务发现,断路器,路由,微代理,事件总线,全局锁,决策竞争,分布式会话等快速构建分布式系统的工具。
SpringCloud 将各个成熟的服务框架组合起来,通过 SpringBoot 风格进行再封装,屏蔽了复杂的配置和实现原理,为开发者提供一个易部署易维护的分布式系统开发工具包。
一个成熟、传统的互联网架构
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 项目完美融合。
SpringCloud 官网:Spring Cloud
Spring Cloud NetFlix 中文文档:Spring Cloud Netflix 中文文档 参考手册 中文版
Spring Cloud 中文文档:Spring Cloud Dalston 中文文档 参考手册 中文版
Spring Cloud 中文网:Spring Cloud中文网-官方文档中文版
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 |
删除 src 目录,将此项目作为父项目 springcloud
管理依赖
<packaging>pompackaging>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<maven.compiler.source>1.8maven.compiler.source>
<maven.compiler.target>1.8maven.compiler.target>
<junit.version>4.12junit.version>
<lombok.version>1.16.10lombok.version>
<log4j.version>1.2.17log4j.version>
properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-dependenciesartifactId>
<version>Greenwich.SR1version>
<type>pomtype>
<scope>importscope>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-dependenciesartifactId>
<version>2.1.4.RELEASEversion>
<type>pomtype>
<scope>importscope>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.47version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.1.10version>
dependency>
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
<version>1.3.2version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>${junit.version}version>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>${lombok.version}version>
dependency>
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>${log4j.version}version>
dependency>
<dependency>
<groupId>ch.qos.logbackgroupId>
<artifactId>logback-coreartifactId>
<version>1.2.3version>
dependency>
dependencies>
dependencyManagement>
springcloud-api
<artifactId>springcloud-apiartifactId>
<dependencies>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
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;
}
}
springcloud-provider-dept-8001
<artifactId>springcloud-provider-dept-8001artifactId>
<dependencies>
<dependency>
<groupId>org.examplegroupId>
<artifactId>springcloud-apiartifactId>
<version>1.0-SNAPSHOTversion>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
dependency>
<dependency>
<groupId>ch.qos.logbackgroupId>
<artifactId>logback-coreartifactId>
dependency>
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-testartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-jettyartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-devtoolsartifactId>
dependency>
dependencies>
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>
# 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
@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 {
@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();
}
}
@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();
}
}
@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 = 1
Caused by: java.nio.charset.MalformedInputException: Input length = 1
file was loaded in the wrong encoding utf-8
springcloud-consumer-dept-80
<artifactId>springcloud-consumer-dept-80artifactId>
<dependencies>
<dependency>
<groupId>org.examplegroupId>
<artifactId>springcloud-apiartifactId>
<version>1.0-SNAPSHOTversion>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-devtoolsartifactId>
dependency>
dependencies>
# resources/application.yml
server:
port: 80
// config
@Configuration // spring applicationContext.xml
public class ConfigBean {
// 注册 bean
@Bean
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
@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);
}
}
@SpringBootApplication
public class DeptConsumer_80 {
public static void main(String[] args) {
SpringApplication.run(DeptConsumer_80.class, args);
}
}