# SpringCloudDemo
**Repository Path**: cjbgitee/spring-cloud-demo
## Basic Information
- **Project Name**: SpringCloudDemo
- **Description**: No description available
- **Primary Language**: Java
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2021-11-06
- **Last Updated**: 2021-11-13
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# SpringCloud
## 架构史
```
三层架构 + MVC
架构:
Spring IOC AOP
SpringBoot 自动装配
模块化 =》 微服务
微服务4个核心问题
1. 多个服务,客户端的访问?
2. 多个服务,相互之间的通信?
3. 多个服务,如何治理?
4. 多个服务,服务挂了?
微服务解决方案:
Spring Cloud 是基于SpringBoot的生态
1. Spring Cloud NetFlix 一站式解决方案
api网关,zuul组件
服务Feign --Http
服务注册发现:Eurka
熔断机制:Hystrix
2. Apache Dubbo Zookeeper 半自动,需要整合第三方
API: 没有
服务通信:Dubbo
服务注册发现:Zookeeper
服务熔断:没有
3. Spring Cloud Alibaba 一站式解决方案,更简单
新概念:服务网格 Server Mesh
istio
微服务核心问题
1. API网关
2. 协议:Http,RPC
3. 治理:注册和发现
4. 熔断机制
```
> 常见面试题
1. 什么是微服务
2. 微服务之间是如何独立通信的
3. SpringCloud和Dubbo的异同
4. 对Springboot和Springcloud的理解
5. 什么是服务熔断?什么是服务降级?
6. 微服务的优缺点?
7. 微服务技术栈?
8. eureka和zookeeper的区别
## 微服务
### 概述
微服务(Microservice Architecture)是近几年流行的一种架构思想
ThoughtWorks公司首席科学家Martin Fowler于2014年提出:
https://martinfowler.com/articles/microservices.html
- 就目前而言,对于微服务,业界没有一个统一标准的定义
- 通常而言,微服务架构是一种架构模式,或者说是一种架构风格,它提倡将但一个的应用程序划分为一组小的服务,每个服务运行在其他独立的进程内,服务之间相互协调,互相配置,为用户提供最终价值。服务之间采用轻量级的通信机制互相沟通,每个服务都围绕着具体的业务进行构建,并且能够被独立的部署到生产环境中,另外,应尽量避免统一的,集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对齐进行构建,可以有一个非常轻量级的集中管理来协调这些服务,可以使用不同的语言来编写服务,也可以使用不同的数据存储
### 优缺点
**优点**
- 单一职责原则
- 每个服务足够内聚,足够小,代码容易理解
- 开发简单,开发效率提高,一个服务可能就是专一的干一件事
- 微服务能够被小团队单独开发,这个小团队是2-5人开发组成
- 微服务是松耦合的,是有功能意义的服务,开发和部署阶段都是独立的
- 微服务能使用不同的语言开发,可以融合最新技术
- 易于和第三方集成,允许容易且灵活的集成自动部署
- 微服务只是业务逻辑的代码,不会有HTML,CSS
- 每个微服务都有自己的存储能力,可以有自己的数据库,也可以有统一的数据库
**缺点**
- 开发人员需要处理分布式系统的复杂性
- 多服务运维难度,压力也在增大
- 系统部署依赖
- 服务间通信成本
- 数据一致性
- 系统继承测试
- 性能监控
### 技术栈
| 微服务条目 | 落地技术 |
| ------------------- | ---------------------------------------------- |
| 服务开发 | SpringBoot Spring SpringMVC |
| 服务配置与管理 | Netflix公司的Archaius 阿里的Diamond |
| 服务注册与发现 | Eureka Consul Zookeeper |
| 服务调用 | Rest RPC gRPC(google) |
| 服务熔断器 | Hystrix Enovy |
| 负载均衡 | Ribbon Nginx |
| 服务接口调用 | Feign |
| 消息队列 | kafka RbbitMQ activeMQ |
| 服务配置中心管理 | SpringCloudConfig Chef |
| 服务路由(API网关) | Zuul |
| 服务监控 | Zabbix Nagios Metrics Specatator |
| 全链路追踪 | Zipkin Brave Dapper |
| 服务部署 | Docker OpenStack Kubernates |
| 数据流操作开发包 | SpringCloud Stream(封装于Redis、Rabbit、Kafka) |
| 事件消息总线 | SpringCloud Bus |
### 推荐理由
1. 选型依据
- 整体解决方案和框架成熟度
- 社区热度
- 可维护性
- 学习曲线
2. 当前IT公司的微服务架构
- 阿里:dubbo+HFS
- 京东:JSF
- 新浪:Motan
- 当当:Dubbox
3. 微服务框架对比
| | Netflix | Motan | gRPC | Thrift | Dubbo(X) |
| ---------- | ----------------------------------------------- | ------------- | ------------ | -------- | ------------ |
| 功能定位 | 一站式解决方案 | RPC+ZK+Consul | RPC框架 | RPC框架 | 服务框架 |
| 支持Rest | Ribbon | — | — | — | — |
| 支持RPC | — | Hession2 | 是 | 是 | 是 |
| 支持多语言 | 是 | — | 是 | 是 | — |
| 负载均衡 | 服务端zuul
客户端ribbon
中间层eureka | 是(客户端) | — | — | 是(客户端) |
| 配置服务 | Netflix Archaius
SpringCloud Config Server | 是(ZK) | — | — | — |
| 调用监测 | zuul | — | — | — | — |
| 应用案例 | Netflix | Sina | Google | Facebook | |
| 社区活跃 | 高 | 一般 | 高 | 一般 | |
| 学习难度 | 中断 | 低 | 高 | 高 | 低 |
| 文档丰富 | 高 | 一般 | 一般 | 一般 | 高 |
| 其他 | Bus支持管理端点 | 支持降级 | 内部继承gRPC | IDL定义 | 使用公司多 |
## 入门概述
SpringCloud基于SpringBoot提供了一套微服务解决方案,包括服务注册与发现,配置中心,全链路监控,服务网关,负载均衡,熔断器等组件,除了基于NetFlix的开源组件做高度抽象封装之外,还有一些选型中立的开源组件
SpringCloud利用SpringBoot的开发便利性,巧妙地简化了分布式系统基础设施的开发,SpringCloud为开发人员提供了快速构建分布式系统的一些工具,**包括配置管理,服务发现,断路器,路由,微代理,事件总线,全局锁,决策竞争,分布式会话等等**,他们都可以用SpringBoot的开发风格做到一键启动和部署
SpringBoot并没有重复造轮子,只是将目前各家公司开发的比较成熟,经得住考验的服务框架组合起来,通过SpringBoot风格进行再封装,屏蔽了复杂的配置和实现原理,**最终给开发者留出了一套简单易懂,易部署和易维护的分布式系统开发工具包**
SpringCloud是分布式微服务架构下的一站式解决方案,是各个微服务架构落地技术的集合体,俗称微服务全家桶

> SpringBoot与SpringCloud
- SpringBoot专注于快速方便的开发单个个体微服务
- SpringCloud是关注全局的微服务协调整理治理框架,它将SpringBoot开发的一个个单体微服务整合并管理起来,为各个微服务之间提供:配置管理,服务发现,断路器,路由,微代理,事件总线,全居锁,决策竞选,分布式会话等等集成服务
- SpringCloud以SpringBoot为基础
- SpringBoot专注于快速、方便的开发单个个体微服务,SpringCloud关注全局的服务治理框架
> SpringCloud与Dubbo
- SpringCloud基于http的REST方式,调用灵活,依赖小;Dubbo基于dubbo的RPC通信,性能高
- SpringCloud功能比Dubbo更加全面和强大,天然的与Spring Framework、SpringBoot、Spring Data、Spring Batch等Spring项目融合;使用Dubbo需要我们自己配置和整合其他第三方框架
- Dubbo的定位是一款RPC框架,SpringCloud是微服务架构下的一站式解决方案
> SpringCloud项目
- Distributed/versioned configuration 分布式/版本控制配置
- Service registration and discover 服务注册与发现
- Routing 路由
- Service-to-service calls 服务到服务的调用
- Load balancing 负载均衡配置
- Circuit Breakers 断路器
- Distributed messaging 分布式消息管理
> 学习网站
[【狂神说Java】SpringCloud最新教程IDEA版_哔哩哔哩_bilibili](https://www.bilibili.com/video/BV1jJ411S7xr?p=3&spm_id_from=pageDriver)
https://springcloud.cc/spring-cloud-netflix.html
https://springcloud.cc/spring-cloud-dalston.html 中文API
http://springcloud.cn/ 中国社区
https://springcloud.cc/ 中文网
http://springcloud.fun/ Spring Cloud 中文导航
## Cloud Alibaba
该项目旨在为微服务提供一站式解决方案,包括开发分布式应用程序和服务所需的组件
> 主要功能
- 服务限流降级:支持WebServlet、WebFlux、OpenFeign、RestTemplate、Gateway、Zuul、Dubbo访问、修改、监控限制和流降级的功能
- 服务注册发现:集成Ribbon
- 分布式配置管理:支持分布式系统中的外部配置
- 消息驱动能力:基于Spring Cloud Stream
- 分布式事务:使用@GlobalTransactional
- 阿里云对象存储
- 分布式任务调度
- 阿里云短信服务
> 主要组件
- Sentinel:把流量作为切入点,从流量控制、熔断降级、系统负载保护等多维度维护服务的稳定性
- Nacos:易于构建云原生应用的动态服务发现、配置管理和服务管理平台
- RocketMQ:基于Java的高性能、高吞吐量的分布式消息和流计算平台
- Dubbo:高性能RPC框架
- Seate:易于使用的高性能微服务分布式事务解决方案
- Alibaba Cloud OSS:阿里云对象存储服务Object Storage Service
- Alibaba Cloud SchedulerX:分布式任务调度产品,支持周期性任务与固定时间点触发任务
- Alibaba Cloud SMS:覆盖全球的短信服务,又好、高效、智能的互联网通讯能力

> 优势
- 阿里强大的技术团队
- 搭建简单,学习成本低
- 良好的可视化界面
- 继承Dubbo
- 云原生趋势
> Alibaba对Netflix的加强
- 注册中心和动态配置使用Nacos
- 服务通信增加对Dubbo的支持
- 服务保护改为Sentinel
- 此外增加Seata、OSS、SchedulerX、SMS、RocketMQ、Arthas、ACM


## 相关概念
> 云原生CloudNative
**技术的变革,一定是思想先行**,云原生是一种**构建和运行应用程序的方法**,是一套技术体系和方法论
云计算是云原生的基础,云计算分3层:
- 基础设施即服务IaaS
- 平台即服务Paas
- 软件即服务SaaS
2013 Pivotal公司Matt Stine首次提出CloudNative概念
2015 Matt Stine定义云原生特征:12因素、微服务、自敏捷架构、基于API协作、抗脆弱性
2017 Matt Stine重新归纳特征:模块化、可观察、可部署、可测试、可替换、可处理6特质
Pivotal 官网最新对云原生概况:**DevOps+持续交付+微服务+容器**
总而言之,符合云原生架构的应用程序应该是:采用开源堆栈(K8S+Docker)进行容器化,基于微服务架构提高灵活性和可维护性,借助敏捷方法、DevOps支持持续迭代和运维自动化,利用云平台设施实现弹性伸缩、动态调度、优化资源利用率
云原生构建引用简便快捷,部署应用轻松自如、运行应用按需伸缩
> 云元素的四要素
- 微服务:微服务理论基础--康威定律;DDD领域模型==》服务解耦、内聚更强、变更更易
- 容器化:基于LXC技术的Docker容器引擎;K8S容器编排系统,用于容器管理
- DevOps:Dev+Ops开发和运维合体
- 持续交付:要求开发版本和稳定版本并存,需要很多流程和工具支撑
> 云原生的改变
- 本地部署使用c/c++/java编写,云原生使用以网络为中心的go/node.js编写
- 本地部署需要停机更新,云原生应该始终是最新的,支持频繁变更,持续交付,蓝绿部署
- 本地部署无法动态扩展,云原生利用云的弹性自动伸缩
- 本地部署对网络资源(ip、端口)依赖,甚至硬编码,云原生对网络和存储没有限制
- 本地部署的传统应用需要手工运维,云原生应用这一切都是自动化的
- 本地部署的传统应用依赖系统环境,云原生不会硬连接到任何系统环境,而是依赖抽象的基础架构,从而获得良好移植性
- 本地部署的传统应用是单体引用,或者强依赖,基于微服务架构的云原生应用,纵向划分服务,模块化更合理
## 参考链接
[为什么Spring Cloud Alibaba会替代Spring Cloud - 知乎 (zhihu.com)](https://zhuanlan.zhihu.com/p/385084113)
[什么是云原生?这回终于有人讲明白了 - 知乎 (zhihu.com)](https://zhuanlan.zhihu.com/p/150190166)
[从 Netflix 到 Alibaba,Spring Cloud 更好了吗? - InfoQ 写作平台](https://xie.infoq.cn/article/55ec677aeb3c79c7a6495d3ac)
[(3条消息) 微服务学习3:Spring Cloud Alibaba大战Spring Cloud Netflix_何哥的博客-CSDN博客](https://blog.csdn.net/CSDN2497242041/article/details/117818015)
# RestTemplate
基于RestTemplate实现接口层、实现层、调用层,实现简单的远程调用
## 创建根项目
创建Maven项目springclouddemo
```xml
4.0.0
com.demo
springcloud
1.0-SNAPSHOT
pom
1.8
1.8
1.8
1.8
3.8.1
2.3.12.RELEASE
Hoxton.SR12
2.2.0
8.0.27
4.13
1.2.17
1.18.12
1.2.8
org.springframework.boot
spring-boot-dependencies
${spring.boot-version}
pom
import
org.springframework.cloud
spring-cloud-dependencies
${spring.cloud-version}
pom
import
org.mybatis.spring.boot
mybatis-spring-boot-starter
${mybatis.spring.boot-version}
mysql
mysql-connector-java
${mysql.version}
junit
junit
${junit.version}
log4j
log4j
${log4j.version}
org.projectlombok
lombok
${lombok.version}
provided
com.alibaba
druid
${druid.version}
org.apache.maven.plugins
maven-compiler-plugin
${maven-compiler-plugin.version}
${java.version}
${java.version}
```
使用dependencyManagement对项目依赖版本号进行管理
## 服务接口层
1. 创建Maven项目001-springcloud-api
> pom.xml
```xml
springcloud
com.demo
1.0-SNAPSHOT
4.0.0
001-springcloud-api
org.projectlombok
lombok
```
2. 创建公共对象
> Dept.java
```java
// 因为需要远程调用,需要实现序列化
@Data
@NoArgsConstructor
@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;
}
}
```
## 服务实现层
1. 创建Maven项目002-springcloud-provider-8001
```xml
springcloud
com.demo
1.0-SNAPSHOT
4.0.0
002-springcloud-provider-8001
com.demo
001-springcloud-api
1.0-SNAPSHOT
junit
junit
test
mysql
mysql-connector-java
com.alibaba
druid
ch.qos.logback
logback-core
org.mybatis.spring.boot
mybatis-spring-boot-starter
org.springframework.boot
spring-boot-test
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-jetty
org.springframework.boot
spring-boot-devtools
```
2. 配置文件
> application.yml
```yml
server:
port: 8001
mybatis:
type-aliases-package: com.demo.entity
config-location: classpath:mybatis/mybatis-config.xml
mapper-locations: classpath:mybatis/mapper/*.xml
spring:
application:
name: 002-springcloud-provider-8001
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/webdemo?useUnicode=true&characterEncoding=utf-8
username: root
password: root
```
> mybatis-config.xml
```xml
```
3. 实现服务
> DeptDao.java
```java
@Mapper
@Repository
public interface DeptDao {
boolean addDept(Dept dept);
Dept get(Long id);
List listAll();
}
```
> DeptMapper.xml
```xml
insert into DEPT(DNAME, DB_SOURCE) values (#{dname}, database())
```
> DeptService.java
```java
public interface DeptService {
boolean addDept(Dept dept);
Dept get(Long id);
List listAll();
}
```
> DeptServiceImpl.java
```java
@Service
public class DeptServiceImpl implements DeptService {
@Autowired
private DeptDao deptDao;
@Override
public boolean addDept(Dept dept) {
return deptDao.addDept(dept);
}
@Override
public Dept get(Long id) {
return deptDao.get(id);
}
@Override
public List listAll() {
return deptDao.listAll();
}
}
```
> DeptController.java
```java
@RestController
public class DeptController {
@Autowired
private DeptService deptService;
@PostMapping("/dept/add")
public boolean addDept(Dept dept) {
return deptService.addDept(dept);
}
@GetMapping("/dept/get/{id}")
public Dept get(@PathVariable("id") Long id) {
return deptService.get(id);
}
@GetMapping("/dept/listAll")
public List listAll() {
return deptService.listAll();
}
}
```
4. 启动类
> DeptProvider_8001
```java
@SpringBootApplication
public class DeptProvider_8001 {
public static void main(String[] args) {
SpringApplication.run(DeptProvider_8001.class, args);
}
}
```
## 服务调用层
1. 创建Maven项目003-springcloud-consumer-80
```xml
springcloud
com.demo
1.0-SNAPSHOT
4.0.0
003-springcloud-consumer-80
com.demo
001-springcloud-api
1.0-SNAPSHOT
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-devtools
```
2. 配置文件
> application.xml
>
```xml
server:
port: 80
```
3. 模版Bean
> ConfigBean.java
>
```java
@Configuration
public class ConfigBean {
@Bean
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
```
跟以前的spring.xml里面使用Bean标签创建实例类似
4. 调用服务
> DeptController.java
```java
@RestController
public class DeptController {
@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/get/{id}")
public Dept get(@PathVariable("id") Long id) {
return restTemplate.getForObject(REST_URL_PREFIX + "/dept/get/" + id, Dept.class);
}
@RequestMapping("/consumer/dept/list")
public List list() {
return restTemplate.getForObject(REST_URL_PREFIX + "/dept/listAll", List.class);
}
}
```
5. 启动类
> DeptConsumer_80.java
```java
@SpringBootApplication
public class DeptConsumer_80 {
public static void main(String[] args) {
SpringApplication.run(DeptConsumer_80.class, args);
}
}
```