原文链接: How to Develop Microservices With Spring Cloud and Netflix Discovery (翻译:钟涛)
今天,我将为大家展示如何使用Eureka发现服务器(discovery server)来搭建一个小型的微服务应用。
我将使用Eureka作为发现服务器,各个应用可以通过Eureka来发现彼此,建立连接。
对于本例,总共将创建4个微服务应用程序。
发现服务器将扮演这样一个角色,所有的微服务应用程序将自己的信息注册到发现服务器,所有的微服务应用程序也可以访问这个发现服务器,以获得其他微服务应用程序的信息。当一个微服务应用程序想访问另一个微服务应用程序时,它不必提前获悉对方的主机地址和端口号,它都可以通过询问发现服务器来获得,这样的话,即使对方应用程序的地址发生了改变,也不会造成影响。
当一个应用程序从一台物理服务器迁移到另一台新的物理服务器时,我们可以从发现服务器知道新的主机地址和端口。假设您决定将应用程序从印度服务器( http://myservice.gov.in:9001 )迁移到美国服务器( http://myservice.gov.us:99013 ),您不需要通知之前使用您服务的任何应用程序。他们可以从发现服务器自动知道新的主机地址和端口号,甚至不需要做任何事情。
请参见下图以了解发现服务器是如何工作的,如何为注册的发现客户端提供服务。例如, read-service 需要使用 book-service 和 library-service 提供的服务,那么 read-service 如何获得对方的主机名和端口号呢?这些信息将由 discovery-service 提供,因为 book-service 和 library-service 已经将信息注册到了 discovery-service 中。
要了解更多关于Spring cloud Netflix的信息,您可以访问 https://cloud.spring.io/spring ... .html 。
下面,让我们一步一步地开发这个项目。
首先,我们将创建一个基于Eureka的 discovery-service 。如果您是Spring Boot的新手,可以阅读我的文章 https://github.com/prateekpara ... rest2 来创建一个Spring Boot应用程序。现在,请点击 https://start.spring.io/ 打开Spring Initializr。现在请按照下方截图操作。
单击 ADD DEPENDENCIES 按钮并选择需要的依赖项(在搜索栏中只需键入依赖项——Eureka和Actuator即可完成添加。不要选错了,不要选择Eureka client)
现在单击 GENERATE 按钮生成项目,并将其保存到您的机器上,作为maven项目导入到您的工具中(这里我使用的是Eclipse)。
现在,打开 DemoDiscoveryServerApplication.java ,并添加 @EnableEurekaServer
:
```java
package com.bhaiti.jorhat.demodiscoveryserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@EnableEurekaServer
public class DemoDiscoveryServerApplication {
public static void main(String[] args) {
SpringApplication.run(DemoDiscoveryServerApplication.class, args);
}
}
```
将 application.properties 重命名为 application.yml ,并添加如下信息:
yaml server.port: 9001 spring.application.name: demo-discovery-server eureka: server: evictionIntervalTimerInMs: 3000 response-cache-update-interval-ms: 3000 client: registerWithEureka: false fetchRegistry: false service-url.defaultZone: http://localhost:${server.port}/eureka
从上面的配置信息中,可以看到, registerWithEureka 和 fetchRegistry 的值都是 false 。原因是我们不希望注册这个应用程序本身,因为此应用程序将作为发现服务器,接收其他应用程序的注册。有关配置的详细信息,请参考 repository 。
您的发现服务器已经准备好了。
在项目主目录中,执行以下命令编译应用程序:
mvn clean package
启动应用程序:
java -jar target/demo-discovery-server-0.0.1-SNAPSHOT.jar
现在您可以通过仪表板来查看Eureka发现服务器,请点击 http://localhost:9001
现在你还看不到任何Eureka客户端应用程序。让我们开发我们的第一个Eureka客户端应用程序 book-service 。
按以下步骤创建一个REST应用程序 book-service
请注意,这次我们选择了 Eureka Client 作为依赖项 ,因为我们的REST应用程序也是Eureka客户端应用程序。生成项目并将其作为maven项目导入到eclipse中。
将 application.properties 重命名为 application.yml ,并添加如下配置:
yaml server.port: 9901 spring: application.name: book-service eureka: client: serviceUrl: defaultZone: http://localhost:9001/eureka/ registryFetchIntervalSeconds: 1 instance: leaseRenewalIntervalInSeconds: 1
通过配置项 defaultZone 可以看到,这个Eureka客户端应用程序将自己注册到 http://localhost:9001/eureka/ 这个地址。现在我们必须在REST应用程序 book-service 中进行一些编码。首先打开 BookServiceApplication.java 文件,并在其中添加 @EnableDiscoveryClient
以激活发现客户机。
```java
package com.bhaiti.jorhat.book.bookservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class BookServiceApplication {
public static void main(String[] args) {
SpringApplication.run(BookServiceApplication.class, args);
}
}
```
按如下所示,创建一个新的java类 BookService.java
并添加如下代码:
```java
package com.bhaiti.jorhat.book.bookservice;
import java.util.Arrays;
import java.util.List;
public class BookService {
private static List<String> bookList = Arrays.asList("Book1","Book2","Book3");
public static List<String> getBookList() {
return bookList;
}
}
```
同样的方法,创建 BookController.java
```java
package com.bhaiti.jorhat.book.bookservice;
import java.util.List;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class BookController {
@GetMapping("/books")
public ResponseEntity<List<String>> getBookList(){
return ResponseEntity.ok(BookService.getBookList());
}
}
```
在 pom.xml
中添加如下依赖项:
xml <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</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</artifactId> </dependency>
现在,我们可以编译并且运行它了:
shell cd book-service mvn clean package java -jar target/book-service-0.0.1-SNAPSHOT.jar
现在刷新Eureka(发现服务器)仪表板,您可以看到 book-service 已经被注册进来了。
现在创建 library-service 应用程序。只需重复步骤2,创建项目并将其导入到eclipse中。
参考 book-service 更新 library-service 的 pom .xml
。分别添加两个类 LibraryService.java 和 LibraryController.java
@EnableDiscoveryClient
java @SpringBootApplication @EnableDiscoveryClient public class LibraryServiceApplication { public static void main(String[] args) { SpringApplication.run(LibraryServiceApplication.class, args); } }
按如下方式创建 LibraryService.java
```java
package com.bhaiti.uk.global.repo;
import java.util.HashMap;
import java.util.Map;
public class LibraryService {
private static Map<String, String> libList;
static {
libList = new HashMap<String, String>();
libList.put("Book1", "Library3");
libList.put("Book2", "Library1");
libList.put("Book3", "Library2");
}
public static Map<String, String> getLibList() {
return libList;
}
}
```
按如下方式创建 LibraryController.java
```java
package com.bhaiti.uk.global.repo;
import java.util.Map;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class LibraryController {
@GetMapping("/librarys")
public ResponseEntity<Map<String, String>> getBookList(){
return ResponseEntity.ok(LibraryService.getLibList());
}
}
```
将 application.properties 重命名为 application.yml ,并添加如下配置:
yaml server.port: 9902 spring: application.name: library-service eureka: client: serviceUrl: defaultZone: http://localhost:9001/eureka/ registryFetchIntervalSeconds: 1 instance: leaseRenewalIntervalInSeconds: 1
编译并且运行应用程序:
shell cd library-service mvn clean package java -jar target/library-service-0.0.1-SNAPSHOT.jar
现在刷新Eureka(发现服务器)仪表板,您可以看到 library-service 已经被注册进来了。
现在我们将创建最后一个REST应用程序 - read-service 。创建并将其导入到eclipse中。请注意,我们在这里增加了一个依赖项,即OpenFeign。
将 application.properties 重命名为 application.yml ,并添加如下配置:
yaml server.port: 9903 spring: application.name: library-service eureka: client: serviceUrl: defaultZone: ${EUREKA_URI:http://localhost:9001/eureka} registryFetchIntervalSeconds: 1 instance: leaseRenewalIntervalInSeconds: 1
参照 library-service 修改 pom.xml
。
在 read-service 中,我们将同时使用 book-service 和 library-service .。为了调用 book-service 和 library-service 的REST API,我们将在这里实现一个假想客户机。
首先修改 ReadServiceApplication.java :
java @SpringBootApplication @EnableDiscoveryClient public class ReadServiceApplication {
现在,创建我们的Feign客户端。分别创建两个接口 BookClient.java 和 LibraryClient 。
```java
package com.bhaiti.jorhat.read;
import java.util.List;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
@FeignClient("book-service")
public interface BookClient {
@GetMapping("/books")
List<String> getBookList();
}
```
```java
package com.bhaiti.jorhat.read;
import java.util.Map;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
@FeignClient("library-service")
public interface LibraryClient {
@GetMapping("/librarys")
Map<String, String> getLibraryList();
}
```
使用FeignClient的好处是,当进行REST调用时,您不需要知道对方的主机名和端口号。在这里,我们没有使用URI来对 book-service 进行REST调用。Feign可以获取REST调用所需的一切,从 discovery server 获取关于 book-service 和 library-service 的一切信息(主机名和端口号)。因为 book-service 和 library-service 不仅是基于REST的应用程序,也是Eureka客户端应用程序,因此它可以从发现服务器中获取的其他Eureka客户端应用程序的信息。
要了解更多关于FeignClient的信息,请访问 https://cloud.spring.io/spring ... .html 和 https://cloud.spring.io/spring ... html/
假设您不想使用FeignClient,而想使用http连接或 RestTemplate
进行REST调用,在这种情况下,您可以使用以下代码获取应用程序的主机名和端口号。
```java
@Autowired
private EurekaClient eurekaClient;
public String getBaseUrl() {
Application application = eurekaClient.getApplication("book-service");
InstanceInfo instanceInfo = application.getInstances().get(0);
String hostname = instanceInfo.getHostName();
int port = instanceInfo.getPort();
return " http://" + hostname + ":" + port;
}
```
按如下方式创建 ReadServiceController.java
```java
package com.bhaiti.jorhat.read;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ReadServiceController {
@Autowired
BookClient bookClient;
@Autowired
LibraryClient libraryClient;
@GetMapping(path= "/read/{bookName}", produces = "application/json")
public ResponseEntity<String> getReadingLocation(@PathVariable(value = "bookName") String bookName){
String response;
List<String> bookList = bookClient.getBookList();
if(bookList.contains(bookName)) {
Map<String, String> libList = libraryClient.getLibraryList();
response = "You can read this book - " + bookName
+ " at this Library - " + libList.get(bookName);
} else {
response = "Your Book - " + bookName + " is not currently available in Libaries";
}
return ResponseEntity.ok().body(response);
}
}
```
最后,按如下方式修改 ReadServiceApplication.java
```java
package com.bhaiti.jorhat.read;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients
@EnableDiscoveryClient
public class ReadServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ReadServiceApplication.class, args);
}
}
```
现在,您的微服务应用程序已经完全准备好进行测试了。
首先编译并运行它,然后检查Eureka服务器。
shell cd read-service mvn clean package java -jar target/read-service-0.0.1-SNAPSHOT.jar
现在,点击下面的URL并检查
您将在浏览器中看到如下信息。
只需将书名更改为Book1、Book2和Book4,并对每个条目进行测试。您可以通过以下链接获得所有源代码 - https://github.com/prateekpara ... ample 。
希望你喜欢本教程。