# 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是分布式微服务架构下的一站式解决方案,是各个微服务架构落地技术的集合体,俗称微服务全家桶 ![Spring Cloud diagram](https://spring.io/images/cloud-diagram-dark-b902fd07e60945a9a8930ca01f86bdf3.svg) > 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:覆盖全球的短信服务,又好、高效、智能的互联网通讯能力 ![img](https://pic2.zhimg.com/80/v2-7b99ad060d2528967c87b51e7f1ebf65_720w.jpg) > 优势 - 阿里强大的技术团队 - 搭建简单,学习成本低 - 良好的可视化界面 - 继承Dubbo - 云原生趋势 > Alibaba对Netflix的加强 - 注册中心和动态配置使用Nacos - 服务通信增加对Dubbo的支持 - 服务保护改为Sentinel - 此外增加Seata、OSS、SchedulerX、SMS、RocketMQ、Arthas、ACM ![图片](https://img-blog.csdnimg.cn/img_convert/580c5952a715f8401f883528ba227f87.png) ![图片](https://img-blog.csdnimg.cn/img_convert/c13a7f7ea8f6d43fb57d0ee4d0d8cff4.png) ## 相关概念 > 云原生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); } } ```