Spring Cloud Eureka是Spring Cloud提供的服务治理组件,用来实现各个微服务实例的自动化注册和发现。
Spring Cloud Eureka是Spring Cloud Netflix微服务套件中的一部分,基于Netflix Eureka做了二次封装,并且增加了Spring Boot风格的自动化配置,我们只需要通过简单引入依赖和注解配置就能让Spring Boot构建的微服务和Eureka服务治理体系进行整合。
除了Spring Cloud Eureka,Spring Cloud Consul、Spring Cloud Zookeeper也是Spring Cloud提供的服务注册和发现的组件。
Eureka 完全开源,并且经历了Netflix公司生产环境的考验,三年迭代,功能和性能都很稳定。是Spring Cloud首选推荐的服务注册和发现组件。与Spring Cloud的Ribbon、Hystrix、Zuul等组件无缝对接。
Spring Cloud Eureka包含服务端和客户端两部分,下面是Spring Cloud Eureka的架构图:
Application Service:服务提供者
Application Client:服务消费者
Make Remote Call:接口调用
us-east-1c,us-east-1d,us-east-1e是zone,都属于us-east-1这个region
Eureka包含两个组件,Eureka Server和Eureka Client
Eureka Server,Eureka服务端,提供服务发现的能力,当微服务启动的时候,就向Eureka Server注册自己的信息(ip,端口,微服务名称等),Eureka Server会存储这些信息。
Eureka Client,Eureka客户端,java的,用于简化和Eureka Server的交互。
微服务启动后,会周期性的向Eureka Server发送心跳以续约自己的租期。(默认30秒)
如果Eureka Server在一定时间内没有接收到某个微服务实例的心跳,Eureka Server将会注销该实例(默认90秒)
默认情况下,Eureka Server同时也是Eureka Client,多个Eureka Server实例之间通过复制的方式来实现服务注册表中数据的同步。
Eureka Client会缓存服务注册表中的信息,这种方式有一定的优势,微服务无需每次请求都查询Eureka Server,从而降低了Eureka Server的压力及时Eureka Server所有的节点都宕掉,服务消费者依然可以使用缓存中的信息找到服务提供者并完成调用。
下面实际操作一下,创建两个微服务。先创建一个服务提供者,再创建一个服务消费者,服务消费者先通过普通的方式调用服务提供者,再通过Spring Eureka 调用服务提供者。
先创建一个microservice-provider项目,作为服务提供者。
pom文件中引入Spring Boot的依赖:
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>1.4.3.RELEASEversion>
parent>
再添加Spring MVC的支持:
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
spring-boot-starter-parent定义了Spring Boot版本的基础依赖以及一些默认配置内容,比如,配置文件application.properties的位置等。
spring-boot-starter-web,是全栈web开发模块,包含嵌入式Tomcat,Spring MVC。
配置完pom依赖之后,再添加MicroServiceProviderApplication文件:
@SpringBootApplication
public class MicroServiceProviderApplication {
public static void main(String[] args) {
SpringApplication.run(MicroServiceProviderApplication.class, args);
}
}
然后再添加一个Controller,用来提供服务,这里为了简单起见,直接返回hello world。
@RestController
public class ProviderController {
@RequestMapping(value = "/provider", method = RequestMethod.GET)
public String provider() {
return "hello world";
}
}
之后,编写配置文件application.properties,添加如下配置:
server.port=8000
spring.application.name=microservice-provider
到这里,服务提供者项目就写完了,接下来,再写服务消费者微服务。
创建一个microservice-consumer项目,作为服务消费者。配置和服务提供者类似,pom文件同样添加spring-boot-starter-parent和spring-boot-starter-web的依赖。编写MicroServiceConsumeApplication作为启动类,并在启动类中实例化RestTemplate对象。
@SpringBootApplication
public class MicroServiceConsumeApplication {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(MicroServiceConsumeApplication.class, args);
}
}
然后创建ConsumerController作为消费者方法,用来去调用服务提供者,这里通过restTemplate去请求服务提供者的API:
import org.springframework.web.client.RestTemplate;
@RestController
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value = "/consumer", method = RequestMethod.GET)
public String consumer() {
return this.restTemplate.getForEntity("http://localhost:8000/provider", String.class).getBody();
}
}
接下来配置服务消费者的application.properties,添加如下内容:
server.port=9000
spring.application.name=microservice-consumer
这样,服务消费者也写好了,本地启动这两个服务的话,访问http://localhost:9000/consumer,就可以看到返回的hello world。
但是这种调用方式,只是通过硬编码的方式,在程序中写死了服务提供者的地址,然后去请求的API,这样就会存在很多问题,试用场景有限,无法动态伸缩。
所以,就需要一个服务发现机制,服务消费者通过这种机制去发现服务提供者,然后再去调用,这样就不是硬编码了。
接下来,创建一个Eureka Server作为注册中心,然后再把服务提供者和服务消费者两个微服务进行改造,改造成Eureka Client,并且注册到注册中心。这样,当服务消费者再调用服务提供者的时候,就可以通过注册中心,获得服务提供者的地址,然后进行调用。
接下来,创建Eureka Server项目:eurekaserver
在pom文件中给项目添加依赖:
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-eureka-serverartifactId>
dependency>
dependencies>
之后再编写启动类:EurekaServerApplication
@SpringBootApplication
@EnableEurekaServer//声明这是一个Eureka server
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
在启动类上添加@EnableEurekaServer注解,声明这是一个Eureka Server。
最后在application.properties文件中,添加配置项:
server.port=8761
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
server.port=8761指明了项目启动的端口。
eureka.client.register-with-eureka=false,这个配置项表示是否将自己注册到Eureka Server,默认为true(默认情况下,Eureka Server也是一个Eureka Client),由于我们这里只有这一个Eureka Server,所以把这个配置项设置为false。
eureka.client.fetch-registry=false,这个配置项表示是否从Eureka Server获取配置信息,默认为true。由于我们这里只有这一个Eureka Server,所以把这个配置项设置为false。
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/ 这个配置项是与Eureka Server交互的地址。注册服务、查询服务,都是这个地址。
经过上面几步配置,我们的Eureka Server就开发完成了,接下来启动这个项目,在浏览器输入http://localhost:8761,就可以看到Eureka Server 的界面。
接下来,改造服务提供者和服务消费者。
先修改服务提供者,在pom文件中添加依赖:
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-eurekaartifactId>
dependency>
然后修改MicroServiceProviderApplication,在上面添加注解@EnableDiscoveryClient,声明是一个Eureka client:
@EnableDiscoveryClient//声明是一个Eureka client
@SpringBootApplication
public class MicroServiceProviderApplication {
public static void main(String[] args) {
SpringApplication.run(MicroServiceProviderApplication.class, args);
}
}
之后配置文件中添加配置项:
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
配置完成之后启动项目,项目启动的时候,就会作为一个Eureka client向Eureka Server注册信息,注册的地址为http://localhost:8761/eureka/,这个地址就是我们Eureka Server启动的时候,指定的注册地址。
此时再刷新http://localhost:8761,就可以看到Eureka Server 的界面上已经注册了一个服务了,服务名称是microservice-provider。
然后继续再改造服务消费者,改造方式和microservice-provider一样,也是在pom文件中添加spring-cloud-starter-eureka的依赖,在MicroServiceConsumeApplication上面添加注解@EnableDiscoveryClient注解,在application.properties中添加服务注册地址eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
除此之外,在TestTemplate生成的地方,添加@LoadBalanced注解,使用负载均衡。(关于负载均衡,后续文章接续介绍)
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
修改restTemplate调用的地址,原来是调用http://localhost:8000/provider,现在改成调用http://MICROSERVICE-PROVIDER/provider。
之后,再启动microservice-consumer。刷新http://localhost:8761,可以看到,microservice-consumer也注册到Eureka Server上了。
浏览器输入http://localhost:9000/consumer,调用成功。
上面讲了通过Eureka,搭建微服务并且进行服务治理的过程。先搭建了一个Eureka Server,然后再创建两个Eureka Client,一个作为服务消费者,另一个作为服务提供者。
服务提供者先去Eureka Server上面注册自己的服务
服务消费者去Eureka Server上获取服务,然后进行消费。
参考资料:
1.《Spring Cloud与Docker微服务架构实战》 周立 著
2.《Spring Cloud微服务实战》 翟永超 著