簡介
Eureka是Netflix開源的基於rest的服務治理方案,分為Server端和Client端,Server端為注冊中心,其他微服務通過Client端連接Server端進行服務的注冊和發現。
項目介紹
- sc-parent,父模塊
- sc-provider,提供者模塊
- sc-eureka,注冊中心
- sc-consumer-discovery,消費者模塊
搭建父模塊
創建父模塊sc-parent,pom.xml:
<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">
<modelVersion>4.0.0</modelVersion>
<groupId> com.cf</groupId>
<artifactId>sc-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<!-- 繼承Spring Boot的默認值 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<!-- 降低maven-jar-plugin插件版本,防止版本不匹配導致的pom.xml第一行報錯 -->
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
</properties>
<dependencies>
<!-- 添加web應用依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<!-- SpringCloud依賴 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<!-- 打可執行jar包插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- 指定編譯插件使用的jdk版本 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
搭建注冊中心
1.在父模塊下創建子模塊項目sc-eureka,pom.xml:
<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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.cf</groupId>
<artifactId>sc-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>sc-eureka</artifactId>
<dependencies>
<!-- Eureka服務端依賴 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
</project>
2.創建啟動類eureka.EurekaApplication:
package eureka;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
//聲明該類為SpringBoot服務的入口
@SpringBootApplication
//聲明該微服務為注冊中心,提供服務發現和注冊的功能
@EnableEurekaServer
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
3.創建配置文件/src/main/resources/application.yml:
server:
port: 8080 #當前服務端口
eureka:
instance:
hostname: localhost #當前Eureka實例主機名
client:
registerWithEureka: false #表示不向注冊中心注冊自己
fetchRegistry: false #表示此客戶端不需要從Eureka注冊中心獲取Eureka注冊表信息
serviceUrl:
defaultZone: http://localhost:8080/eureka/ ##eureka對外提供的地址(客戶端連接的地址)
其他配置信息可以參考EurekaInstanceConfigBean和EurekaClientConfigBean兩個配置類
4.運行啟動類EurekaApplication,在瀏覽器中訪問http://localhost:8080/,出現如下圖表示注冊中心搭建成功:
提供者與服務注冊
1.在父模塊下創建子模塊項目sc-provider,pom.xml:
<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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.cf</groupId>
<artifactId>sc-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>sc-provider</artifactId>
<dependencies>
<!-- Eureka客戶端依賴,用於連接服務端進行服務注冊和發現 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
</project>
2.創建啟動類provider.ProviderApplication:
package provider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
3.創建Controller:provider.controller.BookController
package provider.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/book")
@RestController
public class BookController {
@GetMapping("/list")
public String getBookList(){
//模擬從service返回數據
return "[\"Java入門到放棄\",\"C++入門到放棄\",\"Python入門到放棄\",\"C入門到放棄\"]";
}
}
4.創建配置文件/src/main/resources/application.yml:
server:
port: 8081
spring:
application:
name: sc-provider #注冊到Eureka注冊中心上的服務名稱,對應Eureka界面上的Application列
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8080/eureka/ #注冊中心的訪問地址
instance:
preferIpAddress: true #表示將自己的IP注冊到Eureka注冊中心。默認為false,表示將hostname注冊到注冊中心
5.依次啟動注冊中心sc-eureka和提供者sc-provider,當提供者啟動時,會將自己的信息注冊到Eureka注冊中心,在瀏覽器中訪問http://localhost:8080/,提供者sc-provider已經在注冊中心注冊。
消費者和服務發現
1.在父模塊下創建子模塊項目sc-consumer-discovery,pom.xml:
<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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.cf</groupId>
<artifactId>sc-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>sc-consumer-discovery</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
</project>
2.創建啟動類consumer.ConsumerDiscoveryApplication:
package consumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
public class ConsumerDiscoveryApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerDiscoveryApplication.class, args);
}
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
3.創建調用提供者服務的Controller:consumer.controller.ConsumerDiscoveryController
package consumer.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class ConsumerDiscoveryController {
@Autowired
private DiscoveryClient discoveryClient;
@Autowired
private RestTemplate restTemplate;
@GetMapping("/getBookList")
public String getBookList(){
//通過服務名獲取實例信息
List<ServiceInstance> list = discoveryClient.getInstances("sc-provider");
if (list != null && list.size() > 0 ) {
//調用服務,並返回服務結果
return restTemplate.getForObject(list.get(0).getUri() + "/book/list", String.class);
}
return null;
}
}
4.創建application.yml:
server:
port: 8082
spring:
application:
name: sc-consumer-discovery
eureka:
client:
registerWithEureka: false #在本實例中消費者不提供服務,所以無需到注冊中心注冊。在實際應用中,消費者也可能是提供者。
serviceUrl:
defaultZone: http://localhost:8080/eureka/
5.依次啟動注冊中心sc-eureka、提供者sc-provider、消費者sc-consumer-discovery,當消費者啟動時,會從注冊中心查詢可用的服務列表及其網絡地址。直接訪問提供者和消費者調用提供者結果如下:
總結
在傳統的應用程序中,都是把提供者的網絡地址硬編碼在代碼中,導致提供者和消費者耦合度高,當提供者網絡地址發生了變化,則需要修改消費者配置並重新發布。Eureka起到了解耦的作用,提供者到Eureka注冊中心中注冊,消費者從Eureka注冊中心中獲取提供者的網絡地址並進行調用,當提供者網絡地址變更時會重新到注冊中心注冊。