分享

服务治理

 __安如少年 2020-12-07

服务治理是微服务架构中核心模块,它主要用来实现各个微服务实例的自动化注册、发现、续约和销毁。

Spring Cloud Eureka是Spring Cloud Netflix微服务套件中的一部分,它基于Netflix Eureka做了二次封装。主要负责完成微服务架构中的服务治理功能。

Eureka服务治理架构

在这里插入图片描述

服务注册

在服务治理框架中,一定会有一个或者多个注册中心,每个服务提供者都要向注册中心注册自己提供的服务,注册的信息包括主机IP与端口号、服务版本号、通讯协议等信息。注册中心按照服务名分类组织服务列表,使用一个数据结构描述这些元信息,通常使用二级Map存储,注册中心以周期心跳检测的方式去监测服务是否可用,若不可用需要从服务清单中剔除,以达到排除故障服务的效果。

服务发现

在服务治理框架中,消费者调用服务时使用注册中心的地址,通过服务名发起请求调用服务。服务调用方通过服务名从服务注册中心的服务清单中获取服务实例的列表清单,通过指定的负载均衡策略调用相应的服务。

Eureka服务端

Eureka服务端,即服务注册中心。提供服务治理功能,启动类使用注解@EnableEurekaServer标注,启动后作为注册中心角色。注册中心支持集群模式部署,当集群中某个注册中心发生故障时,Eureka会自动转入自我保护模式,Eureka允许在分片发生故障的时候继续提供服务的发现和注册,当故障节点恢复时,集群中的的不同服务注册中心通过异步模式互相复制维持各节点最新的状态。

Eureka客户端

Eureka客户端,即服务提供者和服务消费者,它们都是Eureka客户端,它们启动后向注册中心(Eureka服务端)注册和发现其他服务。从注册中心获取服务清单列表,并周期性的发送心跳来更新它的服务租约。同时,从服务端查询当前注册的服务信息并把它们缓存到本地并周期行的刷新服务状态。

创建Eureka Server服务

设计POM.xml

<project xmlns="http://maven./POM/4.0.0" xmlns:xsi="http://www./2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven./POM/4.0.0 http://maven./xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

<!-- 
SpringCloud是基于SpringBoot框架的,必须引入SpringBoot的依赖
 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
</parent>

<groupId>com.test</groupId>
<artifactId>eureka-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>eureka-server</name>
<url>http://maven.</url>

<properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<!-- 
Spring Cloud的命名没有按照版本方式管理,是采用命名方式,
版本名称采用伦敦地铁站的名称命名,根据字母表的顺序对应版本时间顺序,
比如最早的Release版本号为Angel,第二个Release版本为Brixton
 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
  <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
  </dependency>
  <!-- 
  Eureka 服务依赖
   -->
  <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
  </dependency>
</dependencies>

</project>

配置文件

application.properties

server.port=8110
eureka.instance.hostname=localhost
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/

启动类代码

package com.test.eureka_server;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@EnableEurekaServer
@SpringBootApplication
public class App 
{
    public static void main( String[] args )
    {
        SpringApplication.run(App.class, args);
    }
}

注册中心高可用设计

在高可用系统中,我们往往将服务搭建为集群,不仅可以提供负载均衡有可以提供高可用功能,
SpringCloud框架汇总,服务注册中心也是一个独立的服务,我们需要注册中心是高可用的和负载均衡的
因为一旦服务注册中心出现故障,整个微服务系统就会瘫痪,因此需要保证服务注册中心的高可用。
Eureka Server的高可用是将自己做为服务向其他服务注册中心注册自己,形成一组互相注册的服务注册中心,以实现服务清单的互相同步,达到高可用的效果。

实现Eureka Server注册中心高可用和负载均衡非常简单,只修改配置文件即可,负载均衡的策略有调用服务的客户端实现。

application-node1.properites

#服务注册中心端口号
server.port=8110
#服务注册中心实例的主机名
eureka.instance.hostname=10.10.10.1
#是否向自注册
eureka.client.register-with-eureka=false
#是否从注册中心检索服务清单
eureka.client.fetch-registry=false
#服务注册中心的配置内容,多个注册中心地址使用英文逗号分隔
eureka.client.serviceUrl.defaultZone=http://10.10.10.2/eureka/,http://10.10.10.3/eureka/

application-node2.properties

#服务注册中心端口号
server.port=8110
#服务注册中心实例的主机名
eureka.instance.hostname=10.10.10.2
#是否向自注册
eureka.client.register-with-eureka=false
#是否从注册中心检索服务清单
eureka.client.fetch-registry=false
#服务注册中心的配置内容,多个注册中心地址使用英文逗号分隔
eureka.client.serviceUrl.defaultZone=http://10.10.10.1/eureka/,http://10.10.10.3/eureka/

application-node3.properties

#服务注册中心端口号
server.port=8110
#服务注册中心实例的主机名
eureka.instance.hostname=10.10.10.3
#是否向自注册
eureka.client.register-with-eureka=false
#是否从注册中心检索服务清单
eureka.client.fetch-registry=false
#服务注册中心的配置内容,多个注册中心地址使用英文逗号分隔
eureka.client.serviceUrl.defaultZone=http://10.10.10.1/eureka/,http://10.10.10.2/eureka/

剔除故障服务节点

注册中心Eureka Server每隔60秒中检查所有注册的服务是否存活,如果超过默认时长90秒没有收到服务的续约请求,就将服务从注册中心删除掉。

服务自我保护

服务向注册中心注册后,会维护一个心跳连接,每隔固定时长向注册中心发送心跳信息,证明自己是存活的。注册中心会统计最近15分钟之内的有效心跳数与总数的比例,当比例小于85%时,会将当前服务保护起来,类似服务半关闭半开放状态,允许一个客户端调用此服务,根据调用结果决定是否真正关闭此服务,这些由客户端容错机制决定,比如请求重试,断路器等。

eureka.server.enableSelfPreservation=true. 可以设置改参数值为false,以确保注册中心将不可用的实例删除

服务续约

服务向注册中心注册以后,每个服务提供者会维护一个心跳用来持续连接Eureka Server,通知注册中心服务继续可用,否则Eureka Server的剔除任务会将该服务实例从服务列表中排除出去。此过程为服务续约。

服务续约的两个重要属性:

eureka.instance.lease-expiration-duration-in-seconds

leaseExpirationDurationInSeconds,表示eureka server至上一次收到client的心跳之后,等待下一次心跳的超时时间,在这个时间内若没收到下一次心跳,则将移除该instance。
默认为90秒
如果该值太大,则很可能将流量转发过去的时候,该instance已经不存活了。
如果该值设置太小了,则instance则很可能因为临时的网络抖动而被摘除掉。
该值至少应该大于leaseRenewalIntervalInSeconds

eureka.instance.lease-renewal-interval-in-seconds

leaseRenewalIntervalInSeconds,表示eureka client发送心跳给server端的频率。如果在leaseExpirationDurationInSeconds后,server端没有收到client的心跳,则将摘除该instance。除此之外,如果该instance实现了HealthCheckCallback,并决定让自己unavailable的话,则该instance也不会接收到流量。
默认30秒

region(地域)与zone(可用区)

region代表地域,zone代表区域,它们是AWS中的概念。在非AWS环境下,我们可以简单地将region理解为地域,zone理解成机房。一个region可以包含多个zone,可以理解为一个地域内的多个不同的机房。

客户端服务的配置文件
eureka.client.availabilityZones.beijing=myzone # beijing是region
eureka.client.region=beijing

客户端服务使用Ribbon的默认策略会优先访问通客户端处于同一个region中的服务端实例,只有当同一个zone中没有可用服务端实例的时候才会访问其他zone中的实例

安全访问

注册中心对外提供服务,默认没有用户名和密码,无法保护数据安全,可以使用Spring-Security保证数据安全

pom文件中引入依赖

<dependency> 
   <groupId>org.springframework.boot</groupId> 
   <artifactId>spring-boot-starter-security</artifactId> 
</dependency>

application.properties配置文件

server.port=8110
eureka.instance.hostname=localhost
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/

security.user.name=chenqx
security.user.password=123

客户端服务配置注册中心地址为
eureka.client.serviceUrl.defaultZone=http://:@ e u r e k a . i n s t a n c e . h o s t n a m e : {eureka.instance.hostname}: eureka.instance.hostname:{server.port}/eureka/

加入安全保护后Eureka控制界面
在这里插入图片描述
在这里插入图片描述

打包成独立运行Jar
修改POM文件

<project xmlns="http://maven./POM/4.0.0" xmlns:xsi="http://www./2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven./POM/4.0.0 http://maven./xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

<!-- 
SpringCloud是基于SpringBoot框架的,必须引入SpringBoot的依赖
 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
</parent>

<groupId>com.test</groupId>
<artifactId>eureka-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>eureka-server</name>
<url>http://maven.</url>

<properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<!-- 
Spring Cloud的命名没有按照版本方式管理,是采用命名方式,
版本名称采用伦敦地铁站的名称命名,根据字母表的顺序对应版本时间顺序,
比如最早的Release版本号为Angel,第二个Release版本为Brixton
 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
  <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
  </dependency>
  <!-- 
  Eureka 服务依赖
   -->
  <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
  </dependency>
  
  <!-- 
  SpringBoot集成Spring Security
   -->
<dependency> 
<groupId>org.springframework.boot</groupId> 
<artifactId>spring-boot-starter-security</artifactId> 
</dependency> 
</dependencies>

<!-- 
 根据SpringCloud约定打成可以独立执行Jar包,使用Maven命令
 mvn  package  spring-boot:repackage
 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

执行maven命令
mvn package spring-boot:repackage
在这里插入图片描述

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多