Spring Boot做爲目前最火爆的web框架。那麼spring boot與Eureka又有什麼關聯呢?前端
Eureka是Netflix開源的一個RESTful服務,主要用於服務的註冊發現。
Eureka由兩個組件組成:Eureka服務器和Eureka客戶端。Eureka服務器用做服務註冊服務器。
Eureka客戶端是一個java客戶端,用來簡化與服務器的交互、做爲輪詢負載均衡器,並提供服務的故障切換支持。
Netflix在其生產環境中使用的是另外的客戶端,它提供基於流量、資源利用率以及出錯狀態的加權負載均衡。
SpringCloud Eureka是SpringCloud Netflix服務套件中的一部分,它基於Netflix Eureka作了二次封裝,主要負責完成微服務架構中的服務治理功能。java
咱們在建立新的項目時,若是選擇了相關SpringCloud的依賴,則會自動在pom.xml配置文件內添加SpringCloud最新穩定版本依賴配置。
spring-cloud-dependencies這個依賴是SpringCloud內所須要依賴的版本維護,在maven項目內若是被<dependencyManagement>內修飾的<dependency>,子項目或者本項目在使用時能夠不用設置版本號,默認使用<dependencyManagement>下<dependency>內設置的版本信息。
正因如此,這也是爲何咱們添加了spring-cloud-dependencies依賴後,在使用相關SpringCloud插件時能夠不用添加version標籤設置導入指定版本的依賴。web
新建maven項目,其中pom.xml內容以下:spring
<?xml version="1.0" encoding="UTF-8"?> <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.vincent</groupId> <artifactId>spring-cloud-eureka-server</artifactId> <version>1.0-SNAPSHOT</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.1.4.RELEASE</version> <scope>import</scope> <type>pom</type> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Greenwich.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> </dependencies> </project>
能夠看到,這裏與普通的springboot惟一區別是添加了eureka-server依賴包。如何使用Eureka?apache
僅僅須要在啓動類上開啓一個註解@EnableEurekaServer就能夠,App.java以下:瀏覽器
package com.vincent; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; /** * Created by iie4b on 2019-6-18 21:27 */ @SpringBootApplication @EnableEurekaServer public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } }
配置application.properties,內容以下:springboot
server.port=8080 eureka.instance.hostname=127.0.0.1 # 是否向服務中心註冊本身 eureka.client.register-with-eureka=false # 是否檢索服務 eureka.client.fetch-registry=false # 服務註冊中心的配置內容,指定服務註冊中心的位置 eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
其中「defaultZone」是一個魔術字符串後備值,爲任何不表示首選項的客戶端提供服務URL(即它是有用的默認值)。服務器
Eureka是一個高可用的組件,每個實例註冊以後須要向註冊中心發送心跳包,在默認狀況下erureka server也是一個eureka client ,必需要指定一個 server。eureka.client.register-with-eureka=false表示是否向註冊中心註冊本身,默認爲true,true將會在註冊中心看到server本身的服務。架構
啓動App.java,在瀏覽器上輸入http://127.0.0.1:8080/app
能夠看到可視化界面,可是咱們發現這裏並無Application服務,「No instances available」,若是設置eureka.client.register-with-eureka=true將會在這裏顯示出本身的服務,目前尚未其餘服務向服務中心註冊,因此沒有其餘服務。
當客戶端註冊Eureka時,它提供關於自身的元數據,例如主機和端口,健康指示符URL,主頁等。Eureka從屬於服務的每一個實例接收心跳消息。若是心跳失敗超過可配置的時間表,則一般將該實例從註冊表中刪除。
新建maven項目,其中pom.xml內容以下:
<?xml version="1.0" encoding="UTF-8"?> <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.vincent</groupId> <artifactId>spring-cloud-eureka-provider-A-1</artifactId> <version>1.0-SNAPSHOT</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.1.4.RELEASE</version> <scope>import</scope> <type>pom</type> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Greenwich.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> </dependencies> </project>
client的依賴與server的依賴幾乎同樣。
在Spring-boot的啓動類上經過註解@EnableEurekaClient 代表本身是一個eurekaclient.
App.java內容以下:
package com.vincent; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; /** * Created by vincent on 2019-6-18 21:56 */ @SpringBootApplication @EnableEurekaClient public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } }
同時provider-A項目提供一個服務,新建controller/UserController.java
package com.vincent.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.Map; /** * Created by vincent on 2019-6-18 21:58 */ @RestController public class UserController { @GetMapping("/user/{name}") public Map<String,Object> getUser(@PathVariable("name") String userName) { Map<String,Object> data = new HashMap<>(); data.put("id",userName); data.put("from","provider-A-1"); return data; } }
而後配置application.properties,內容以下:
# 註冊中心的註冊地址 eureka.client.service-url.defaultZone=http://127.0.0.1:8080/eureka/ # 服務名稱--調用的時候根據名稱來調用該服務的方法 spring.application.name=service-provider-A server.port=8081
啓動App.java
從界面裏咱們能夠看到,這個客戶端已經向註冊中心註冊服務了,刷新http://localhost:8080/
能夠看到SERVICE-PROVIDER-A-1已經成功加入進去了。
有標紅的,由於註冊的服務都是高可用的,這裏只檢測到一個服務,產生的預警,不影響使用,等下咱們啓動多個實例就不會了。
測試客戶端方法是否可用:
說明客戶端正常。
這個服務提供者與上一個服務提供者幾乎同樣。pom.xml以下:
<?xml version="1.0" encoding="UTF-8"?> <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.vincent</groupId> <artifactId>spring-cloud-eureka-provider-A-2</artifactId> <version>1.0-SNAPSHOT</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.1.4.RELEASE</version> <scope>import</scope> <type>pom</type> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Greenwich.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> </dependencies> </project>
爲了與provider-A-1區別,provider-A-2中的UserController.java以下:
@RestController public class UserController { @GetMapping("/user/{name}") public Map<String,Object> getUser(@PathVariable("name") String userName) { Map<String,Object> data = new HashMap<>(); data.put("id",userName); data.put("from","provider-A-2"); return data; } }
provider-A-2中的application.properties以下:
# 註冊中心的註冊地址 eureka.client.service-url.defaultZone=http://127.0.0.1:8080/eureka/ # 服務名稱--調用的時候根據名稱來調用該服務的方法 spring.application.name=service-provider-A server.port=8082
注意這裏的application.name都是service-provider-A
啓動App.java
查看Eureka Server後臺:
發現紅色的警告沒有了,由於咱們有了兩個一樣的服務,提供了高可用服務,還能夠負載均衡。
這兩個服務能夠分別訪問如下:
端口8081表示Provider-A-1的服務
端口8082表示Provider-A-2的服務
咱們目前已經提供好了服務provider-A-1和provider-A-2,而且他們有負載均衡的能力。接下來創建消費者,使用服務。
創建消費者,他的pom.xml以下:
<groupId>com.vincent</groupId> <artifactId>spring-cloud-eureka-consumer-A-1</artifactId> <version>1.0-SNAPSHOT</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.1.4.RELEASE</version> <scope>import</scope> <type>pom</type> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Greenwich.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> </dependencies>
創建ConsumerController.java
package com.vincent.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.web.bind.annotation.*; import org.springframework.web.client.RestTemplate; import java.util.HashMap; import java.util.Map; /** * Created by vincent on 2019-6-19 19:09 */ @RestController public class ConsumerController { // 啓動的時候要注意,因爲咱們在controller中注入了RestTemplate,因此啓動的時候須要實例化該類的一個實例 @Autowired private RestTemplateBuilder builder; @Autowired private RestTemplate restTemplate; // 使用RestTemplateBuilder來實例化RestTemplate對象,spring默認已經注入了RestTemplateBuilder實例 @Bean @LoadBalanced public RestTemplate restTemplate() { return builder.build(); } /** * Rest服務端使用RestTemplate發起http請求,而後獲得數據返回給前端 * @param username * @return */ @GetMapping(value = "/gotoUser/{username}") @ResponseBody public Map<String, Object> getUser(@PathVariable("username") String username) { Map<String, Object> data = new HashMap<>(); /** * 地址是http://service-provider * 而不是http://127.0.0.1:8082/ * 由於他向註冊中心註冊了服務,服務名稱service-provider-A,咱們訪問service-provider-A便可 */ data = restTemplate.getForObject("http://service-provider-A/user/" + username, Map.class); return data; } }
啓動類App.java
@SpringBootApplication @EnableEurekaClient public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } }
consumer-A的application.properties內容以下:
# 註冊中心的註冊地址 eureka.client.service-url.defaultZone=http://127.0.0.1:8080/eureka/ # 服務名稱--調用的時候根據名稱來調用該服務的方法 spring.application.name=service-consumer-A server.port=8083
能夠看到有兩個服務提供方,一個消費者。由於消費者服務沒有負載均衡,因此有警告,能夠忽略。
訪問消費者,瀏覽器輸入http://localhost:8083/gotoUser/vincent
能夠實現負載均衡,交替訪問provider-A-1和provider-A-2。
每一個微服務都是一個Eureka-Client,咱們把每一個app(SpringBootApplication)都向註冊中心註冊一個服務。 有時候,某個服務的工做量比較大的時候,咱們能夠多註冊幾個同名稱的微服務,從而讓他們交替工做,減輕單個服務的壓力。