什么是微服务注册中心?

在上一篇文章《Spring Cloud介绍》中,提到有一句话:微服务框架可以为这些微小的服务提供统一的管理和必要的工具,使它们更易于开发和维护。

“统一的管理和必要的工具”正是微服务框架与单纯地“分布式应用”的区别所在。我们在后续的文章也主要是介绍这样一些Spring Cloud提供的管理微服务的组件和工具。

微服务注册中心最主要的功能正是用来“管理”微服务的。它相当于一个信息中心,保存着每个微服务的ip地址等信息。这样当其它微服务要调用这个微服务时,就可以去注册中心拿到ip,再根据ip去访问相应的微服务。如下图:
在这里插入图片描述

为什么需要注册中心?

注册中心相当于“婚介所”或者“房屋中介所”。试想一下,如果没有一个这样的中间角色,当一个微服务(消费者)需要调用另一个微服务(生产者)时,它需要保存生产者的地址(如ip,端口等信息)。而这个时候一旦生产者的地址产生了变化,比如:

  • 新增了节点
  • 减少了节点
  • 原有结点的ip或端口变化

就会导致所有的消费者更改配置。传统分布式系统是对每个API创建一个对外的网关,一般使用ELB等负载均衡工具再配上DNS系统来实现
在这里插入图片描述
这样虽然一定程度上能解决服务调用之间的问题,但仍然需要维护大量的ELB/DNS等信息,而且当结点想要动态地增加或删除时,需要去修改ELB的配置。

使用注册中心后,结点的注册、删除、健康检查等功能都能自动化。消费者再也不需要手动去挨个寻找和维护任何生产者的地址信息,只是定时去注册中心取一下就行。

注册中心技术选型
FeatureeurekaConsulzookeeperetcd
服务健康检查可配支持服务状态,内存,硬盘等(弱)长连接,keepalive连接心跳
多数据中心支持
kv 存储服务支持支持支持
一致性算法raftpaxos增强raft
capapcpcpcp
使用接口(多语言能力)http(sidecar)支持 http 和 dns客户端http/grpc
watch 支持支持 long polling/大部分增量全量/支持long polling支持支持 long polling
自身监控metricsmetricsmetrics
安全acl /https aclhttps支持(弱)
spring cloud 集成已支持已支持已支持已支持

关于分布式CAP的理论,本文不细讲,有兴趣的读者自己去了解一下或者参考我的这篇文章我所了解的分布式事物。C代表一致性,A代表高可用性,P代表分区容错性。在分布式系统中,三者不能同时满足,而P是一定需要满足的,所以常见的分布式系统要么满足AP,要么满足CP。

本文以Eureka为例来搭建和使用注册中心,Eureka是Netflix自己开发的,它是通过在客户端配置所有注册中心结点来实现高可用的:

eureka:
    instance:
        hostname: localhost
client:
    registerWithEureka: false
    fetchRegistry: false
    serviceUrl:
        defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
使用Eureka
  • 首先创建一个主Maven工程,在其pom文件引入依赖,Spring Boot版本为2.1.5.RELEASESpring Cloud版本为Finchley.RELEASE。这个pom文件作为父pom文件,起到依赖版本控制的作用,其他module工程继承该pom。
<?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.bazooka</groupId>
    <artifactId>Eureka-sample</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>com.bazooka</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.5.RELEASE</version>
    </parent>

    <modules>
        <module>eureka-server</module>
        <module>service-client</module>
    </modules>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
  • 创建eureka-server,作为服务注册中心。
    File -> New -> Project…
    在这里插入图片描述
    选择cloud discovery->eureka server ,然后一直下一步就行了。
    在这里插入图片描述
    创建好之后其pom继承了父pom文件,并引入spring-cloud-starter-netflix-eureka-server的依赖。
<?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.bazooka</groupId>
    <artifactId>eureka-server</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>eureka-server</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>com.bazooka</groupId>
        <artifactId>Eureka-sample</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>

</project>

首先需要在springboot工程的启动application类上加@EnableEurekaServer

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

在默认情况下erureka server也是一个eureka client ,必须要指定一个 server。eureka server的配置文件appication.yml

server:
    port: 8761

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

spring:
    application:
        name: eurka-server

通过eureka.client.registerWithEureka:false和fetchRegistry:false来表明自己是一个eureka server。
启动项目之后,输入如下链接可以看到页面
在这里插入图片描述

  • 创建一个eureka client作为服务提供者
    创建过程同eureka server,不再赘述,创建好的eureka client的pom如下
<?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.bazooka</groupId>
	<artifactId>service-client</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>service-client</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>com.bazooka</groupId>
		<artifactId>Eureka-sample</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>

	<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
		</dependency>

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

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

通过注解@EnableEurekaClient 表明自己是一个eureka client。

@SpringBootApplication
@EnableEurekaClient
@RestController
public class ServiceClientApplication {

	public static void main(String[] args) {
		SpringApplication.run(
				ServiceClientApplication.class, args );
	}

	@Value("${server.port}")
	String port;

	@GetMapping("/client")
	public String home(@RequestParam(value = "name", defaultValue = "bazooka") String name) {
		return "hi " + name + " ,i am from port:" + port;
	}

}

仅仅@EnableEurekaClient是不够的,还需要在配置文件中注明自己的服务注册中心的地址,application.yml配置文件如下

server:
    port: 8762

spring:
    application:
        name: service-client

eureka:
    client:
        serviceUrl:
            defaultZone: http://localhost:8761/eureka/

启动项目,会在client端看到如下文字。
在这里插入图片描述
同时在server端也可以看到如下效果。
在这里插入图片描述
这个时候就会发现一个服务已经在注册中心了。

源码地址

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐