目录
服务治理
服务治理是微服务架构中非常重要的模块,主要用来实现服务的自动注册与发现。在最初构建微服务系统的时候服务可能并不多,可以通过简单的静态配置来维护服务间的相互调用,但是当系统功能越来越复杂,微应用也不断增加,静态配置已经不能起到很好的作用,服务间的调用关系越来越难以理清,并且集群规模,服务位置,服务命名等都可能发生变化。而服务治理就是专门为解决这些问题而产生的。
服务注册:在服务治理模块中,通常会有一个注册中心,每个服务都会向注册中心提供自己的主机地址,版本号,通信协议等信息,注册中心按照服务名来组织服务清单。例如如果有两个提供服务A的进程运行在192.168.0.1:9000和192.168.0.2:9001上,还有两个提供服务B的进程运行在192.168.3.2:9000和192.168.0.4:9001上,那么注册中心就会维护一个类似以下的服务清单。并且注册中心还会一直监测清单中的服务是否可用,若不可用就需要从服务清单中剔除。
服务名 | 位置 |
服务A | 192.168.0.1:9000,192.168.0.2:9001 |
服务B | 192.168.3.2:9000,192.168.0.4:9001 |
服务发现:当服务调用方想从服务提供方获取服务时,它不能通过接口直接调用服务方的服务,因为它不知道服务提供方的具体位置,因此服务调用方需要通过服务注册中心,获取服务清单。如上,如果服务C想调用服务A,C需要向注册中心发起请求获取服务A的可用位置192.168.0.1:9000,192.168.0.2:9001,然后服务C通过某种负载均衡策略来进行服务调用。
Netflix Eureka
Spring Cloud Eureka,使用Netflix Eureka来实现服务注册与发现,它既包含了服务端组件也包含客户端组件,并且服务端和客户端都是采用java编写。
Eureka服务端:我们也称为服务注册中心。支持高可用配置。如果Eureka以集群模式部署,当集群中有分片出现故障时,那么Eureka就转入自我保护模式。它允许在分片故障期间继续提供服务的发现和注册,当故障分片恢复运行时,集群中的其他分片会把状态同步给故障恢复的分片。
Eureka客户端:主要是服务的注册与发现。客户端向注册中心注册自身所提供的服务信息,并周期性发送心跳。同时也能从服务端查询当前注册的服务信息,并把它们缓存到本地并周期性的刷新服务信息。
搭建服务注册中心(单机模式)
- 1.引入依赖
!--设置springcloud版本-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!--服务治理-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
- 2.使用@EnableEurekaServer
通过@EnableEurekaServer注解启动一个注册中心,只需在一个普通的Spring Boot应用中添加这个注解就能开启此功能。
@EnableEurekaServer
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
在默认设置下,该服务注册中心也会将自己注册为客户端,所以需要设置禁用这种行为,可以在application.properties中增加如下配置:
#Eureka-Server配置
eureka.instance.hostname=server1
#注册中心维护服务实例,设置为false不需要检索服务
eureka.client.fetch-registry=false
#注册中心不需要注册自己设置为false
eureka.client.register-with-eureka=false
server.port=8089
#高可用时,此时不能使用localhost,此处server2需要在host文件中设置
eureka.client.serviceUrl.defaultZone=http://server1:8090/eureka/
完成上面的配置后,启动应用并访问 http://localhost:8089/。可以看到如下所示页面。当前的 Instances currently registered with Eureka是空的,说明这个注册中心还没有注册任何服务。
注册服务提供者
- 1.引入依赖
<!--设置springcloud版本-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--服务治理-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
</dependencies>
- 2.编写一个服务方法
@RestController
public class TempController {
private final Logger logger = Logger.getLogger(getClass());
@Autowired
private DiscoveryClient client;
@RequestMapping("/get")
public String temp(){
ServiceInstance localServiceInstance = client.getLocalServiceInstance();
logger.info(localServiceInstance.getHost()+":"+localServiceInstance.getPort()+
":"+localServiceInstance.getServiceId());
return "hello world";
}
}
- 3.使用@EnableDiscoveryClient注解,激活Eureka中的DiscoveryClient实现,实现上面Controller的信息输出。
@EnableDiscoveryClient
@SpringBootApplication
//因为我的启动类没有放在根目录下面所以不能自动扫描组件,这里手动扫描一下
@ComponentScan(basePackages = {"com.example.controller"})
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
- 4.配置properties
spring.application.name=client
server.port = 1111
#指定服务注册地址
eureka.client.serviceUrl.defaultZone = http://localhost:8089/eureka/
- 5.启动服务
启动之后可以看到注册中心控制台输出以下信息,表示该服务注册成功。
刷新注册中心页面,可以看到该服务的注册信息:
通过访问http://localhost:1111/get直接向该服务发起请求,在控制台可以看到如下输出:
这些输出内容就是之前在Controller中注入的DiscoveryClient对象从服务注册中心获取的服务相关信息。