Eureka,古希腊词语,意思为找到了、我发现了,在微服务架构中,它主要是作为注册中心,实现服务治理功能。Eureka 就像是个平台,例如滴滴、家政服务这些。
Eureka 入门
创建 Eureka 注册中心
我们先来创建个Eureka Demo 工程,首先编写创建个聚合工程,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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.dane.springcloud</groupId>
<artifactId>springcloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springcloud</name>
<packaging>pom</packaging>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.RELEASE</spring-cloud.version>
</properties>
<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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
然后创建编写 Eureka 注册中心 Module:
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.dane.eureka</groupId>
<artifactId>eureka</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eureka</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>com.dane.springcloud</groupId>
<artifactId>springcloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
</project>
启动类加入注解 @EnableEurekaServer:
@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
配置文件,注意的是 eureka.client.register-with-eureka 要设置为false,不然启动把自己当作客户端向自己注册,会报错。
spring.application.name=eureka-server
server.port=8761
#是否注册自己到注册中心,默认是true
eureka.client.register-with-eureka=false
#由于注册中心的职责就是维护服务实例,它并不需要去检索服务,所以也设置为false
eureka.client.fetch-registry=false
接着启动程序访问http://localhost:8761/
编写服务提供者
新建 Module user-service,,然后加入相关依赖
<parent>
<groupId>com.dane.springcloud</groupId>
<artifactId>springcloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
启动类加入注解 @EnableDiscoveryClient:
@EnableDiscoveryClient
@SpringBootApplication
public class UserserviceApplication {
public static void main(String[] args) {
SpringApplication.run(UserserviceApplication.class, args);
}
}
加入配置:
spring.application.name=user-service
server.port=8081
eureka.client.service-url.defaultZone = http://localhost:8761/eureka
#采用ip注册
eureka.instance.prefer-ip-address=true
# 定义实例ID格式
eureka.instance.instance-id=${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}
编写UserController
@RestController
@RequestMapping("/user")
public class UserController {
@GetMapping("/hello")
public String hello(){
return "hello";
}
}
启动程序可以看到:
image.png
编写服务消费者
新建 Module consume,pom 配置、启动类注解和 Module userservice 一样,不过配置文件就不一样:
spring.application.name=consume
server.port=8082
配置 RestTemplate,RestTemplate 提供了多种便捷访问远程 Http 服务的方法:
@Configuration
public class RestConfig {
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
然后是 Controller ,这里路径是写服务的名词,也就是application.name:
@RestController
public class ConsumeController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("/callhello")
public String callHello(){
List<ServiceInstance> instances = discoveryClient.getInstances("user-service");
ServiceInstance instance = instances.get(0);
String url = "http://"+instance.getHost()+":"+instance.getPort()+"/user/hello";
System.out.println(url);
return restTemplate.getForObject(url,String.class);
}
}
这样就可以访问到了
image.png
Eureka 高可用
上面的入门例子中,所有服务都通过 Eureka 去提供给调用者,当 Eureka 服务挂了是时候,整个系统就停止工作了,所以 Eureka 必须搭建集群来保证。
Eureka 集群只需要在配置中指定另外多个 Eureka 的地址就可以了,比如有 master 和 slaveone 两台机器,我们需要将 master 注册到 slaveone 上面,slaveone 也注册到 master 上面,我们可以通过开发工具这样模拟:
在 Eureka Module 创建 application-master.properties 和 application-slaveone.properties:
image.png
application-master.properties
server.port=8761
eureka.client.service-url.defaultZone = http://localhost:8762/eureka
application-slaveone.properties
server.port=8762
eureka.client.service-url.defaultZone = http://localhost:8761/eureka
application.properties
spring.application.name=eureka-server
spring.profiles.active=master
先启动程序,然后修改spring.profiles.active=master 为 spring.profiles.active=slaveone,然后添加多一个springboot:
image.png
image.png
接着启动,然后在服务提供者 userservice,它要向多个注册中心注册自己,只需要配置:
eureka.client.service-url.defaultZone = http://localhost:8761/eureka,http://localhost:8762/eureka
然后重新启动就可以了,可以在每个 Eureka 看到:
image.png
Eureka 开发过程中的配置
在实际开发过程中,我们可能会不停的重启服务,由于 Eureka 有自己的保护机制,故节点下线后,服务信息还有一直保存在 Eureka 中,我们可以通过一些配置方便我们使用,当然,只是在开发环境下使用,生产环境不推荐
Eureka 注册中心配置:
#关闭自我保护
eureka.server.enable-self-preservation=false
#设置清理时间间隔,默认是60s
eureka.server.eviction-interval-timer-in-ms=5000
服务提供者在注册中心注册后,或保持一个心跳,告诉注册中心“我还活着”,这个行为叫做续约,有一个心跳间隔和超时时间,为了方便开发,我们也可以调整:
#默认90秒
eureka.instance.lease-expiration-duration-in-seconds= 5
#默认30秒
eureka.instance.lease-renewal-interval-in-seconds= 5
消费者也是定期的拉取服务列表,我们也可以修改方便开发:
#默认30秒
eureka.client.registry-fetch-interval-seconds= 5
以上所有方便开发的,都不要在生成环境修改。
Eureka 服务上下线监控
可能有特定需求需要知道服务上下线,可以进行监控,注意的是,集群环境下,要注意多触发情况。
@Component
public class EurekaStateChangeListener {
@EventListener
public void listen(EurekaRegistryAvailableEvent event){
System.out.println("注册中心启动");
}
@EventListener
public void listen(EurekaServerStartedEvent event){
System.out.println("EurekaServer 启动");
}
@EventListener
public void listen(EurekaInstanceCanceledEvent event){
System.out.println(event.getServerId()+"\t"+event.getAppName()+"服务下线");
}
@EventListener
public void listen(EurekaInstanceRegisteredEvent event){
System.out.println(event.getInstanceInfo().getAppName()+"服务注册");
}
@EventListener
public void listen(EurekaInstanceRenewedEvent event){
System.out.println(event.getServerId()+"\t"+event.getAppName()+"服务进行续约");
}
}
网友评论