1. 搭建一个 eureka 服务发现服务器

1.1. eureka-server-demo

新建 module,使用 spring boot 快速开发

1.2. POM

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
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring-cloud-demo</artifactId>
<groupId>io.github.hiant</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>eureka-server-demo</artifactId>
<packaging>jar</packaging>
<name>eureka-server-demo</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-eureka-server</artifactId>
</dependency>
</dependencies>
</project>

spring-cloud-starter-eureka-server 用来提供基于 eureka 的服务发现服务器所需依赖

1.3. 源码

class 描述
EurekaServerDemoApplication 服务器启动入口

1.3.1. EurekaServerDemoApplication

1
2
3
4
5
6
7
8
@SpringBootApplication
@EnableEurekaServer // 注解方式,在spring boot中启动服务发现服务器,具体配置,通过spring boot方式注入进去
public class EurekaServerDemoApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerDemoApplication.class, args);
}
}

1.4. 配置

文件名 描述
application.properties 也可以使用yml。这里面有个坑,map类型的键值,键没法再像其他前缀已经通过短横线表示驼峰变量名
1
2
3
4
5
6
7
8
9
10
11
12
# 服务器端口号,不修改 eureka.client.service-url.defaultZone ,这里的端口号必须是 8671
server.port=8765
# eureka 服务器实例绑定的机器地址
eureka.instance.hostname=localhost
# 注册到 eureka 服务器的是 ip 还是 hostname
eureka.instance.prefer-ip-address=true
# eureka 服务器的地址,服务提供方需要使用该地址注册服务
eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
# 是否注册自身到 eureka 服务器,这里仅是一个注册服务器,因此设为false
eureka.client.register-with-eureka=false
# 是否从 eureka 服务器获取注册信息
eureka.client.fetch-registry=false

1.5. 其他

1.5.1. 遗留问题

  1. 注册 eureka 服务选择用 ip 时,怎么设置 ip?不设置时,默认地址是什么?
  2. 如何设置 eureka 注册服务器为集群模式?

2. 注册一个服务

2.1. eureka-service-demo

简单的使用 java.util.UUID 做一个全局id生成服务

2.2. POM

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
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring-cloud-demo</artifactId>
<groupId>io.github.hiant</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>eureka-service-demo</artifactId>
<packaging>jar</packaging>
<name>eureka-service-demo</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-eureka</artifactId>
</dependency>
</dependencies>
</project>

spring-cloud-starter-eureka 用来提供 eureka 服务注册及 spring web 的依赖

2.3. 源码

class 描述
EurekaServiceDemoApplication 服务器启动入口
UUIDController UUID服务

2.3.1. EurekaServiceDemoApplication

1
2
3
4
5
6
7
8
@SpringBootApplication
@EnableEurekaClient // 注解方式,在spring boot中注册服务
public class EurekaServiceDemoApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServiceDemoApplication.class, args);
}
}

2.3.2. UUIDController

一个简单的 restful 服务,当访问 http://ip:port/uuid 时返回一个 java.util.UUID 生成的随机 id

1
2
3
4
5
6
7
8
@RestController
public class UUIDController {
@GetMapping("/uuid")
public String uuid() {
return UUID.randomUUID().toString();
}
}

2.4. 配置

文件名 描述
application.properties spring boot 配置文件
1
2
3
4
5
6
# 服务名字
spring.application.name=UUID
# 服务端口,spring cloud 使用 restful 方式调用服务
server.port=8081
# 注册服务器地址
eureka.client.service-url.defaultZone=http://localhost:8765/eureka/

2.5. 其他

2.5.1. 遗留问题

3. 通过服务注册器发现服务并访问

3.1. eureka-client-demo

3.2. POM

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
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring-cloud-demo</artifactId>
<groupId>io.github.hiant</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>eureka-client-demo</artifactId>
<packaging>jar</packaging>
<name>eureka-client-demo</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-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>com.netflix.eureka</groupId>
<artifactId>eureka-core</artifactId>
</dependency>
<dependency>
<groupId>com.netflix.ribbon</groupId>
<artifactId>ribbon-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
</dependencies>
</project>

spring-cloud-netflix-eureka-client、eureka-core、ribbon-eureka 用来提供 eureka 服务发现的依赖

spring-cloud-starter-feign 用来提供 eureka 服务调用的依赖

3.3. 源码

class 描述
EurekaClientDemoApplication 客户端启动入口

3.3.1. EurekaClientDemoApplication

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class EurekaClientDemoApplication {
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(EurekaClientDemoApplication.class, args);
Service service = context.getBean(Service.class);
System.out.println(service.uuid());
}
@FeignClient("UUID")
interface Service {
@GetMapping("/uuid")
String uuid();
}
}

FeignClient 包装了服务名,Service 里面的 uuid 方法通过注解包装了 eureka-service-demo 工程提供的 rest api

3.4. 配置

文件名 描述
application.properties spring boot 配置文件
1
2
3
4
# 注册服务器地址
eureka.client.service-url.defaultZone=http://localhost:8765/eureka/
# 是否注册自身到 eureka 服务器,这里仅是调用者,因此设为false
eureka.client.register-with-eureka=false

3.5. 其他

3.5.1. 遗留问题

  1. FeignClient 包装带来的耦合度影响

    通过 FeignClient 的包装,客户端调用远端服务,其实和本地调用一个方法已经一样了,这和 dubbo 声明一个接口,然后服务端实现该接口,客户端调用该接口是一样的,这样从另外个方面来说也是增加了耦合度了。

  2. Feign的HTTP Client

    Feign在默认情况下使用的是JDK原生的URLConnection发送HTTP请求,没有连接池,但是对每个地址会保持一个长连接,即利用HTTP的persistence connection 。我们可以用Apache的HTTP Client替换Feign原始的http client, 从而获取连接池、超时时间等与性能息息相关的控制能力。

  3. Feign的扩展属性设置

    http://cloud.spring.io/spring-cloud-static/spring-cloud.html#spring-cloud-feign

    #Hystrix支持,如果为true,hystrix库必须在classpath中
    feign.hystrix.enabled=false
    #请求和响应GZIP压缩支持
    feign.compression.request.enabled=true
    feign.compression.response.enabled=true
    #支持压缩的mime types
    feign.compression.request.enabled=true
    feign.compression.request.mime-types=text/xml,application/xml,application/json
    feign.compression.request.min-request-size=2048

4. 验证

  1. 启动 io.github.hiant.EurekaServiceDemoApplication

    http://localhost:8765/

  2. 启动 io.github.hiant.EurekaServiceDemoApplication

    http://localhost:8765/ 会显示注册的 UUID 服务

  3. 启动 io.github.hiant.EurekaClientDemoApplication

    会在控制台输出获取到的 uuid