Spring-Cloud Euraka介绍
Spirng Cloud Eureka使用Netflix Eureka来实现服务注册与发现。它既包含了服务端组件,也包含了客户端组件,并且服务端与客户端均采用java编写,所以Eureka主要适用于通过java实现的分布式系统,或是JVM兼容语言构建的系统。Eureka的服务端提供了较为完善的REST API,所以Eureka也支持将非java语言实现的服务纳入到Eureka服务治理体系中来,只需要其他语言平台自己实现Eureka的客户端程序。目前.Net平台的Steeltoe、Node.js的eureka-js-client等都已经实现了各自平台的Ereka客户端组件。
Euraka介绍
Eureka由多个instance(服务实例)组成,这些服务实例可以分为两种:Eureka Server和Eureka Client。为了便于理解,我们将Eureka client再分为Service Provider和Service Consumer。
- Eureka Server 提供服务注册和发现
- Service Provider 服务提供方,将自身服务注册到Eureka,从而使服务消费方能够找到
- Service Consumer服务消费方,从Eureka获取注册服务列表,从而能够消费服务
搭建注册服务中心
创建一个Spring Boot工程,命名为Eureka-Server,并在pom文件中引入依赖:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
<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>
启动一个服务注册中心
启动一个服务注册中心的方式很简单,就是在Spring Boot的入口类上添加一个@EnableEurekaServer
注解,如下:
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
配置服务注册中心
Eureka Server会将自己也作为客户端来尝试注册自己,我们需要禁用它的客户端禁用行为。
下面是一个Eureka Server的application.properites的相关配置:
#服务注册中心端口号
server.port=1110
#服务注册中心实例的主机名
eureka.instance.hostname=localhost
#是否向服务注册中心注册自己【由于我们目前创建的应用是一个服务注册中心,而不是普通的应用,默认情况下,这个应用会向注册中心(也是它自己)注册它自己,设置为false表示禁止这种默认行为】
eureka.client.register-with-eureka=false
#是否检索服务【表示不去检索其他的服务,因为服务注册中心本身的职责就是维护服务实例,它也不需要去检索其他服务】
eureka.client.fetch-registry=false
#服务注册中心的配置内容,指定服务注册中心的位置
eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
注册服务提供者
在创建好的工程中,我们需要添加Eureka依赖,添加方式如下:
<?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>org.sang</groupId> <artifactId>provider</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>provider</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.SR3</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>
创建应用的入口
这是一个web工程,所以我们添加一个Controller,在该Controller中提供一个访问入口,如下:
@RestController public class HelloController { private final Logger logger = Logger.getLogger(getClass()); @Autowired private DiscoveryClient client; @RequestMapping(value = "/hello", method = RequestMethod.GET) public String index() { List<ServiceInstance> instances = client.getInstances("hello-service"); for (int i = 0; i < instances.size(); i++) { logger.info("/hello,host:" + instances.get(i).getHost() + ",service_id:" + instances.get(i).getServiceId()); } return "Hello World"; } }
这里创建服务之后,在日志中将服务相关的信息打印出来。
激活Eureka中的DiscoveryClient
在Spring Boot的入口函数处,通过添加@EnableDiscoveryClient注解来激活Eureka中的DiscoveryClient实现(因为我们在HelloController中注入了DiscoveryClient)。
@EnableDiscoveryClient @SpringBootApplication public class ProviderApplication { public static void main(String[] args) { SpringApplication.run(ProviderApplication.class, args); } }
配置服务名称和注册中心地址
最后的最后,我们在application.properties文件中配置一下服务名和注册中心地址即可,如下:
spring.application.name=hello-service eureka.client.service-url.defaultZone=http://localhost:1111/eureka
高可用服务注册中心
Eureka Server的高可用实际上就是将自己做为服务向其他服务注册中心注册自己,这样就可以形成一组互相注册的服务注册中心,以实现服务清单的互相同步,达到高可用的效果。
Eureka Server的同步遵循着一个非常简单的原则:只要有一条边将节点连接,就可以进行信息传播与同步。可以采用两两注册的方式实现集群中节点完全对等的效果,实现最高可用性集群,任何一台注册中心故障都不会影响服务的注册与发现
(1)创建application-peer1.properties
server.port=1111
eureka.instance.hostname=master
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.instance.preferIpAddress=true
eureka.server.enableSelfPreservation=false【可以设置改参数值为false,以确保注册中心将不可用的实例删除】
eureka.client.serviceUrl.defaultZone=http://backup1:1112/eureka/,http://backup2:1113/eureka/
(2)创建application-peer2.properties
server.port=1112
eureka.instance.hostname=backup1
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.instance.preferIpAddress=true
eureka.server.enableSelfPreservation=false【可以设置改参数值为false,以确保注册中心将不可用的实例删除】
eureka.client.serviceUrl.defaultZone=http://master:1111/eureka/,http://backup2:1113/eureka/
(3)创建application-peer3.properties
server.port=1113
eureka.instance.hostname=backup2
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.instance.preferIpAddress=true
eureka.server.enableSelfPreservation=false【可以设置改参数值为false,以确保注册中心将不可用的实例删除】
eureka.client.serviceUrl.defaultZone=http://master:1111/eureka/,http://backup1:1112/eureka/
(4) 在hosts文件中增加如下配置
127.0.0.1 master
127.0.0.1 backup1
127.0.0.1 backup2