Spring Cloud 为构建微服务分布式系统中提供很多的工具,本示例以服务的注册和发现为例来演示使用Eureka来完成。

一、版本与工具

版本:

  1. Spring Boot 2.0.2.RELEASE
  2. Spring Cloud Finchley.RC2
  3. JDK 1.8

工具:

  1. Maven
  2. Eclipse

二、项目结构

为了统一版本,采用一个项目多个模块的方式,创建一个 spring-cloud-eureka-hello-demo 项目,在其中创建 spring-cloud-eureka-serverspring-cloud-service-consumerspring-cloud-service-provider 三个模块 :

三、Eureka Server

在Eureka Server模块,首先需要引入 spring-cloud-starter-netflix-eureka-server 依赖,然后添加 @EnableEurekaClient 注解,最后在配置相关设置。

pom.xml

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
<?xml version="1.0"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.devnp</groupId>
<artifactId>spring-cloud-eureka-hello-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>spring-cloud-service-consumer</artifactId>

<name>spring-cloud-service-consumer</name>
<url>http://maven.apache.org</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>

</project>

application.yaml 配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server:
port: 8761

spring:
application:
name: spring-cloud-eureka-server


eureka:
instance:
hostname: localhost
client:
register-with-eureka: false
fetch-registry: false

添加注解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.devnp.springcloudeurekaserver;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

/**
* @author duliu
*
*/
@SpringBootApplication
@EnableEurekaServer
public class SpringCloudEurekaServerApplication {

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

四、服务提供者

在服务提供者这个模块在代码上和普通的提高RESTful API并没有多大的特别,只需要添加Eureka Client相关依赖和配置即可。

application.yaml 配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server:
port: 8001

spring:
application:
name: spring-cloud-service-provider

eureka:
instance:
hostname: localhost
instanceId: ${spring.application.name}:${spring.application.instance_id:${server.port}}
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/

RESTful API 接口 ProviderController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.devnp.springcloudserviceprovider.web;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
* @author duliu
*
*/
@RestController
public class ProviderController {

@GetMapping("/hello")
public Object hello() {
return "Hello Wolrd!" ;
}
}

五、服务消费者

服务者也是作为 Eureka Client, 所以在都需要添加相关的依赖和配置。

在请求和一般直接请求目标的URL有不同之处,这时候需要请求 服务提供者名称/api 这样即使提供者的IP或者域名发生变化,在消费端也不需要做任何修改。

ConsumerContoller.java

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
package com.devnp.springcloudserviceconsumer.web;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

/**
* @author duliu
*
*/
@RestController
public class ConsumerContoller {

@Autowired
private RestTemplate restTemplate;

@GetMapping("/hello")
public Object hello() {
String reponse = restTemplate.getForObject("http://spring-cloud-service-provider/hello", String.class, CollectionUtils.EMPTY_COLLECTION);

return reponse ;
}
}

RestTemplate 是需要手动去完成配置:

SpringCloudServiceConsumerApplication.java

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
28
29
30
31
32
33
34
35
36
37
38
39
40
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

/**
* @author duliu
*
*/
@SpringBootApplication
@EnableEurekaClient
public class SpringCloudServiceConsumerApplication {

@Bean
@LoadBalanced
public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
return new RestTemplate(factory);
}

@Bean
public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setReadTimeout(5000);// ms
factory.setConnectTimeout(15000);// ms
return factory;
}

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
SpringApplication.run(SpringCloudServiceConsumerApplication.class, args);
}

}

六、测试

先启动Eureka Server,然后启动服务提供者和消费者,访问http://localhost:8761/

发现服务已经完成注册,这时来进去访问API http://localhost:8002/hello

代码

spring-cloud-eureka-hello-demo.zip

https://github.com/duliu1990/spring-cloud-demo