赞
踩
集群:同一个业务,部署在多个服务器上(不同的服务器运行同样的代码,干同一件事)
分布式:一个业务分拆多个子业务,部署在不同的服务器上(不同的服务器,运行不同的代码,为了同一个目的)
CAP理论:数据一致性consistency
可用性availability
分区容错性partition-tolerance
下面有三个节点(它们是集群的),此时三个节点都能够相互通信:
由于我们的系统是分布式的,节点之间的通信是通过网络来进行的。只要是分布式系统,那很有可能会出现一种情况:因为一些故障,使得有些节点之间不连通了,整个网络就分成了几块区域。
数据就散布在了这些不连通的区域中,这就叫分区
此时我们节点一和节点三是不可通信的,这就有了抉择:
一般我们说的分布式系统,P:分区容错性(partition-tolerance)这个是必需的,这是客观存在的。CAP是无法完全兼顾的,从上面的例子也可以看出,我们可以选AP,也可以选CP。但是,要注意的是:不是说选了AP,C就完全抛弃了。不是说选了CP,A就完全抛弃了!
在CAP理论中,C所表示的一致性是强一致性(每个节点的数据都是最新版本),其实一致性还有其他级别的:
同样,可用性的值域可以定义成0到100%的连续区间
所以,CAP理论定义的其实是在容忍网络分区的条件下,“强一致性”和“极致可用性”无法同时达到。
分布式集群会出现什么问题呢?首当其冲的就是子系统之间的通讯问题。子系统与子系统之间不是在同一个环境下,那就需要远程调用。远程调用可能就会想到httpClient、WebService等等这些技术来实现。既然是远程调用就必须知道ip地址,我们可能有以下的场景。
http://123.123.123.123:8888/java3y/3
http://123.123.123.123:8888/java3y/3,(同样地)B->C,C->D
http://123.123.123.123:8888/java3y/3,(同样地)B->C
万一我们B服务的IP地址变了,那么其他服务器都需要手动更新B服务的IP地址。
这种情况就让Eureka来解决。A、B、C、D四个服务都可以拿到Eureka(服务E)那份注册清单。A、B、C、D四个服务互相调用不再通过具体的IP地址,而是通过服务名来调用!
Eureka治理机制
服务提供者
服务消费者
Eureka Server服务注册中心
通过Eureka服务治理框架,我们可以通过服务名来获取具体的服务实例的位置了(IP)。一般在使用SpringCloud的时候不需要自己手动创建HttpClient来进行远程调用。
可以使用Spring封装好的RestTemplate工具类,使用起来很简单:
// 传统的方式,直接显示写死IP是不好的!
//private static final String REST_URL_PREFIX = "http://localhost:8001";
// 服务实例名
private static final String REST_URL_PREFIX = "http://MICROSERVICECLOUD-DEPT";
@Autowired
private RestTemplate restTemplate;
// 该方法调用了其他服务器的服务
@RequestMapping(value = "/consumer/dept/add")
public boolean add(Dept dept) {
// REST请求地址、请求参数、HTTP响应转换被转换成的对象类型。
return restTemplate.postForObject(REST_URL_PREFIX + "/dept/add", dept, Boolean.class);
}
为了实现服务的高可用,我们可以将服务提供者集群。比如说,现在一个秒杀系统设计出来了,准备上线了。在11月11号时为了能够支持高并发,我们开多台机器来支持并发量。
现在想要这三个秒杀系统合理摊分用户的请求(专业来说就是负载均衡),可能你会想到nginx。
其实SpringCloud也支持的负载均衡功能,只不过它是客户端的负载均衡,这个功能实现就是Ribbon!
负载均衡又区分了两种类型:
Ribbon是支持负载均衡,默认的负载均衡策略是轮询,我们也是可以根据自己实际的需求自定义负载均衡策略的。
实现起来也很简单:继承AbstractLoadBalancerRule类,重写public Server choose(ILoadBalancer lb, Object key)即可。
到目前为止,我们的服务看起来好像挺好的了:能够根据服务名来远程调用其他的服务,可以实现客户端的负载均衡。
但是,如果我们在调用多个远程服务时,某个服务出现延迟,会怎么样??在高并发的情况下,由于单个服务的延迟,可能导致所有的请求都处于延迟状态,甚至在几秒钟就使服务处于负载饱和的状态,资源耗尽,直到不可用,最终导致这个分布式系统都不可用,这就是“雪崩”。
解决方法
Hystrix提供几个熔断关键参数:滑动窗口大小(20)、 熔断器开关间隔(5s)、错误率(50%)
上面已经介绍了Ribbon和Hystrix了,可以发现的是:他俩作为基础工具类框架广泛地应用在各个微服务的实现中。我们会发现对这两个框架的使用几乎是同时出现的。为了简化我们的开发,Spring Cloud Feign
出现了!它基于 Netflix Feign 实现,整合了Spring Cloud Ribbon
与 Spring Cloud Hystrix
,除了整合这两者的强大功能之外,它还提供了声明式的服务调用(不再通过RestTemplate
)。
为了保证对外服务的安全性, 我们在服务端实现的微服务接口,往往都会有一定的权限校验机制,但我们的服务是独立的,我们不得不在这些应用中都实现这样一套校验逻辑,这就会造成校验逻辑的冗余。
例如,购物车和订单模块都需要用户登录了才可以正常访问,基于现在的架构,只能在购物车和订单模块都编写校验逻辑,这无疑是冗余的代码。
为了解决上面这些常见的架构问题,API网关的概念应运而生。在SpringCloud中了提供了基于Netfl ix Zuul实现的API网关组件Spring Cloud Zuul。
Spring Cloud Zuul是这样解决上述两个问题的:
每个服务都有自己的配置文件,既然是配置文件,给我们配置的东西,那难免会有些改动的。
比如我们的Demo中,每个服务都写上相同的配置文件。万一我们有一天,配置文件中的密码需要更换了,那就得三个都要重新更改。
Spring Cloud Config项目是一个解决分布式系统的配置管理方案。它包含了Client和Server两个部分,server提供配置文件的存储、以接口的形式将配置文件的内容提供出去,client通过接口获取数据、并依据此数据初始化自己的应用。
eureka、consul、nacos、zookeeper主要功能为提供注册中心的服务,后两者同样具备配置中心的功能;主要使用eureka与nacos开发项目
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。