1、概述

微服务框架中最为核心和基础的模块就是服务治理,它主要用来实现各个微服务实例的自动化注册与发现。在这个体系结构中有一个“中心点”——服务注册中心,每个服务必须注册到服务注册中心。而各个服务之间进行通讯并不需要知道具体服务的主机名和端口。这种实现的一个缺点是所有客户机必须实现某种逻辑来与这个中心点进行交互,这样在实现服务请求之前将增加一次额外的网络往返。

Spring Cloud 使用 Netflix Eureka 来实现服务注册与发现,它既包含了服务端组件,也包含了客户端组件。Eureka服务端也称为服务注册中心,支持高可用配置。它依托强一致性提供良好的服务实例可用性。Eureka客户端可以同时充当服务器,将其状态复制到一个连接的对等点上。换句话说,客户机检索服务注册中心所有连接的节点的列表,并通过负载平衡算法向所有其他服务发出请求。每个客户机为了声明自己的存活状态,他们必须向注册中心发送一个心跳信号。

在本例中为了体现服务治理功能,实现了三个微服务:

  • 一个服务注册中心 (Eureka Server)
  • 一个在注册中心注册的REST服务(Eureka Client)
  • 一个Web应用程序,服务的消费者(Spring Cloud Netflix Feign Client)

2、注册中心

使用Spring Cloud Netflix Eureka实现一个注册中心非常简单。在pom里增加spring-cloud-starter-eureka-server依赖,在启动类里添加@EnableEurekaServer注解。

首先创建一个Maven工程,并添加一些依赖关系

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.10.RELEASE</version>
    <relativePath />
</parent>       
<dependencies>
    <dependency>
    <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka-server</artifactId>
    </dependency>
</dependencies>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-parent</artifactId>
            <version>Edgware.SR2</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

然后创建一个启动类

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

在application.yml中加入配置信息

server:
  port: 8888 #服务注册中心端口号

eureka:
  instance:
    hostname: localhost #服务注册中心实例的主机名
  client:
    registerWithEureka: false #是否向服务注册中心注册自己
    fetchRegistry: false #是否检索服务
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

现在通过浏览器访问http://localhost:8888 可以看到Eureka的控制台,在那里能看到将来注册后的服务实例和一些状态和健康指标。
1.png

3、服务提供者

首先我们添加一些依赖关系

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

然后实现主应用类

@SpringBootApplication
@EnableEurekaClient
@RestController
public class EurekaClientApplication implements GreetingController {
    @Autowired
    @Lazy
    private EurekaClient eurekaClient;

    @Value("${spring.application.name}")
    private String appName;

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

    public String greeting() {
        return String.format("Hello from '%s'!", eurekaClient.getApplication(appName).getName());
    }

}

在application.yml文件里添加配置

spring:
  application:
    name: spring-cloud-eureka-client

server:
  port: 0

eureka:
  client:
    serviceUrl:
      defaultZone: ${EUREKA_URI:http://localhost:8888/eureka}
  instance:
    preferIpAddress: true

我们让Spring Boot为我们选择一个随机端口,因为后面是使用名称来访问这个服务。现在重新访问Eureka控制台可以看到新注册的这个服务。
2.png

4、服务消费者

最后我们实现第三个微服务,使用Spring Netflix Feign Client实现的REST消费Web应用。

在Feign Client工程的pom.xml文件里添加一些依赖

<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>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

定义Feign Client 接口,引入要调用的服务名称

@FeignClient("spring-cloud-eureka-client")
public interface GreetingClient{
    @RequestMapping("/greeting")
    String greeting();
}

定义主服务类,是一个controller控制器

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@Controller
public class FeignClientApplication {
    @Autowired
    private GreetingClient greetingClient;

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

    @RequestMapping("/get-greeting")
    public String greeting(Model model) {
        model.addAttribute("greeting", greetingClient.greeting());
        return "greeting-view";
    }
}

下面是HML模板可进行页面展现

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
    <head>
        <title>Greeting Page</title>
    </head>
    <body>
        <h2 th:text="${greeting}"></h2>
    </body>
</html>

配置文件内容

spring:
  application:
    name: spring-cloud-eureka-feign-client

server:
  port: 8080

eureka:
  client:
    serviceUrl:
      defaultZone: ${EUREKA_URI:http://localhost:8888/eureka}

启动运行这个服务,在浏览器里访问 http://localhost:8080/get-greeting 就会看到

Hello from 'SPRING-CLOUD-EUREKA-CLIENT'!

5、结论

我们现在可以使用Spring Cloud Netflix Eureka Server实现服务注册中心,并注册一些Eureka Clients。在创建服务提供者的时候没有指定端口,这样服务将监听一个随机选择的端口。使用Feign Client通过服务名可以定位和消费这个REST服务,甚至在位置发生变化时也可以。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐