微服务注册中心
注册中心可以说是微服务架构中的”通讯录“,它记录了服务和服务地址的映射关系。在分布式架构中,服务会注册到这里,当服务需要调用其它服务时,就这里找到服务的地址,进行调用。
注册中心的主要作用
服务注册中心(下称注册中心)是微服务架构非常重要的一个组件,在微服务架构里主要起到了协调者的一个作用。注册中心一般包含如下几个功能:
- 服务发现:
- 服务注册/反注册:保存服务提供者和服务调用者的信息;
- 服务订阅/取消订阅:服务调用者订阅服务提供者的信息,最好有实时推送的功能;
- 服务路由(可选):具有筛选整合服务提供者的能力。
- 服务配置:
- 配置订阅:服务提供者和服务调用者订阅微服务相关的配置;
- 配置下发:主动将配置推送给服务提供者和服务调用者。
- 服务健康检测:
- 检测服务提供者的健康情况。
常见的注册中心
zookeeper
zookeeper它是一个分布式服务框架,是Apache Hadoop 的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等。简单来说zookeeper=文件系统+监听通知机制。
Eureka
Eureka是在Java语言上,基于Restful Api开发的服务注册与发现组件,Springcloud Netflix中的重要组件。
Consul
Consul是由HashiCorp基于Go语言开发的支持多数据中心分布式高可用的服务发布和注册服务软件,采用Raft算法保证服务的一致性,且支持健康检查。
Nacos
Nacos是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。简单来说 Nacos 就是注册中心 + 配置中心的组合,提供简单易用的特性集,帮助我们解决微服务开发必会涉及到的服务注册与发现,服务配置,服务管理等问题。Nacos 还是 Spring Cloud Alibaba 组件之一,负责服务注册与发现。
最后我们通过一张表格大致了解Eureka、Consul、Zookeeper、Nacos的异同点。选择什么类型的服务注册与发现组件可以根据自身项目要求决定。
组件名 | 语言 | CAP | 一致性算法 | 服务健康检查 | 对外暴露接口 |
---|---|---|---|---|---|
Eureka | Java | AP | 无 | 可配置 | HTTP |
Consul | GO | CP | Raft | 支持 | HTTP/DNS |
Zookeeper | Java | CP | Paxos | 支持 | 客户端 |
Nacos | Java | AP | Raft | 支持 | HTTP |
Eureka的概述
Eureka基础知识
Eureka是Netflflix开发的服务发现框架,SpringCloud将它集成在自己的子项目spring-cloud-netflflix中,实现SpringCloud的服务发现功能。
上图简要描述了Eureka的基本架构,由3个角色组成:
- Eureka Server:提供服务注册和发现;
- Service Provider:服务提供方,将自身服务注册到Eureka,从而使服务消费方能够找到;
- Service Consumer:服务消费方,从Eureka获取注册服务列表,从而能够消费服务。
注意: 服务提供方可以同时也是服务消费方的角色,同理服务消费方也可能是服务提供方角色。
Eureka交互流程和原理
图是来自Eureka官方的架构图,大致描述了Eureka集群的工作过程。图中包含的组件非常多,可能比较难以理解,我们用通俗易懂的语言解释一下:
- Application Service 相当于本书中的服务提供者,Application Client相当于服务消费者;
- Make Remote Call,可以简单理解为调用RESTful API;
- us-east-1c、us-east-1d等都是zone,它们都属于us-east-1这个region。
由图可知,Eureka包含两个组件:Eureka Server和Eureka Client,它们的作用如下:
- Eureka Client是一个Java客户端,用于简化与Eureka Server的交互;
- Eureka Server提供服务发现的能力,各个微服务启动时,会通过Eureka Client向Eureka Server进行注册自己的信息(例如网络信息),Eureka Server会存储该服务的信息;
- 微服务启动后,会周期性地向Eureka Server发送心跳(默认周期为30秒)以续约自己的信息。如果Eureka Server在一定时间内没有接收到某个微服务节点的心跳,Eureka Server将会注销该微服务节点(默认90秒);
- 每个Eureka Server同时也是Eureka Client,多个Eureka Server之间通过复制的方式完成服务注册表的同步;
- Eureka Client会缓存Eureka Server中的信息。即使所有的Eureka Server节点都宕掉,服务消费者依然可以使用缓存中的信息找到服务提供者。
综上,Eureka通过心跳检测、健康检查和客户端缓存等机制,提高了系统的灵活性、可伸缩性和可用性。
Eureka注册中心搭建
- 创建项目,父工程的
pom.xml
文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.itcrud</groupId>
<artifactId>msc-cloud</artifactId>
<version>1.0-SNAPSHOT</version>
<modules>
<module>eureka-server7001</module>
</modules>
<!-- 指定打包方式,默认是jar -->
<packaging>pom</packaging>
<!-- 统一管理jar包版本 -->
<properties>
<!-- 必备之一:maven编译指定java的版本 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<!-- 必备之二:单元测试junit测试和日志log4j的版本号 -->
<junit.version>4.13</junit.version>
<!-- 必备之三:springboot、springCloud、springCloudAlibaba的版本号 -->
<!-- 必备之四:lombok的版本号 -->
<lombok.version>1.18.24</lombok.version>
<!-- 必备之五:数据库连接和数据库连接池的版本号 -->
<mysql.version>8.0.29</mysql.version>
<druid.version>1.2.11</druid.version>
<!-- 必备之六:数据层Mybatis的版本号 -->
<mybatis.spring.boot.version>1.3.0</mybatis.spring.boot.version>
<!-- 必备之七:fastjson、guava、commons-lang3工具版本号 -->
<fastjson.version>2.0.7</fastjson.version>
<guava.version>23.0</guava.version>
<commons-lang3.version>3.12.0</commons-lang3.version>
</properties>
<!--用来做依赖的管理,锁定依赖的版本号,一般都是放在父工程内,当子工程需要使用,只需指定groupId、artifactId,无需指定版本号-->
<!--只对依赖进行管理,不做具体的引入-->
<!-- 优势:统一管理,版本变更统一修改;子工程引入简单;不容易出现版本冲突问题 -->
<dependencyManagement>
<dependencies>
<!-- spring boot 2.3.12.RELEASE-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.3.12.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- spring Cloud Hoxton.SR12-->
<!-- spring boot 和 spring Cloud版本号的依赖关系可以到spring Cloud官网上查询 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR12</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.7.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
<addResources>true</addResources>
</configuration>
</plugin>
</plugins>
</build>
</project>
- 在Eureka子工程的
pom.xml
中添加Spring Cloud的依赖,这里使用Eureka2.0版本:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>msc-cloud</artifactId>
<groupId>com.itcrud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>eureka-server7001</artifactId>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>com.itcrud</groupId>
<artifactId>cloud-api-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
</project>
- 创建Eureka子工程,工程内不用写业务代码,添加一个启动类即可,启动类如下:
@SpringBootApplication
@EnableEurekaServer
public class EurekaRegistryApp {
public static void main(String[] args) {
SpringApplication.run(EurekaRegistryApp.class,args);
}
}
- 修改
application.yml
文件,添加eureka的配置信息。
server:
port: 7001
eureka:
instance:
hostname: eureka7001.com
client:
# 是否将自己注册到eureka中
register-with-eureka: false
fetch-registry: false
service-url:
# 当处于集群环境下的时候,这里配置的是集群中除自己以外其他节点的地址,实现相互注册,相互守望
defaultZone: http://eureka7002.com:7002/eureka/
- 直接运行启动类
EurekaRegistryApp
中的main
方法,简单的Eureka注册中心就搭建成功了,通过http://localhost:1001
即可访问Eureka的可视化注册中心。