在微服務架構裏說過微服務架構有四大問題,其一就是 這麼多服務,如何管理?java
而Eureka就是Netflix提供給咱們來管理衆多服務的。mysql
Eureka是一個基於REST(Representational State Transfer)的服務,主要用於AWS雲中定位服務,以實現中間層服務器的負載平衡和故障轉移。web
在Netflix,Eureka除了在中端負載平衡中發揮關鍵做用外,還用於如下目的。spring
爲了幫助Netflix Asgard—一個使雲部署更容易的開源服sql
在遇到問題時快速回滾版本,避免從新啓動100個實例,這可能須要很長時間。緩存
在滾動推送中,爲了不在出現問題時向全部實例傳播新版本。服務器
爲了咱們的cassandra部署,將實例從流量中取出進行維護。網絡
爲了咱們的memcached緩存服務來識別環中的節點列表。架構
出於各類其餘緣由,用於攜帶有關服務的其餘特定於應用程序的元數據。app
添加 eureka-server 依賴
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> <version>1.4.7.RELEASE</version> </dependency>
添加配置
server:
port: 7001
eureka:
instance:
hostname: server1
client:
register-with-eureka: false # 是否將本身註冊到Eureka Server, 默認爲true
fetch-registry: false # 是否從Eureka Server獲取註冊信息,默認爲true
service-url:
defaultZone: http://localhost:7001/eureka/
@SpringBootApplication
@MapperScan("com.example.springcloud.mapper") @EnableEurekaServer //聲明該應用爲Eureka Server public class Eureka7001 { public static void main(String[] args) { SpringApplication.run(Eureka7001.class, args); } }
在以前的服務提供者的基礎上,添加 eureka 依賴
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> <version>1.4.7.RELEASE</version> </dependency>
添加配置
server:
port: 8888
spring:
application:
name: springcloud-provider #註冊中心中的服務名
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/db01?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&serverTimezone=Asia/Shanghai
username: root
password: "123456"
type: com.alibaba.druid.pool.DruidDataSource
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/ #對應Eureka Server的defaultZone
@SpringBootApplication @EnableEurekaClient //聲明該應用爲Eureka Client public class Provider_8888 { public static void main(String[] args) { SpringApplication.run(Provider_8888.class,args); } }
server:
port: 80
eureka:
client:
register-with-eureka: false
service-url:
defaultZone: http://localhost:7001/eureka/ #對應Eureka Server的defaultZone
經過服務名調用服務者
package com.example.springcloud.controller; import com.example.springcloud.domain.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import java.util.List; @RestController @RequestMapping("/consumer") public class IndexController { @Autowired private RestTemplate restTemplate; // 「http://服務名/[controller類上的RequestMapping]」,服務名是服務者配置裏的spring.application.name
// 若是服務提供者controller類上不加RequestMapping,[]裏的路徑可去掉 private static final String URL = "http://SPRINGCLOUD-PROVIDER/user/"; @RequestMapping("/user/{id}") public User getUserById(@PathVariable("id")Integer id) { return restTemplate.getForObject(URL+id, User.class); } @RequestMapping("/user/list") public List<User> getAllUser(){ return restTemplate.getForObject(URL, List.class); } @RequestMapping("/user/add") public int addUser(User dept){ return restTemplate.postForObject(URL+"add", dept, Integer.class); } }
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) @EnableEurekaClient //聲明該應用爲Eureka Client public class Consumer { public static void main(String[] args) { SpringApplication.run(Consumer.class, args); } }
server:
port: 7002
eureka:
instance:
hostname: server2 #在註冊中心中的Eureka Server名
client:
register-with-eureka: false # 是否將本身註冊到Eureka Server, 默認爲true
fetch-registry: false # 是否從Eureka Server獲取註冊信息,默認爲true
service-url:
defaultZone: http://localhost:7001/eureka/ #對集羣中其餘Eureka Server,多個用逗號分開
把以前的Eureka Server的配置中的defaultZone也改爲
server:
port: 7001
eureka:
instance:
hostname: server1 #在註冊中心中的Eureka Server名
client:
register-with-eureka: false # 是否將本身註冊到Eureka Server, 默認爲true
fetch-registry: false # 是否從Eureka Server獲取註冊信息,默認爲true
service-url:
defaultZone: http://localhost:7002/eureka/ #對集羣中其餘Eureka Server,多個用逗號分開
2.更改服務者和消費者的配置中的defaultZone
eureka:
client:
register-with-eureka: false
service-url:
defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/ #對集羣中全部Eureka Server,多個用逗號分開
默認狀況下,若是 Eureka Server 在必定的 90s 內沒有接收到某個微服務實例的心跳,會註銷該實例。可是在微服務架構下服務之間一般都是跨進程調用,網絡通訊每每會面臨着各類問題,好比微服務狀態正常,網絡分區故障,致使此實例被註銷。
固定時間內大量實例被註銷,可能會嚴重威脅整個微服務架構的可用性。爲了解決這個問題,Eureka 開發了自我保護機制,那麼什麼是自我保護機制呢?
Eureka Server 在運行期間會去統計心跳失敗比例在 15 分鐘以內是否低於 85%,若是低於 85%,Eureka Server 即會進入自我保護機制。
Eureka Server 觸發自我保護機制後,頁面會出現提示:
Eureka Server 進入自我保護機制,會出現如下幾種狀況:
Eureka 再也不從註冊列表中移除由於長時間沒收到心跳而應該過時的服務
Eureka 仍然可以接受新服務的註冊和查詢請求,可是不會被同步到其它節點上(即保證當前節點依然可用)
當網絡穩定時,當前實例新的註冊信息會被同步到其它節點中
Eureka 自我保護機制是爲了防止誤殺服務而提供的一個機制。當個別客戶端出現心跳失聯時,則認爲是客戶端的問題,剔除掉客戶端;當 Eureka 捕獲到大量的心跳失敗時,則認爲多是網絡問題,進入自我保護機制;當客戶端心跳恢復時,Eureka 會自動退出自我保護機制。
若是在保護期內恰好這個服務提供者非正常下線了,此時服務消費者就會拿到一個無效的服務實例,即會調用失敗。對於這個問題須要服務消費者端要有一些容錯機制,如重試,斷路器等。
經過在 Eureka Server 配置以下參數,開啓或者關閉保護機制,生產環境建議打開:
eureka:
server:
enable-self-preservation: true