从零开始搭建spring-cloud(1) ----eureka
擼了今年阿里、頭條和美團的面試,我有一個重要發現.......>>>
什么是Eureka,什么是服務注冊與發現?
Spring Boot作為目前最火爆的web框架。那么spring boot與Eureka又有什么關聯呢?
Eureka是Netflix開源的一個RESTful服務,主要用于服務的注冊發現。
Eureka由兩個組件組成:Eureka服務器和Eureka客戶端。Eureka服務器用作服務注冊服務器。
Eureka客戶端是一個java客戶端,用來簡化與服務器的交互、作為輪詢負載均衡器,并提供服務的故障切換支持。
Netflix在其生產環境中使用的是另外的客戶端,它提供基于流量、資源利用率以及出錯狀態的加權負載均衡。
SpringCloud Eureka是SpringCloud Netflix服務套件中的一部分,它基于Netflix Eureka做了二次封裝,主要負責完成微服務架構中的服務治理功能。
從零開始搭建Eureka。
我們在創建新的項目時,如果選擇了相關SpringCloud的依賴,則會自動在pom.xml配置文件內添加SpringCloud最新穩定版本依賴配置。
spring-cloud-dependencies這個依賴是SpringCloud內所需要依賴的版本維護,在maven項目內如果被<dependencyManagement>內修飾的<dependency>,子項目或者本項目在使用時可以不用設置版本號,默認使用<dependencyManagement>下<dependency>內設置的版本信息。
正因如此,這也是為什么我們添加了spring-cloud-dependencies依賴后,在使用相關SpringCloud插件時可以不用添加version標簽設置導入指定版本的依賴。
Eureka-server項目,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-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?
僅僅需要在啟動類上開啟一個注解@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,內容如下:
server.port=8080eureka.instance.hostname=127.0.0.1 # 是否向服務中心注冊自己 eureka.client.register-with-eureka=false # 是否檢索服務 eureka.client.fetch-registry=false # 測試時關閉自我保護機制,保證不可用服務及時踢出, 生產環境中需要打開自我保護機制 eureka.server.enable-self-preservation=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/
可以看到可視化界面,但是我們發現這里并沒有Application服務,“No instances available”,如果設置eureka.client.register-with-eureka=true將會在這里顯示出自己的服務,目前還沒有其他服務向服務中心注冊,所以沒有其他服務。
Eureka-client項目,作為Eureka服務提供者,provider-A-1
當客戶端注冊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已經成功加入進去了。
有標紅的,因為注冊的服務都是高可用的,這里只檢測到一個服務,產生的預警,不影響使用,等下我們啟動多個實例就不會了。
測試客戶端方法是否可用:
說明客戶端正常。
再建立一個Eureka-client項目,作為Eureka服務提供者,provider-A-2
這個服務提供者與上一個服務提供者幾乎一樣。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的服務
建立Eureka-client項目,作為Eureka服務消費者,consumer-A-1
我們目前已經提供好了服務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,所以啟動的時候需要實例化該類的一個實例@Autowiredprivate RestTemplateBuilder builder;@Autowiredprivate RestTemplate restTemplate;// 使用RestTemplateBuilder來實例化RestTemplate對象,spring默認已經注入了RestTemplateBuilder實例@Bean@LoadBalancedpublic RestTemplate restTemplate() {return builder.build();}/*** Rest服務端使用RestTemplate發起http請求,然后得到數據返回給前端* @param username* @return*/@GetMapping(value = "/gotoUser/{username}")@ResponseBodypublic 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)都向注冊中心注冊一個服務。
有時候,某個服務的工作量比較大的時候,我們可以多注冊幾個同名稱的微服務,從而讓他們交替工作,減輕單個服務的壓力。
總結
以上是生活随笔為你收集整理的从零开始搭建spring-cloud(1) ----eureka的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: springcloud 中的zuul整合
- 下一篇: 从零开始搭建spring-cloud(0