快速入门全栈 - 12 SpringCloud 服务注册与发现

一、微服务与SpringCloud

微服务架构是一种架构风格,将单个应用程序作为一套小型服务开发的方法,每种应用程序在自己的进程中运行,并通过轻量级机制通信。服务是围绕业务构建的,可以通过全自动部署机制独立部署。这些服务可以使用不同的语言,不同的存储技术,集中管理很少。

微服务是以缩短交付周期,基于DevOps的演进式架构。客户端通过接入服务层进行访问,服务入口就是API网关,并存有一些安全策略和访问认证。服务在服务注册中心注册,并通过服务路由模块来进行服务发现,服务和服务之间要经过消息中心和消息总线。在这些的基础上存在对运维的服务,起到减少运维工作量的作用。

微服务也会造成其他的问题,原先的一个应用会被拆分成数个,架构的难度、测试的难度、版本控制和管理的难度都会提升,因此实施DevOps是非常重要的。

目前主流微服务框架有Spring Cloud,Dubbo,ServiceComb和Nacos。SpringCloud是基于SpringBoot的一套快速开发微服务的工具集,将各个公司比较成熟的服务框架组合起来,通过SpringBoot进行再封装,免去了复杂的配置和实现原理。

二、SpringCloud Eureka服务治理

服务治理是微服务架构的核心与基础,实现服务的自动化注册与发现。SpringCloud Eureka在Netflix Eureka的基础上重新封装,负责完成微服务架构中的服务治理功能。

快速入门全栈 - 12 SpringCloud 服务注册与发现_第1张图片
  • 服务中心:服务治理中,构建的注册中心来统一管理每一个服务,客户端向注册中心发送自身服务的名称、端口、IP、通信协议等元数据。注册中心使用双层Map结构来将其存储至本地服务清单
  • 服务续约:客户端向服务中心注册自身的服务信息后,周期性的发送心跳包来更新租约。注册中心如果一段时间内没有收到心脏包,则会将客户端剔除
  • 服务发现:当我们启动服务消费者的时候,他会发送一个REST请求给服务中心,来获取注册中心的服务清单。为了性能,Eureka Server会维护一份只读的清单来返回给客户端,同时每个客户端周期性的向注册中心咨询,存入本地并进行访问
  • 服务消费:服务消费者在获取服务清单后,可以通过服务名来获得具体的实例名和元数据,客户端可以根据自己需要决定具体调用哪个实例(使用RestTemplate)
  • 服务下线:在系统运行过程中会面临关闭或重启某个实例的情况,在服务关闭期间,我们不希望用户继续调用示例。在客户端程序中,当服务实例正常关闭的时候,会触发一个服务下线的REST请求给注册中心。注册中心在接收到请求之后,将服务状态设置为下线(DOWN),并将下线时间传播出去。
  • 失效剔除:有时我们的服务实例不会正常下线,由于内存溢出、网络故障等原因不能正常工作,而服务中心没有收到服务下线请求。因此服务中心会创建一个定时任务,每隔一段时间会将超时没有续约的服务剔除出去。
  • 自我保护:服务注册到Eureka Server之后,会维护一个心跳连接,告诉Eureka Server自己还活着。Eureka Server在运行期间,会统计心跳失败的比例在15分钟之内是否低于85%,如果低于85%,Eureka Server会将这些实例保护起来,让实例不过期,尽可能地保护注册信息。在这段保护期间内如果出现问题,客户端很容易拿到已经不存在的服务实例,出现调用失败的情况,所以客户端要有容错机制。
  • 健康检测:为了系统获取微服务相关指标(环境变量、垃圾回收信息、内存信息、线程池信息、HTTP请求统计),SpringCloud提供了Actuator模块来构建监控端点。

服务治理包括三个要素:

  • 服务发现组件:Eureka Server,消费者和服务者都要在服务器上注册来进行数据交流
  • 服务消费者:调用方
  • 服务提供者:被调用方

服务发现组件可以让消费者和提供者进行注册,消费者向服务发现组件发送心跳,并调用服务提供者的服务。

SpringCloud Eureka是一个Netflix开源的服务发现组件,包含Server和Client两部分,SpringCloud集成了Eureka,实现微服务的注册与发现

快速入门全栈 - 12 SpringCloud 服务注册与发现_第2张图片

Eureka支持高可用集群,在集群之间会进行状态的同步。所有的微服务注册在Eureka Server上,所有的客户端都要注册为Eureka Client之后才能通过服务治理来调用服务。

三、SpringCloud Eureka实战

1. Eureka Server

我们首先来看一下Eureka Server注册中心如何搭建

我们首先在Maven中配置依赖,添加SpringBoot和Eureka Server的starter

<dependency>
	<groupId>org.springframework.bootgroupId>
	<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
	<groupId>org.springframework.cloudgroupId>
	<artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
dependency>

之后要在Application启动类中添加注解@EnableEurekaServer,然后还要再application.yml (由application.properties改名)中配置Eureka Server的信息

server:
  port: 8761

eureka:
  instance:
    hostname: localhost
  client:
    registerWithEureka: false
    fetchRegistry: false
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

这样既可完成服务端的配置,我们启动SpringBoot应用后,在浏览器中输入http://localhost:8761/eureka/即可访问到Eureka注册中心的主页了。

2. Eureka Client

现在有了注册中心还不够,因为我们还没有对应的服务让其进行注册,下面我们新建一个模块来将该模块在Eureka Server上进行注册。

在新建模块的时候,我们要记得导入SpringBoot Web和Eureka Client的依赖

<dependency>
	<groupId>org.springframework.bootgroupId>
	<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
	<groupId>org.springframework.cloudgroupId>
	<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>

添加后在Application类中添加注解@EnableEurekaClient,然后再application.yml中添加配置

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
server:
  port: 9001
spring:
  application:
    name: service-hi

在serviceUrl中填写的,是要注册到的Eureka Server的URL。当我们在该模块中添加业务逻辑或控制层的类后,就可以通过URL调用服务了。

@RestController
@RequestMapping("\demo")
public class HelloController{
	@Value("${server.port}")
	String port;
	@RequestMapping("hello")
	public String sayHello(@RequestParam String name){
		return "hi, my name is " + name + ", I am from port " + port;
	}
}

这样启动服务模块后,就可以在刚才的注册中心找到我们新写的服务了,同时调用http://localhost:9001/demo/hello?name=dai,即可调用该服务

3. 高可用注册中心

如果我们只有一个Eureka Server中心,当该节点宕机之后整个微服务都无法使用,因此我们需要配置多个Eureka Server中心,并且在多个实例之间进行状态的同步,我们使用主从模式来进行实例的复制,首先编写application-master.yml。

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8762/eureka/
    register-with-eureka: true
    fetch-registry: true
  server:
  	enable-self-preservation: true
server:
  port: 8761
spring:
  application:
    name: eureka-server

然后编写application-slave.yml

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
    register-with-eureka: true
    fetch-registry: true
  server:
  	enable-self-preservation: true
server:
  port: 8762
spring:
  application:
    name: eureka-server

然后在IDEA右上角的启动位置进行Edit Configuration,新增两个Spring Boot运行,在Active profiles里分别填写master和slave,这样主节点启动时使用的是application-master.yml,从节点启动时使用的是application-slave.yml。两个注册中心,一个端口在8761,一个在8762。下面分别将两个节点进行启动,当第一个节点启动成功,第二个节点还没有完全启动时,第一个节点会报错,当两个节点都完全启动后,第一个节点会重新注册,并且状态刷新。

在需要注册的服务中,需要把eureka.client.service-url-defaultZone写上两个节点的URL,也就是http://localhost:8761/eureka/和http://localhost:8762/eureka/,这样就可以将服务注册在两个注册节点上了。

参考资料

[1] 史上最简单的SpringCloud教程 | 第一篇:服务的注册与发现


我和几位大佬建立了一个微信公众号,欢迎关注后查看更多技术干货文章
欢迎加入交流群QQ1107710098

你可能感兴趣的:(快速入门全栈)