1.介绍
微服务架构是一种服务架构设计风格,简言之,微服务是将单个应用拆分为一组小型服务的方法。每个服务都在自己的进程中运行,服务之间轻量级通信机制(通常是HTTP资源API)。这些服务是围绕业务构建的,可以通过完全自动化的部署机制进行独立部署。对这些服务的集中管理是最低限度的,这些服务可以用不同的编程语言编写,并使用不同的数据存储数据技术。
微服务有自己url和端口,服务之间调用(如url)如果采用硬编码方式,维护起来比较麻烦,并且服务提供方信息发生变化时,服务调用方也跟着要改变。因此服务治理是微服务架构中最核心和基础的模块,主要用来实现各微服务实例的自动化注册和发现。Spring Cloud是一个微服务架构实施的综合性解决框架,它整合了许多被广泛实践过的框架作为实施的基础组件。在Spring Cloud微服务框架中,Spring Cloud Netflix是核心组件,Spring Cloud Eureka是Spring Cloud Netflix微服务组件的一部分,基于Netflix公司的Eureka模块做了二次封装,主要负责微服务架构中的服务注册和发现。
本文进行Eureka Server注册中心和集群的实践,新建了两个SpringBoot项目。
————springcloud-eureka:单节点服务注册中心。
————springcloud-eurekagroup:服务注册中心集群方式。
环境配置:
SpringBoot 2.1.8.RELEASE
SpringCloud Greenwich.SR3
2.服务注册中心
搭建一个Eureka单节点服务注册中心,详细如下:
【步骤一】:创建一个SpringBoot项目(项目名为springcloud-eureka),在pom.xml文件中添加eureka-servers的Maven依赖。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<properties>
<java.version>1.8</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
【步骤二】在SpringBoot项目配置文件application.properties中添加配置。配置内容如下:
server.port=8001
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/
关于上面配置文件的解释
server.port=8001 #表示该服务注册中心的端口号
eureka.instance.hostname=localhost #表示该服务注册中心实例的hostname
eureka.client.register-with-eureka=false #由于此应用是一个注册中心,默认情况下,它会向注册中心(它自己)注册自己,设置为false表示禁止这种默认行为
eureka.client.fetch-registry=false #表示不去检索其他服务,由于服务注册中心的职责就是维护服务实例,因此它并不需要检索服务,所以设置为false.
eureka.client.service-url.defaultZone #设置与Eureka Server交互的地址,查询和注册服务需要此地址,默认地址是 http://localhost:8761/eureka,多个地址可以使用英文逗号(,)分割。
【步骤三】在SpringBoot项目的启动类中添加一个@EnableEurekaServer
注解,启动项目即可。
@EnableEurekaServer
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
以上几个简单步骤就搭建了一个Eureka服务注册中心,可以通过地址https://localhost:8001
访问eureka信息面板,在Instances currently registered with eureka一栏上面显示为No instances available,表示目前无服务注册到eureka服务注册中心。
3.高可用注册中心
在微服务架构中,注册中心是比较关键的节点,如果是单节点的服务注册中心,注册中心发生故障,那么整个服务调用就会出现问题。所以需要一个高可用的服务注册中心,在Eureka中,使用集群的方式是很好的解决方案。实际上Eureka Server高可用实现是通过将自己作为服务向其他服务注册中心注册自己,这样就会形成一组互相注册的服务注册中心,以实现服务清单互相同步,达到高可用的效果。为了在单机上实现集群方式,可以使用SpringBoot项目多环境启动方式分别以不同的端口来启动项目。
【步骤一】:创建SpringBoot项目(项目名为springcloud-eurekagroup),同上面项目一样添加Eureka Server的maven依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<properties>
<java.version>1.8</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
【步骤二】:项目配置
1.创建application-peer1.properties,作为peer1服务注册中心的配置,并将serviceUrl指向peer2.
spring.application.name=spring-cloud-eureka
server.port=8001
eureka.instance.hostname=peer1
eureka.client.serviceUrl.defaultZone=http://peer2:8002/eureka/
eureka.server.enableSelfPreservation=false
2.创建application-peer2.properites,作为peer2服务注册中心的配置,并将ServiceUrl指向peer1.
spring.application.name=spring-cloud-eureka
server.port=8002
eureka.instance.hostname=peer2
eureka.client.serviceUrl.defaultZone=http://peer1:8001/eureka/
eureka.server.enableSelfPreservation=false
3.在etc/hosts文件中添加对peer1和peer2的转换
为了上面配置的host形式的serviceUrl能在本地正确访问到,对peer1和peer2进行转化,hosts文件在Windows系统路径为C:\Windows\System32\drivers\etc
。
127.0.0.1 peer1
127.0.0.1 peer2
4.项目打包成jar,通过spring.profiles.active
属性来分别启动peer1和peer2。
将项目打包成jar,可以直接通过命令mvn clean package -Dmaven.test.skip=true
来打包,或者eclipse中可以通过Run as->Maven build… 输入打包命令clean package -Dmaven.test.skip=true
,其中-Dmaven.test.skip=true
表示不编译和执行测试用例。打包后在${project}/target下面可找到jar包。
分别以peer1和peer2的配置信息启动eureka
java -jar springcloud-eurekagroup-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer1
java -jar springcloud-eurekagroup-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer2
上面以不同的配置文件启动项目后,可以访问peer1服务注册中心,地址为http://localhost:8001/,如下图所示。其中DS Replicas显示为peer2,registered-replicas和available-replicas中有了peer2 Eueka server。访问peer2服务注册中心:http://localhost:8002/,能看到,registered-replicas和available-replicas中有了peer1 节点。尝试关闭peer2服务注册中心,此时无法访问peer1,可以看到unavailable-replicas一栏中出现了peer2节点。
4.问题
1.EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY’RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.
Eureka Server服务注册中心控制面板出现上面这种警告,是因为触发了Eureka Server的自我保护机制。当微服务实例注册到Eureka Server上时,会维护一个心跳,告诉Eureka Server自己处于健康状态。EurekaServer在运行期间,会统计心跳失败的比例在15分钟内是否低于85%,如果出现低于的情况(单机容易满足,生产环境大多是因为网络不稳定导致),Eureka Server会将当前实例注册信息保护起来,让这些实例不会过期,尽可能保护这些注册信息。可以通过以下配置来禁用自我保护模式。
eureka.server.enableSelfPreservation=false
2.Cannot execute request on any known server
出现这种问题很多是application.properties文件中配置错误导致。参考解决方式如下:
方式一:Eureka Server内置客户端默认会向Eureka Server注册自身,并且尝试获取尚未可用的注册表(因为此时还未有服务注册),Eureka Server作为服务注册中心,不需要上面两种行为,设置为禁用。
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
方式二:配置错误,检查eureka.client.serviceUrl.defaultZone配置的url。
方式三:在搭建Eureka Server集群时,先启动的注册中心节点会报错,因为无法连接到还未启动的注册中心节点,这种属于正常情况。
5.参考文章
1.SpringCloud官网
2.《Spring微服务实战》
3.《Spring Cloud与Docker微服务架构实战》
4.《Microservices》