Eureka服务注册与发现

Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。Spring Cloud将它集成在其他子项目spring-cloud-netflix中,以实现spring cloud服务发现功能。

注册中心

注册中心地址

1
http://admin:pwd123@node1.test.com:8001/eureka/,http://admin:pwd123@node1.test.com:8002/eureka/,http://admin:pwd123@node3.test.com:8003/eureka/

服务注册

工程结构

1
2
3
4
5
6
7
8
9
10
11
12
13
eureka-provider
├── pom.xml
├── src
│   └── main
│   ├── java
│   │   └── com
│   │   └── cloud
│   │   └── provider
│   │   ├── Application.java
│   │   └── www
│   │   └── SimpleController.java
│   └── resources
│   └── application.properties

Maven配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<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>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

主类示例

  • @EnableDiscoveryClient开始实例自动发现并注册到注册中心
1
2
3
4
5
6
7
8
9
@EnableDiscoveryClient
@SpringBootApplication
public class Application {

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}

}

配置示例

1
2
3
4
5
6
spring.application.name=server-provider

server.port=7001
spring.http.encoding.charset=utf-8

eureka.client.service-url.defaultZone=http://admin:pwd123@node1.test.com:8001/eureka/,http://admin:pwd123@node1.test.com:8002/eureka/,http://admin:pwd123@node3.test.com:8003/eureka/

服务接口

1
2
3
4
5
6
7
8
9
10
11
12
@RestController
@RequestMapping(value="/api")
public class SimpleController {

private final Logger logger = LoggerFactory.getLogger(Application.class);

@GetMapping(value="/select/{id}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public ResponseEntity getUserEntry(@PathVariable("id") long id) {
return ResponseEntity.ok("测试数据:" + id);
}

}

服务启动

1
2
[root@localhost target ]$ java -jar eureka-provider-1.0-SNAPSHOT.jar --server.port=7001 &
[root@localhost target ]$ java -jar eureka-provider-1.0-SNAPSHOT.jar --server.port=7002 &

注册查看

访问注册中心:http://admin:pwd123@node1.test.com:8001

服务消费(Ribbon)

工程结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
eureka-consumer-ribbon
├── eureka-consumer-ribbon.iml
├── pom.xml
├── src
│   └── main
│   ├── java
│   │   └── com
│   │   └── cloud
│   │   └── consumer
│   │   └── ribbon
│   │   ├── Application.java
│   │   └── www
│   │   └── RibbonController.java
│   └── resources
│   └── application.properties

Maven依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

消费示例

主类示例

@EnableDiscoveryClient注解让改应用注册为Eureka客户端应用,在主类中创建RestTemplate的实例,并通过@LoadBalanced开启客户端负载均衡.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@EnableDiscoveryClient
@SpringBootApplication
public class Application {

@Bean
@LoadBalanced
RestTemplate getRestTemplate() {
return new RestTemplate();
}

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Api服务

这里访问的PROVIDER.TEST.SIMPLESERVER是服务提供方的服务名(服务名不区分大小写)

1
2
3
4
5
6
7
8
9
10
11
12
@RestController
@RequestMapping(value="/api/invoke")
public class RibbonController {

@Autowired
RestTemplate restTemplate;

@GetMapping(value="/select/{id}")
public String remoteInvoke(@PathVariable long id) {
return restTemplate.getForObject("http://SERVER-PROVIDER/api/select/{0}", String.class, id);
}
}

配置示例

1
2
3
4
5
6
7
8
9
10
server.port=8080
spring.application.name=consumer-ribbon

# 心跳时间,即服务续约间隔时间(缺省为30s)
eureka.instance.lease-renewal-interval-in-seconds=5
# 发呆时间,即服务续约到期时间(缺省为90s)
eureka.instance.lease-expiration-duration-in-seconds=10

### 应用注册信息
eureka.client.service-url.defaultZone=http://admin:pwd123@node1.test.com:8001/eureka/,http://admin:pwd123@node1.test.com:8002/eureka/,http://admin:pwd123@node3.test.com:8003/eureka/

启动访问

注册中心面板

访问请求查看
1
2
[root@localhost target ]$ curl -XGET http://172.30.12.197:8080/api/invoke/select/7
测试数据7

服务消费(Feign)

工程结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
eureka-consumer-feign
├── pom.xml
├── src
│   └── main
│   ├── java
│   │   └── com
│   │   └── cloud
│   │   └── consumer
│   │   └── feign
│   │   ├── Application.java
│   │   ├── service
│   │   │   └── SimpleFeignService.java
│   │   └── www
│   │   └── FeignController.java
│   └── resources
│   └── application.properties

Maven依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<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>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

消费示例

主类示例

@EnableDiscoveryClient注解让改应用注册为Eureka客户端应用,@EnableFeignClients开启Spring Cloud Feign支持

1
2
3
4
5
6
7
8
9
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class Application {

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
接口调用

定义调用接口,通过@FeignClient注解指定服务名来绑定服务,这里配置的SERVER-PROVIDER是服务提供方的服务名(服务名不区分大小写)

1
2
3
4
5
6
@FeignClient(name="SERVER-PROVIDER")
public interface SimpleFeignService {

@GetMapping(value="/api/select/{id}")
String getUserEntry(@PathVariable("id") long id);
}
Api服务
1
2
3
4
5
6
7
8
9
10
11
12
@RestController
@RequestMapping(value="/api/invoke")
public class FeignController {

@Autowired
private SimpleFeignService simpleFeignService;

@GetMapping(value="/select/{id}")
public String remoteInvoke(@PathVariable long id) {
return simpleFeignService.getUserEntry(id);
}
}

配置示例

1
2
3
4
5
6
7
8
9
10
server.port=9090
spring.application.name=consumer-feign

# 心跳时间,即服务续约间隔时间(缺省为30s)
eureka.instance.lease-renewal-interval-in-seconds=5
# 发呆时间,即服务续约到期时间(缺省为90s)
eureka.instance.lease-expiration-duration-in-seconds=10

### 应用注册信息
eureka.client.service-url.defaultZone=http://admin:pwd123@node1.test.com:8001/eureka/,http://admin:pwd123@node1.test.com:8002/eureka/,http://admin:pwd123@node3.test.com:8003/eureka/

启动访问

注册中心面板

访问请求查看
1
2
[root@localhost target ]$ curl -XGET http://172.30.12.197:9090/api/invoke/select/5
测试数据5