Spring Cloud 是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地 简化了分布式系统基础设施 的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot 的开发风格做到一键启动和部署。
Spring并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
Spring Cloud Netflix
整个框架的基础,各项服务依赖与它,与各种Netflix OSS组件集成,组成微服务的核心。
Netflix Eureka
服务中心,云端服务发现,一个基于 REST 的服务,用于定位服务,以实现云端中间层服务发现和故障转移。 提供服务的地方
Netflix Hystrix
熔断器,容错管理工具,旨在通过熔断机制控制服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。对不稳定的节点进行下线,转发请求
Netflix Zuul
Zuul 是在云平台上提供动态路由,监控,d性,安全等边缘服务的框架。可以用于拦截各种恶意请求。
Netflix Archaius
配置管理API,包含一系列配置管理API,提供动态类型化属性、线程安全配置 *** 作、轮询框架、回调机制等功能。可以实现动态获取配置, 原理是每隔60s(默认,可配置)从配置源读取一次内容,这样修改了配置文件后不需要重启服务就可以使修改后的内容生效,前提使用archaius的API来读取。
Spring Cloud Config
配置中心,配置管理工具包,让你可以把配置放到远程服务器,集中化管理集群配置,目前支持本地存储、Git以及Subversion。
Spring Cloud Bus
事件、消息总线,用于在集群(例如,配置变化事件)中传播状态变化,可与 Spring Cloud Config 联合实现热部署。
Spring Cloud Cluster
Spring Cloud Cluster 将取代 Spring Integration。提供在分布式系统中的集群所需要的基础功能支持,如:选举、集群的状态一致性、全局锁、tokens等常见状态模式的抽象和实现。
如果把不同的帮派组织成统一的整体,Spring Cloud Cluster已经帮你提供了很多方便组织成统一的工具。
Eureka是Netflix开源的一款提供服务注册和发现的产品,它提供了完整的 Service Registry 和 Service Discovery 实现。也是springcloud体系中最重要最核心的组件之一。
服务中心又称 注册中心(类似于京东的杰夫),管理各种服务功能包括服务的注册、发现、熔断、负载、降级等,比如dubbo admin后台的各种功能。
传统的分布式,项目A调用项目B
有了服务中心后:
传统分布式,项目A调用项目B,项目B在调用项目C
有了注册中心之后:
通过服务中心来获取服务你不需要关注你调用的项目IP地址,由几台服务器组成,每次直接去服务中心获取可以使用的服务去调用既可。
由于各种服务都注册到了服务中心,就有了去做很多高级功能条件。比如
几台服务提供相同服务来做均衡负载;监控服务器调用成功率来做熔断,移除服务列表中的故障点;监控服务调用时间来对不同的服务器设置不同的权重等等。 Netflix 与 Eureka 的关系
Spring Cloud 封装了 Netflix 公司开发的 Eureka 模块来实现服务注册和发现。
Eureka 采用了 C-S 的设计架构。Eureka Server 作为服务注册功能的服务器,它是服务注册中心。而系统中的其他微服务,使用 Eureka 的客户端连接到 Eureka Server,并维持心跳连接。这样系统的维护人员就可以通过 Eureka Server 来监控系统中各个微服务是否正常运行。Spring Cloud 的一些其他模块(比如 Zuul )就可以通过 Eureka Server 来发现系统中的其他微服务,并执行相关的逻辑。
Eureka 由两个组件组成:Eureka 服务器和 Eureka 客户端。
Eureka 服务器用作服务注册服务器。Eureka客户端是一个java客户端,用来简化与服务器的交互、作为轮询负载均衡器,并提供服务的故障切换支持。Netflix在其生产环境中使用的是另外的客户端,它提供基于流量、资源利用率以及出错状态的加权负载均衡。
Eureka 的基本架构
Eureka 采用了 C-S 的设计架构。
Eureka Server 作为服务注册功能的服务器,它是服务注册中心。而系统中的其他微服务,则使用 Eureka Client 连接到 Eureka Server 并维持心跳连接。这样系统的维护人员就可以通过 Eureka Server 来监控系统中各个微服务是否正常运行。Spring Cloud 的一些其他子模块(例如 Gateway)就可以通过 Eureka Server 来发现系统中的其他微服务,并执行相关的业务逻辑。一个 Eureka 的高可用架构图如下:
具体步骤:
节点直接同步: 服务启动后向 Eureka 注册,Eureka Server 会将注册信息向其他 Eureka Server 进行同步,当服务消费者要调用服务提供者,则向服务注册中心获取服务提供者地址,然后会将服务提供者地址缓存在本地,下次再调用时,则直接从本地缓存中取,完成一次调用。当服务注册中心 Eureka Server 检测到服务提供者因为宕机、网络原因不可用时,则在服务注册中心将服务置为 DOWN 状态,并把当前服务提供者状态向订阅者发布,订阅过的服务消费者更新本地缓存。将本地缓存也置为无效服务提供者在启动后,周期性(默认30秒)向 Eureka Server 发送心跳,以证明当前服务是可用状态。Eureka Server 在一定的时间(默认90秒)未收到客户端的心跳,则认为服务宕机,注销该实例
eureka的自我保护机制
在默认配置中,Eureka Server 在默认 90s 没有得到客户端的心跳,则注销该实例,但是往往因为微服务跨进程调用,网络通信往往会面临着各种问题,比如微服务状态正常,但是因为网络分区故障时,Eureka Server注销服务实例则会让大部分微服务不可用,这很危险,因为服务明明没有问题。网络延迟导致心跳延迟收到
为了解决这个问题,Eureka 有自我保护机制,通过在Eureka Server配置如下参数,可启动保护机制。
eureka.server.enable-self-preservation=true
它的原理是,当 Eureka Server 节点在短时间内丢失过多的客户端时(可能发送了网络故障),那么这个节点将进入自我保护模式,不再注销任何微服务,当网络故障回复后,该节点会自动退出自我保护模式。
服务注册中心的搭建
1、pom 中添加依赖
org.springframework.cloud spring-cloud-starterorg.springframework.cloud spring-cloud-starter-eureka-serverorg.springframework.boot spring-boot-starter-testtest
2、添加启动代码中添加 @EnableEurekaServer 注解
@SpringBootApplication @EnableEurekaServer public class SpringCloudEurekaApplication { public static void main(String[] args) { SpringApplication.run(SpringCloudEurekaApplication.class, args); } }
3、配置文件
在默认设置下,该服务注册中心也会将自己作为客户端来尝试注册它自己,所以我们需要禁用它的客户端注册行为,在 application.properties 添加以下配置:
spring.application.name=spring-cloud-eureka server.port=8000 eureka.client.register-with-eureka=false eureka.client.fetch-registry=false eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/
eureka.client.register-with-eureka :表示是否将自己注册到Eureka Server,默认为true。eureka.client.fetch-registry :表示是否从Eureka Server获取注册信息,默认为true。eureka.client.serviceUrl.defaultZone :设置与Eureka Server交互的地址,查询服务和注册服务都需要依赖这个地址。默认是http://localhost:8761/eureka;多个地址可使用 , 分隔。
启动工程后,访问:http://localhost:8000/,可以看到下面的页面,其中还没有发现任何服务:
注册中心这么关键的服务,如果是单点话,遇到故障就是毁灭性的。在一个分布式系统中,服务注册中心是最重要的基础部分,理应随时处于可以提供服务的状态。
为了维持其可用性,使用集群是很好的解决方案。Eureka 通过互相注册的方式来实现高可用的部署,所以我们只需要将 Eureke Server 配置其他可用的 serviceUrl 就能实现高可用部署。
具体步骤如下:
1、创建 application-peer1.properties,作为 peer1 服务中心的配置,并将serviceUrl 指向 peer2:
spring.application.name=spring-cloud-eureka server.port=8000 eureka.instance.hostname=peer1 eureka.client.serviceUrl.defaultZone=http://peer2:8001/eureka/
2、创建 application-peer2.properties,作为 peer2 服务中心的配置,并将serviceUr l指向 peer1
spring.application.name=spring-cloud-eureka server.port=8001 eureka.instance.hostname=peer2 eureka.client.serviceUrl.defaultZone=http://peer1:8000/eureka/
3、host转换
在hosts文件中加入如下配置
127.0.0.1 peer1 127.0.0.1 peer2
4、打包启动
依次执行下面命令
#打包 mvn clean package # 分别以peer1和peeer2 配置信息启动eureka java -jar spring-cloud-eureka-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer1 java -jar spring-cloud-eureka-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer2
依次启动完成后,浏览器输入: http://localhost:8000/效果图如下:
根据图可以看出peer1的注册中心DS Replicas已经有了peer2的相关配置信息,并且出现在available-replicas中。
我们手动停止peer2来观察,发现peer2就会移动到unavailable-replicas一栏中,表示peer2不可用。
到此双节点的配置已经完成。
eureka集群使用在生产中我们可能需要 三台或者大于三台的注册中心 来保证服务的稳定性,配置的原理其实都一样,将注册中心分别指向其它的注册中心。
这里只介绍三台集群的配置情况,其实和双节点的注册中心类似,每台注册中心分别又指向其它两个节点即可,使用application.yml来配置。
application.yml配置详情如下:
--- spring: application: name: spring-cloud-eureka profiles: peer1 server: port: 8000 eureka: instance: hostname: peer1 client: serviceUrl: defaultZone: http://peer2:8001/eureka/,http://peer3:8002/eureka/ --- spring: application: name: spring-cloud-eureka profiles: peer2 server: port: 8001 eureka: instance: hostname: peer2 client: serviceUrl: defaultZone: http://peer1:8000/eureka/,http://peer3:8002/eureka/ --- spring: application: name: spring-cloud-eureka profiles: peer3 server: port: 8002 eureka: instance: hostname: peer3 client: serviceUrl: defaultZone: http://peer1:8000/eureka/,http://peer2:8001/eureka/
分别以peer1、peer2、peer3的配置参数启动eureka注册中心。
java -jar spring-cloud-eureka-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer1 java -jar spring-cloud-eureka-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer2 java -jar spring-cloud-eureka-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer3
依次启动完成后,浏览器输入: http://localhost:8000/效果图如下:
我们假设服务提供者有一个 hello 方法,可以根据传入的参数,提供输出“hello xxx,this is first messge”的服务
1、pom 包配置
创建一个 springboot 项目,pom.xml 中添加如下配置:
org.springframework.cloud spring-cloud-starter-eurekaorg.springframework.boot spring-boot-starter-testtest
2、配置文件
application.properties 配置如下:
spring.application.name=spring-cloud-producer server.port=9000 eureka.client.serviceUrl.defaultZone=http://localhost:8000/eureka/
3、启动类
启动类中添加 @EnableDiscoveryClient 注解
@SpringBootApplication @EnableDiscoveryClient public class ProducerApplication { public static void main(String[] args) { SpringApplication.run(ProducerApplication.class, args); } }
4、controller
提供 hello 服务
@RestController public class HelloController { @RequestMapping("/hello") public String index(@RequestParam String name) { return "hello "+name+",this is first messge"; } }
添加 @EnableDiscoveryClient 注解后,项目就具有了服务注册的功能。启动工程后,就可以在注册中心的页面看到 SPRING-CLOUD-PRODUCER 服务。
1、pom 包配置 和服务提供者一致
org.springframework.cloud spring-cloud-starter-eurekaorg.springframework.boot spring-boot-starter-testtest
2、配置文件
application.properties 配置如下:
spring.application.name=spring-cloud-consumer server.port=9001 eureka.client.serviceUrl.defaultZone=http://localhost:8000/eureka/
3、启动类
启动类添加 @EnableDiscoveryClient和 @EnableFeignClients 注解。
@SpringBootApplication @EnableDiscoveryClient @EnableFeignClients public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } }
@EnableDiscoveryClient :启用服务注册与发现@EnableFeignClients:启用feign进行远程调用
Feign 是一个声明式 Web Service 客户端。使用 Feign 能让编写 Web Service 客户端更加简单, 它的使用方法是定义一个接口,然后在上面添加注解,同时也支持JAX-RS标准的注解。Feign也支持可拔插式的编码器和解码器。Spring Cloud对Feign进行了封装,使其支持了Spring MVC标准注解和 HttpMessageConverters。Feign可以与Eureka和Ribbon组合使用以支持负载均衡。
4、feign调用实现
@FeignClient(name= "spring-cloud-producer") public interface HelloRemote { @RequestMapping(value = "/hello") public String hello(@RequestParam(value = "name") String name); }
name:远程服务名,及spring.application.name配置的名称
此类中的方法和远程服务中contoller中的方法名和参数需保持一致。
5、web层调用远程服务
将 HelloRemote 注入到controller层,像普通方法一样去调用即可。
@RestController public class ConsumerController { @Autowired HelloRemote HelloRemote; @RequestMapping("/hello/{name}") public String index(@PathVariable("name") String name) { return HelloRemote.hello(name); } }
到此,最简单的一个服务注册与调用的例子就完成了。
测试 简单调用依次启动 spring-cloud-eureka、spring-cloud-producer、spring-cloud-consumer 三个项目
先输入: http://localhost:9000/hello?name=neo 检查spring-cloud-producer服务是否正常
返回: hello neo,thisisfirst messge
说明spring-cloud-producer正常启动,提供的服务也正常。
浏览器中输入:http://localhost:9001/hello/neo
返回: hello neo,thisisfirst messge
说明客户端已经成功的通过feign调用了远程服务hello,并且将结果返回到了浏览器。
以上面spring-cloud-producer为例子修改,将其中的 controller 改动如下:
@RestController public class HelloController { @RequestMapping("/hello") public String index(@RequestParam String name) { return "hello "+name+",this is producer 2 send first messge"; } }
在配置文件中改动端口:
spring.application.name=spring-cloud-producer server.port=9003 eureka.client.serviceUrl.defaultZone=http://localhost:8000/eureka/
打包启动后,在 eureka 就会发现两个服务提供者,如下图:
然后在浏览器再次输入: http://localhost:9001/hello/neo进行测试:
第一次返回结果: hello neo,thisisfirst messge第二次返回结果: hello neo,thisisproducer2send first messge
不断的进行测试下去会发现两种结果交替出现,说明两个服务中心自动提供了服务均衡负载的功能。如果我们将服务提供者的数量在提高为N个,测试结果一样,请求会自动轮询到每个服务端来处理。
Eureka 与 Zookeeper 的区别序号 比较项 Eureka zookeeper Nacos ConsulEureka 通过 线程隔离,信号隔离,熔断器和降级等方式进行雪崩保护zookeeper CAP理论
C: Consistency,一致性的意思。
一致性就是说,我们读写数据必须是一摸一样的。
比如一条数据,分别存在两个服务器中,server1和server2。
我们此时将数据 a 通过 server1 修改为数据 b。此时如果我们访问server1访问的应该是b。当我们访问server2的时候,如果返回的还是未修改的a,那么则不符合一致性,如果返回的是b,则符合数据的一致性。
Availability,可用性的意思。
只要我对服务器,发送请求,服务器必须对我进行相应,保证服务器一直是可用的。
P:Partition tolerance,分区容错的意思。
一般来说,分布式系统是分布在多个位置的。比如我们的一台服务器在北京,一台在上海。可能由于天气等原因的影响。造成了两条服务器直接不能互相通信,数据不能进行同步。这就是分区容错。我们认为,分区容错是不可避免的。也就是说 P 是必然存在的。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)