一、概述
1、SpringCloud要解决的四个核心问题
- 用户访问---API----解决路由问题
- 服务之间的通信----HTTP RPC----解决通信问题
- 服务的管理---注册和发现----解决高可用问题(多线程)
- 服务宕机---熔断机制---解决服务降级问题
2、解决方案 :SpringCloud NetFlix【一站式解决方案】
- 路由问题---zuul组件
- 解决通信问题---Feign
- 服务注册和发现---Eureka
- 熔断机制---Hystrix
3、其他解决方案
(1) Apache Dubbo Zookeeper【半自动】
- 路由问题---第三方组件,或自己实现
- 解决通信问题---Dubbo
- 服务注册和发现---Zookeeper
- 熔断机制---借助Hystrix
(2) SpringCloud Alibaba【一站式解决方案】
4、springBoot和springCloud的关系
(1)springBoot----用来构建微服务---一个个jar包
springCloud---用来启动和管理微服务
(2)springboot专注于快速、方便的开发单个个体微服务
spingcloud关注全局的服务治理框架
(3)springboot可以独立于spingcloud单独使用
spingcloud必须依赖于springboot
(4)springCloud所有步骤都和springBoot一样,就是springBoot工程
springCloud只是用不同于dubbo的方式来管理springBoot工程
5、Dubbo与springCloud调用不同点
(1)dubbo消费者调用提供者-----RPC协议-----利用service代理对象,方法调用方法---底层native调用
(2)SpringCloud调用----------Http协议------controller调controller
二、微服务和分布式
(一)微服务
1、微服务架构
将单一的应用程序划分为一组小的服务----模块化,解耦合
每个服务运行在自己独立的进程内,服务之间互相协调,互相配置,完成最终任务
2、微服务
一个服务应用具体解决某一个问题,组成微服务架构的一个个独立小服务,强调的是服务的大小---小服务,关注是某个点
3、微服务的两种通信方式
HTTP:超文本传送协议(SpringCloud微服务 RESTful API)--应用层协议,是构建在传输层协议TCP之上的
RPC:远程调用(Dubbo)---主要基于TCP/UDP协议
4、微服务优缺点
【优点】
- 满足单一职责原则
- 每个服务足够内聚,足够小,聚焦一个指定的业务功能
- 开发简单,开发效率高,能够被小团队单独开发
- 只是业务逻辑代码,不和前端界面混合
【缺点】
- 服务间通信成本变高
- 数据会出现不一致问题----网络延迟等
- 要处理分布式系统的复杂性变高----四个问题
- 运维难度变大
(二)分布式
1、分布式
一种工作方式,将不同业务模块部署在不同服务器上,或同一业务模块拆分多个子业务,部署在不同的服务器上,解决高并发问题
2、分布式和微服务区别
分布式的目标是高并发访问,当访问量很大,一台机器承受不了,使用多台机器来完成服务的部署
微服务的目标是解耦,单一职责,让各个模块拆分开来,不会互相影响,微服务可以在同一台机器上部署
3、分布式与集群的区别
分布式:一种工作方式,强调任务在多个物理隔离结点上进行
集群:一组协同工作的服务实体,一种物理形态,强调物理集中,同一管理同一业务部署在多台机器上,提高系统可用性
参考: 分布式与集群的区别是什么? - aspirant - 博客园
三、SpringCloud各部分具体实现
(一)工程架构搭建
1、父工程--用来整体设置依赖的版本号等公共信息
(1)新建一个meaven项目
(2)配置pom.xml
- springBoot父项目依赖
- springCloud依赖管理
(3)作用:统一定义了springBoot和springCloud版本,提供者和消费者继承父项目之后就无需再写版本号
2、API工程---用来放公用的实体类--相当于Dubbo的interface工程
(1)建一个maven工程
(2)作用:放提供者和消费者公共的实体类、工具类、方法等
(3)代码
- 实体类
- 自定义常量类
3、服务提供者
(1)新建springboot工程
(2)配置pom.xml文件
- 继承自定义父项目依赖
- springBoot的起步依赖
- 其他依赖:mybatis起步依赖和jdbc驱动
-
加入API工程的依赖---用来使用项目中的实体类
将公共项目的pom.xml中 该项目依赖复制过来即可
-
加入xml扫描插件
(3)写代码: dao---service---controller
<1>dao层
- dao 接口---@Mapper
- 接口的实现--xml
<2>Service层
- service接口
- service实现类---@service @Autowired
<3>Controller类
- @RestContrller @Autowired @RequestMapping()
- @RestContrller---表示数据全部是json格式,restful请求风格
4、配置application.properties文件
同springBoot中
(二)Eureka注册中心
1、集群注册中心的搭建
方式一:建多个Eureka工程,每个工程对应一个application.properties配置文件
方式二:在一个Eureka工程下,配置多个application.properties配置文件,里面配置的端口号不同即可
2、采用第二种方式搭建集群
主要利用properties配置文件来实现
(1)将同一工程中的properties配置文件复制三份
- 工程原主配置文件
- 复制1:Eureka注册中心1配置文件
- 复制2:Eureka注册中心2配置文件
- 复制3:Eureka注册中心3配置文件
(2)改动配置内容
- 端口号
- 向另外两台注册中心注册自己
(3)运行服务
在运行参数中指定要运行哪个注册中心---工程原主配置文件application.properties
3、提供者和消费者的properties文件
指定注册中心的地方都增加相应的多个注册中心---逗号隔开
eureka.client.service-url.defaultZone=eureka1连接地址,eureka2连接地址,eureka3连接地址
4、注册中心的打包和部署
- 父工程在pom.xml下聚合各个子项目:接口工程、注册中心工程、提供者、消费者
- package打包
- 注册中心部署到lunix系统
rz---选择jar包
vim---启动jar包
5、注册中心的自我保护机制
(1)自我保护机制----即使宕机,也不注销该微服务
避免因为网络分区故障导致的心跳传送不及时,而误以为宕机被注销的情况
(2)思想:
宁愿保留所有服务,不误注销任何一个健康的服务
(3)开启或关闭服务自我保护机制---Eureka的properties配置文件中
eureka.server.enable-self-preservation=false
false表禁用,默认是ture
(4)自我保护机制需要消费者具有容错机制
(三) Ribbon负载均衡
1、负载均衡
(1)负载均衡事将请求均匀地分摊到不同的节点单元上执行
(2)负载均衡分类
- 硬件负载均衡:F5、深信服、Arraydeng等
- 软件负载均衡:Nginx、LVS、HAProxy等(服务器实现的)
(3)Ribbon的功能
- 提供客户端的软件负载均衡算法,从Eureka注册中心中获取一个可用的服务端清单
- 通过心跳检测来排除故障的服务节点,使清单中都是可以正常访问的服务端节点
- Ribbon会自动化配置RestTemplate对象,通过@LoadBalanced开启RestTemplate对象调用负载均衡
(4)负载均衡算法
轮询、权重、最小连接数
服务器端的负载均衡是指利用服务器的方式来进行负载均衡
2、Nginx与Ribbon区别
(1)Nginx---服务器端 负载均衡
Nginx记录各个服务器的地址-->浏览器先访问Nginx,然后Nginx通过内部算法对服务器进行均衡访问
(2)Ribbon---客户端 负载均衡
提供者将服务注册到注册中心(ip port name)-->消费者访问注册中心拿到要访问的服务信息-->当拿到的可访问服务多于1时-->Ribbon均衡
【总结】
Nginx:客户端负载均衡---服务记录清单---Nginx软件中
Ribbon:服务器端负载均衡---服务记录清单---注册中心中
目的都是让请求能够均衡地访问各个服务器,而不是一股脑访问某一个
3、Ribbon具体操作---@LoadBalance(消费者端)
(1)pom文件中加入springcloud起步依赖,就自动加入了Ribbin的依赖
(2)在RestTemplate类中加入@LoadBalance
(3)负载均衡算法---IRule接口定义的:轮询、权重、最小连接数
- 负载均衡的入口---ILoadBalancer接口
- 切换均衡算法---配置类中加一个bean---配置temple 加bean的那个类
@Configuration
public class RestConfig{
@LoadBalanced //使用Ribbon实现负载均衡的调用(封装Ribbon+Eureka+RestTemplate)
@Bean
public RestTemplate restTenplate(){
return new RestTemplate();
}
@Bean
public IRule iRule(){
return new RoundRobinRRule();//采用轮循方式负载均衡
}
}
4、不同均衡算法
默认根据性能和节点可用性选择
(四) Feign 声明式服务调用
1、Feign
Netflix公司开发的声明式的REST风格调用客户端
是一个远程调用的restful风格的http接口的一个组件
2、作用--负载均衡
简化服务端的代码开发---自动封装
feign代替Ribbon+RestTemplate
3、实现
<1>在接口工程中的操作
- pom.xml中加fegin依赖
- 声明一个controller的接口,其实现类是controller类
- 接口上加Fegin注解:@FeignClient(“注册中心的的服务地址”)
用来指定服务名称--application.name[注册中心application那栏],进而绑定服务
- 接口中方法上加@RequestMapping(“请求名”)
通过SpringMVC中提供的注解利用同一个请求名来绑定提供者提供的接口
@FeginClient("服务地址")
public interface GoodsRemoteClient{
@RequestMapping("请求名")
public ResultObject goods();
}
<2>提供者工程
@RequestMapping(“接口中同一个请求名”)实现fegin接口,其他实现和原controller代码没变化
public class GoodsController{
@Autowired
private GoodService goodService;
@RequestMapping("请求名")
public ResultObject goods(){
//具体处理代码
}
}
<3>消费者工程
调用fegin接口中方法
- application类中加开启fegin注解:@EnableFefinClients
-
controller类中调用:将接口对象注入进来---@Autowired
-
启动消费者,通过浏览器访问对应请求---实现远程调用
public class GoodsController{
//产品服务的接口地址(注册中心服务名)
private static final String GOODS_SERVICE_URL="http://产品服务的接口路径";
@Autowired
private GoodsRemoteClient remoteClient;//fegin的远程调用客户端对象
}
(五) Hystrix 服务熔断降级 限流
(六)Zuul 网关--路由 过滤 异常 降级
待更...