基于Eureka的Spring Cloud微服务治理框架
框架调用关系说明:
服务生产者启动时,向服务注册中心注册自己提供的服务
服务消费者启动时,在服务注册中心订阅自己所需要的服务
注册中心返回服务提供者的地址信息个消费者
消费者从提供者中调用服务
1. 服务注册与发现
1.1 Eureka简介
微服务之间一般需要相互调用,如果使用硬编码或者配置式,会存在一些问题:
- 适用场景有限:如果网络地址变更,则需要修改配置并重新发布。
- 无法动态伸缩:生产环境中,每个微服务一般都会部署多个实例,从而实现容灾和负载均衡。在微服务架构中,还可能需要动态增减节点。硬编码或者配置都无法实现这种需求。
服务发现组件具备以下功能:
- 服务注册表:记录各个微服务的信息。
- 服务注册与发现:服务注册是指微服务启动时,讲自己的信息注册到服务发现组件的过程;服务发现是指查询可用微服务列表及其网络地址的机制。
- 服务检查:服务发现组件使用一定机制定时检测已注册的服务,如发现某实例长时间无法访问,就会从服务注册中移除该实例。
Eureka是Spring Cloud Netflix微服务套件中的一部分,可以与Spring Boot构建的微服务很容易的整合起来。
Eureka包含了服务器端和客户端组件。服务器端,也被称作是服务注册中心,用于提供服务的注册与发现。Eureka支持高可用的配置,当集群中有分片出现故障时,Eureka就会转入自动保护模式,它允许分片故障期间继续提供服务的发现和注册,当故障分片恢复正常时,集群中其他分片会把他们的状态再次同步回来。
客户端组件包含服务消费者与服务生产者。在应用程序运行时,Eureka客户端向注册中心注册自身提供的服务并周期性的发送心跳来更新它的服务租约。同时也可以从服务端查询当前注册的服务信息并把他们缓存到本地并周期性的刷新服务状态。
本文以Spring Boot 2.1.0版本为例,兼容的Spring Cloud为Greenwich版本。具体兼容关系如下:
Spring Cloud | Spring Boot |
---|---|
Greenwich | 兼容Spring Boot 2.1.x |
Finchley | 兼容Spring Boot 2.0.x,不兼容Spring Boot 1.5.x |
Dalston和Edgware | 兼容Spring Boot 1.5.x,不兼容Spring Boot 2.0.x |
Camden | 兼容Spring Boot 1.4.x,也兼容Spring Boot 1.5.x |
Brixton | 兼容Spring Boot 1.3.x,也兼容Spring Boot 1.4.x |
Angel | 兼容Spring Boot 1.2.x |
1.2 使用Eureka进行服务治理
- 搭建服务注册中心
在Spring Boot工程中添加如下依赖:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.M2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
在Spring Boot工程的main入口,添加@EnableEurekaServer注解,开启服务注册中心:
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@RestController
@EnableEurekaServer
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
在默认情况下,服务注册中心也会把自己当做是一个服务,将自己注册进服务注册中心,所以我们可以通过配置来禁用他的客户端注册行为,在application.yml中添加如下配置:
server:
port: 8080
eureka:
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://localhost:8080/eureka
启动应用,并访问http://localhost:8080/即可看到Eureka信息面板。在"Instances currently registered with Eureka"信息中,没有一个实例,说明目前还没有服务注册。
- 注册服务
在另一个Spring Boot客户端工程中的pom文件中添加Eureka客户端相关的依赖:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</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>
在主类上添加@EnableDiscoveryClient注解以实现Eureka中的DiscoveryClient实现
@EnableDiscoveryClient
@SpringBootApplication
@RestController
public class SpringCloudEurekaProviderApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudEurekaProviderApplication.class, args);
}
@GetMapping("/hello")
public String hello(){
return "hello";
}
}
最后在配置文件application.properties中配置与服务相关的一些基本信息,如服务名、注册中心地址(即上一节中设置的注册中心地址http://localhost:8080/eureka)
spring.application.name=service-provider
server.port=8081
eureka.client.service-url.defaultZone=http://localhost:8080/eureka/
eureka.instance.lease-renewal-interval-in-seconds=5
eureka.instance.leaseExpirationDurationInSeconds=10
-
测试
1.启动注册中心服务
2.启动客户端工程,可以看到如下信息,说明此服务已经注册在了注册中心:2018-12-07 16:45:14.620 INFO 14984 --- [ main] com.netflix.discovery.DiscoveryClient : Discovery Client initialized at timestamp 1544172314617 with initial instances count: 0 2018-12-07 16:45:16.668 INFO 14984 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient : DiscoveryClient_SERVICE-PROVIDER/windows10.microdone.cn:service-provider:8081: registering service... 2018-12-07 16:45:16.979 INFO 14984 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient : DiscoveryClient_SERVICE-PROVIDER/windows10.microdone.cn:service-provider:8081 - registration status: 204
2. 服务提供与调用
本案例中有3个角色:服务注册中心、服务提供者、服务消费者,其中服务注册中心就是上一节的eureka单机版启动既可,流程是首先启动注册中心,服务提供者生产者服务并注册到服务中心中,消费者从服务中心中获取服务并执行。
2.1 服务提供
我们假定服务提供者有一个hello方法,可以提供输出“hello"的服务。
-
pom包配置
创建一个springboot项目,pom.xml中添加如下配置:
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Greenwich.M1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
-
配置文件
application.properties配置如下:
spring.application.name=service-provider server.port=8081 eureka.client.service-url.defaultZone=http://localhost:8080/eureka/ eureka.instance.lease-renewal-interval-in-seconds=5 eureka.instance.leaseExpirationDurationInSeconds=10
其中server.port指生产者服务的端口,eureka.client.service-url.defaultZone配置为上一节中服务注册中心配置的同名参数即可。
-
启动类和controller方法
启动类上添加@EnableDiscoveryClient注解
@EnableDiscoveryClient
@SpringBootApplication
@RestController
public class SpringCloudEurekaProviderApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudEurekaProviderApplication.class, args);
}
@GetMapping("/hello")
public String hello(){
return "hello";
}
}
添加@EnableDiscoveryClient注解后,项目就具有了服务注册的功能。启动工程后,就可以在注册中心的页面看到SPRING-CLOUD-PRODUCER服务。
到此服务提供者配置就完成了。
2.2 服务调用
-
pom包配置
和服务提供者一致
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Greenwich.M1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
-
配置文件
application.properties配置如下:spring.application.name=service-consumer server.port=8082 eureka.client.service-url.defaultZone=http://localhost:8080/eureka/ eureka.client.register-with-eureka=false eureka.client.registry-fetch-interval-seconds=5
-
启动类和controller方法
启动类添加@EnableDiscoveryClient注解。
@EnableDiscoveryClient
@SpringBootApplication
@RestController
public class SpringCloudEurekaConsumerApplication {
private static final Logger log = LoggerFactory.getLogger(SpringCloudEurekaConsumerApplication.class);
@Autowired
RestTemplate restTemplate;
@Bean
@LoadBalanced
RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(SpringCloudEurekaConsumerApplication.class, args);
}
@GetMapping("sayHi")
public String sayHi(){
final String ret = restTemplate.getForEntity("http://service-provider/hello", String.class).getBody();
log.info("服务提供方返回结果:"+ ret);
return ret;
}
}
到此,最简单的一个服务注册与调用的例子就完成了。
2.3 测试
依次启动服务注册中心、服务提供者、服务消费者三个项目
先输入:http://localhost:8081/hello 检查生产者服务是否正常
返回:hello
说明生产者正常启动,提供的服务也正常。
浏览器中输入:http://localhost:8082/sayHi
返回:hello
说明消费者已经成功的调用了远程生产者的服务hello,并且将结果返回到了浏览器。
网友评论