这是我参与8月更文挑战的第16天,活动详情查看:8月更文挑战
简介
Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。Spring Cloud并没有重复制造轮子,它只是将各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
构建分布式系统不需要复杂和容易出错。Spring Cloud 为最常见的分布式系统模式提供了一种简单且易于接受的编程模型,帮助开发人员构建有弹性的、可靠的、协调的应用程序。Spring Cloud 构建于 Spring Boot 之上,使得开发者很容易入手并快速应用于生产中。
架构演变
网络架构由最开始的三层mvc渐渐演变。传统的三层架构后来在互联网公司让几百人几千人同时开发一个项目已经变得不可行,并且会产生代码冲突的问题。基于SOA面向服务开发的架构,渐渐产生了微服务架构。微服务的架构的特点就是项目拆分成各个子项目,进行解耦操作,提供外部访问接口,属于敏捷开发,其实也可以视为面向接口开发。
一旦有了多个子项目,比如把淘宝网的订单系统和会员系统分开来看,就回产生如何管理接口、负载均衡、高并发情况下怎么限流断路等问题。那么这就有SpringCloud出现了。
那么springCloud的组件大概有哪些呢,我先简单介绍下:
- Eureka 服务注册中心
- 服务消费者 Rest 和 Fegin --消费实现负载均衡ribbon
- 接口网关Zuul
- Hystrix 关于服务雪崩的解决方案--服务熔断、服务降级、隔离资源。
Spring Cloud 的服务发现框架——Eureka
Eureka是基于REST(代表性状态转移)的服务,主要在AWS云中用于定位服务,以实现负载均衡和中间层服务器的故障转移。我们称此服务为Eureka服务器。Eureka还带有一个基于Java的客户端组件Eureka Client,它使与服务的交互变得更加容易。客户端还具有一个内置的负载平衡器,可以执行基本的循环负载平衡。在Netflix,更复杂的负载均衡器将Eureka包装起来,以基于流量,资源使用,错误条件等多种因素提供加权负载均衡,以提供出色的弹性。
服务发现 :其实就是一个“中介”,整个过程中有三个角色:服务提供者(出租房子的)、服务消费者(租客)、服务中介(房屋中介) 。
服务提供者 :就是提供一些自己能够执行的一些服务给外界。
服务消费者 :就是需要使用一些服务的“用户”。
服务中介 :其实就是服务提供者和服务消费者之间的“桥梁”,服务提供者可以把自己注册到服务中介那里,而服务消费者如需要消费一些服务(使用一些功能)就可以在服务中介中寻找注册在服务中介的服务提供者。
服务注册 Register :
官方解释:当 Eureka 客户端向 [Eureka] Server 注册时,它提供自身的元数据 ,比如IP地址、端口,运行状况指示符URL,主页等。
结合中介理解:房东 (提供者 [Eureka]在中介 (服务器 [Eureka]Server) 那里登记房屋的信息,比如面积,价格,地段等等(元数据 metaData)。
服务续约 Renew :
官方解释:Eureka 客户会每隔30秒(默认情况下)发送一次心跳来续约 。通过续约来告知 [Eureka]Server 该 Eureka 客户仍然存在,没有出现问题。正常情况下,如果 [Eureka] Server 在90秒没有收到 Eureka 客户的续约,它会将实例从其注册表中删除。
结合中介理解:房东 (提供者 [Eureka] 定期告诉中介 (服务器 [Eureka] Server) 我的房子还租(续约) ,中介 (服务器[Eureka]Server) 收到之后继续保留房屋的信息。
获取注册列表信息 Fetch Registries :
官方解释:Eureka 客户端从服务器获取注册表信息,并将其缓存在本地。客户端会使用该信息查找其他服务,从而进行远程调用。该注册列表信息定期(每30秒钟)更新一次。每次返回注册列表信息可能与 Eureka 客户端的缓存信息不同, Eureka 客户端自动处理。如果由于某种原因导致注册列表信息不能及时匹配,Eureka 客户端则会重新获取整个注册表信息。Eureka 服务器缓存注册列表信息,整个注册表以及每个应用程序的信息进行了压缩,压缩内容和没有压缩的内容完全相同。Eureka 客户端和 Eureka 服务器可以使用JSON / XML格式进行通讯。在默认的情况下 Eureka 客户端使用压缩JSON 格式来获取注册列表的信息。
结合中介理解:租客(消费者 [Eureka]去中介 (服务器 [Eureka]那里获取所有的房屋信息列表 (客户端列表 [Eureka] Client List) ,而且租客为了获取最新的信息会定期向中介 (服务器 [Eureka]那里获取并更新本地列表。
服务下线 Cancel :
官方解释:Eureka客户端在程序关闭时向Eureka服务器发送取消请求。发送请求后,该客户端实例信息将从服务器的实例注册表中删除。该下线请求不会自动完成,它需要调用以下内容:DiscoveryManager.getInstance().shutdownComponent();
结合中介理解:房东 (提供者 [Eureka] Client Provider) 告诉中介 (服务器 [Eureka] Server) 我的房子不租了,中介之后就将注册的房屋信息从列表中剔除。
服务剔除 Eviction :
官方解释:在默认的情况下,当Eureka客户端连续90秒(3个续约周期)没有向Eureka服务器发送服务续约,即心跳,Eureka服务器会将该服务实例从服务注册列表删除 ,即服务剔除。
结合中介理解:房东(提供者 [Eureka] 会定期联系 中介 (服务器 [Eureka] Server) 告诉他我的房子还租(续约),如果中介 (服务器 [Eureka]Server) 长时间没收到提供者的信息,那么中介会将他的房屋信息给下架(服务剔除)。
下面就是 Netflix 官方给出的 Eureka 架构图,你会发现和我们前面画的中介图别无二致。
PRC远程调用的方法
远程调用的方法有两种,我们一一来细说。
- 第一种,通过rest的方式来调用,首先我们要导入rest的pom依赖,我们要使用用户调用订单,就在用户里添加调用依赖。先解释一下什么是ribbon-----ribbon是一个负载均衡客户端 类似nginx反向代理,可以很好的控制htt和tcp的一些行为。
@EnableEurekaClient
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
@LoadBalanced // 开启负载均衡
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
public class memService{
@Autowired
private RestTemplate restTemplate;
@RequestMapping("/memTest")
public String memTest(){
String str = restTemplate.getForObject("http://order-server/orderTest",String.class);
return str;
}
}
- Feigin是一个声明式的伪Http客户端,它使得写Http客户端变得更简单。使用Feign,只需要创建一个接口并注解。它具有可插拔的注解特性,可使用Feign 注解和JAX-RS注解。Feign支持可插拔的编码器和解码器。Feign默认集成了Ribbon,并和Eureka结合,默认实现了负载均衡的效果。
Nginx 和 Ribbon 的对比
提到 负载均衡 就不得不提到大名鼎鼎的 Nignx 了,而和 Ribbon 不同的是,它是一种集中式 的负载均衡器。 Nginx 是接收了所有的请求进行负载均衡的,而对于 Ribbon 来说它是在消费者端进行的负载均衡
负载均衡,不管 Nginx 还是 Ribbon 都需要其算法的支持,如果我没记错的话 Nginx 使用的是 轮询和加权轮询算法。而在 Ribbon 中有更多的负载均衡调度算法,其默认是使用的 RoundRobinRule 轮询策略。
- RoundRobinRule :轮询策略。Ribbon 默认采用的策略。若经过一轮轮询没有找到可用的 provider,其最多轮询 10 轮。若最终还没有找到,则返回 null。
- RandomRule : 随机策略,从所有可用的 provider 中随机选择一个。
- RetryRule : 重试策略。先按照 RoundRobinRule 策略获取 provider,若获取失败,则在指定的时限内重试。默认的时限为 500 毫秒。 当然,在 Ribbon 中你还可以自定义负载均衡算法 ,你只需要实现 IRule 接口,然后修改配置文件或者自定义 Java Config 类。