在分布式系统领域有个著名的CAP定理:
C——数据一致性;
A——服务可用性;
P——服务对网络分区故障的容错性。
这三个特性在任何分布式系统中不能同时满足,最多同时满足两个。
Zookeeper是著名Hadoop的一个子项目,很多场景下Zookeeper也作为Service发现服务解决方案。Zookeeper保证的是CP,即任何时刻对Zookeeper的访问请求能得到一致的数据结果,同时系统对网络分割具备容错性,但是它不能保证每次服务请求的可用性。
而Spring Cloud Netflix在设计Eureka时遵守的就是AP原则。因为对于服务消费者来说,能消费才是最重要的——拿到可能不正确的服务实例信息后尝试消费一下,也好过因为无法获取实例信息而不去消费。所以,对于服务发现而言,可用性比数据一致性更加重要——AP胜过CP。
1、服务注册与服务发现
服务治理是微服务架构中最为核心和基础的模块,主要为各个微服务实例提供自动化注册与发现功能。
服务注册:服务治理框架会构建一个注册中心,每个服务向注册中心注册登记自己提供的服务,将服务名、主机、端口号、版本号、通信协议等告知注册中心,注册中心按服务名分类组织成一个服务清单。
例如:
有三个提供订单服务的实例分别运行在 192.168.0.100:8081、192.168.0.101:8082、192.168.0.102:8083;
还有四个提供用户服务的实例分别运行在 192.168.1.100:8091、192.168.1.101:8092、192.168.1.102:8093、192.168.1.103:8094;
当这些服务全部启动并成功注册到注册中心上后,注册中心会维护一份类似下面的一个服务清单:
| 服务名 | 服务地址 |
| 订单服务 | 192.168.0.100:8081、192.168.0.101:8082、192.168.0.102:8083 |
| 用户服务 | 192.168.1.100:8091、192.168.1.101:8092、192.168.1.102:8093、192.168.1.103:8094 |
服务发现:在服务治理框架下,服务之间不再通过具体实例地址来相互调用,而是通过向注册中心咨询并获取服务清单,以实现(通过服务名)对具体服务的调用。
例如:前台用户下单需要调用订单服务,首先向注册中心发起咨询订单服务的请求,注册中心返回订单服务位置清单,然后调用方通过负载策略选择其中某一个位置进行服务调用即可。
2、单点注册中心
创建一个空项目,pom.xml如下(后面都基于这个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.springcloud.demo</groupId> <artifactId>springcloud-demo</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <modules> <module>eureka-server</module> <module>eureka-service-provider</module> </modules> <name>Maven</name> <!-- FIXME change it to the project's website --> <url>http://maven.apache.org/</url> <inceptionYear>2001</inceptionYear> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.8.RELEASE</version> <relativePath/> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <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> <plugin> <artifactId>maven-surefire-plugin</artifactId> <configuration> <failIfNoTests>true</failIfNoTests> </configuration> </plugin> </plugins> </build> </project>