1、認識Eureka
Eureka是Netflix的一個子模塊,也是核心模塊之一。Eureka是一個基於REST的服務,用於定位服務,以實現雲端中間層服務發現和故障轉移。服務註冊與發現對於微服務架構來說是非常重要的,有了服務發現與註冊,只需要使用服務的標識符,就可以訪問到服務,而不需要修改服務調用的配置文件了。功能類似於dubbo的註冊中心,比如Zookeeper。
2、原理講解
2.1、Eureka基本架構
Spring Cloud 封裝了 Netflix 公司開發的 Eureka 模塊來實現服務註冊和發現,Eureka 採用了 C-S 的設計架構。Eureka Server 作爲服務註冊功能的服務器,它是服務註冊中心。而系統中的其他微服務,使用 Eureka 的客戶端連接到 Eureka Server並維持心跳連接。這樣系統的維護人員就可以通過 Eureka Server 來監控系統中各個微服務是否正常運行。SpringCloud 的一些其他模塊(比如Zuul)就可以通過 Eureka Server 來發現系統中的其他微服務,並執行相關的邏輯。
Eureka架構:
Zookeeper架構:
Eureka包含兩個組件:Eureka Server和Eureka Client。
-
Eureka Server提供服務註冊服務,各個節點啓動後,會在EurekaServer中進行註冊,這樣EurekaServer中的服務註冊表中將會存儲所有可用服務節點的信息,服務節點的信息可以在界面中直觀的看到;
-
EurekaClient是一個Java客戶端,用於簡化Eureka Server的交互,客戶端同時也具備一個內置的、使用輪詢(round-robin)負載算法的負載均衡器。在應用啓動後,將會向Eureka Server發送心跳(默認週期爲30秒)。如果Eureka Server在多個心跳週期內沒有接收到某個節點的心跳,EurekaServer將會從服務註冊表中把這個服務節點移除(默認90秒)
2.2 Eureka三大架構
-
Eureka Server 提供服務註冊和發現;
-
Service Provider服務提供方將自身服務註冊到Eureka,從而使服務消費方能夠找到;
-
Service Consumer服務消費方從Eureka獲取註冊服務列表,從而能夠消費服務;
3、配置Eureka服務註冊中心
3.1、新建microservicecloud-eureka-7001eureka服務註冊中心Module
1)新建microservicecloud-eureka-7001
在microservicecloud下選擇maven Module,後新建module,這裏步驟不詳細說明。
2)pom文件
<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.jiatp.springcloud</groupId>
<artifactId>microservicecloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>microservicecloud-eureka-7001</artifactId>
<description>eureka註冊中心</description>
<dependencies>
<!--eureka-server服務端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
<version>1.2.7.RELEASE</version>
</dependency>
<!-- 修改後立即生效,熱部署 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
<version>1.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
</project>
3)yml配置
server:
port: 7001
eureka:
instance:
hostname: localhost #eureka服務端的實例名稱
client:
register-with-eureka: false #false表示不向註冊中心註冊自己。
fetch-registry: false #false表示自己端就是註冊中心,我的職責就是維護服務實例,並不需要去檢索服務
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #設置與Eureka Server交互的地址查詢服務和註冊服務都需要依賴這個地址。
4)EurekaServer7001_App主啓動類
@SpringBootApplication
@EnableEurekaServer //開啓服務 eureka server
public class EurekaServer7001_App {
public static void main(String[] args) {
// TODO Auto-generated method stub
SpringApplication.run(EurekaServer7001_App.class, args);
}
}
測試:http://localhost:7001/
無註冊的服務:現在沒有Eureka客戶端
3.2、修改microservicecloud-provider-dept-8001將部門微服務註冊進eureka服務中心
1)修改pom文件
<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.jiatp.springcloud</groupId>
<artifactId>microservicecloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>microservicecloud-provider-dept-8001</artifactId>
<dependencies>
<dependency><!-- 引入自己定義的api通用包,可以使用Dept部門Entity -->
<groupId>com.jiatp.springcloud</groupId>
<artifactId>microservicecloud-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</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-test</artifactId>
</dependency>
<!-- 修改後立即生效,熱部署 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
<version>1.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<!--添加到eureka客戶端 將provider註冊進去 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
</dependencies>
</project>
2)yml配置
server:
port: 8001
mybatis:
config-location: classpath:mybatis/mybatis.cfg.xml # mybatis配置文件所在路徑
type-aliases-package: com.jiatp.springcloud.entity # 掃描此包下的entity ->所有entity別名類所在包
mapper-locations:
- classpath:mybatis/mapper/**/*.xml # mapper映射文件
spring:
application:
name: microservicecloud-dept # 很重要,對外暴露的微服務名字
datasource:
type: com.alibaba.druid.pool.DruidDataSource # 數據源類型
driver-class-name: org.gjt.mm.mysql.Driver # 數據庫驅動包
url: jdbc:mysql://localhost:3306/cloudDB01?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone = GMT
username: root
password: 123456
dbcp2:
min-idle: 5 # 數據庫連接池的最小維持連接數
initial-size: 5 # 初始化連接數
max-idle: 5 # 最大連接數
max-wait-millis: 200 # 等待連接獲取的最大超時時間
eureka:
client: # 客戶端註冊進eureka服務列表內
serviceUrl:
defaultZone: http://localhost:7001/eureka
3)修改DeptProvider8001_App主啓動類
@SpringBootApplication
@EnableEurekaClient //本服務啓動後會自動註冊進eureka服務中
public class DeptProvider8001_App
{
public static void main(String[] args)
{
SpringApplication.run(DeptProvider8001_App.class, args);
}
}
測試:先要啓動EurekaServer,輸入http://localhost:7001/
注意這裏:Application:名字是yml配置中:spring.application.name=xxxxx
3.3、Actuator應用監控和註冊信息完善
1)主機名稱微服務名稱修改
eureka:
instance:
instance-id: microservicecloud-dept8001 # 自定義服務名稱信息
2)訪問信息有IP信息提示
eureka:
client: #客戶端註冊進eureka服務列表內
service-url:
defaultZone: http://localhost:7001/eureka
instance:
instance-id: microservicecloud-dept8001 #自定義服務名稱信息
prefer-ip-address: true #訪問路徑可以顯示IP地址
3)微服務info內容詳細信息
引入Actuator應用監控 相關依賴
<!--springboot2.x之Actuator應用監控 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
總的父工程microservicecloud修改pom.xml添加構建build信息
pom文件添加
<build>
<finalName>microservicecloud</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<delimiters>
<delimit>$</delimit>
</delimiters>
</configuration>
</plugin>
</plugins>
</build>
修改microservicecloud-provider-dept-8001中yml中添加info信息
info:
app.name: jiatp-microservicecloud
company.name: www.jiatp.club
build.artifactId: $project.artifactId$
build.version: $project.version$
3.4、microservicecloud-provider-dept-8001服務發現Discovery
對於註冊進eureka裏面的微服務,可以通過服務發現來獲得該服務的信息
1)修改microservicecloud-provider-dept-8001工程的DeptController
@RequestMapping(value = "/dept/discovery", method = RequestMethod.GET)
public Object discovery()
{
List<String> list = client.getServices();
System.out.println("**********" + list);
List<ServiceInstance> srvList = client.getInstances("MICROSERVICECLOUD-DEPT");
for (ServiceInstance element : srvList) {
System.out.println(element.getServiceId() + "\t" + element.getHost() + "\t" + element.getPort() + "\t"
+ element.getUri());
}
2)修改DeptProvider8001_App主啓動類
@SpringBootApplication
@EnableEurekaClient //本服務啓動後會自動註冊進eureka服務中
@EnableDiscoveryClient //服務發現
public class DeptProvider8001_App
{
public static void main(String[] args)
{
SpringApplication.run(DeptProvider8001_App.class, args);
}
}
測試:啓動順序:先要啓動EurekaServer,再啓動DeptProvider8001_App主啓動類,需要稍等一會兒,輸入http://localhost:8001/dept/discovery
這裏也可以通過修改消費者:microservicecloud-consumer-dept-80工程的DeptController_Consumer
//測試@EnableDiscoveryClient,消費端可以調用服務發現
@RequestMapping(value="/consumer/dept/discovery")
public Object discovery()
{
return restTemplate.getForObject(REST_URL_PREFIX+"/dept/discovery", Object.class);
}
在瀏覽器測試:http://localhost/consumer/dept/discovery
知識點:eureka自我保護
故障現象:
什麼是自我保護?
默認情況下,如果EurekaServer在一定時間內沒有接收到某個微服務實例的心跳,EurekaServer將會註銷該實例(默認90秒)。但是當網絡分區故障發生時,微服務與EurekaServer之間無法正常通信,以上行爲可能變得非常危險了——因爲微服務本身其實是健康的,此時本不應該註銷這個微服務。Eureka通過“自我保護模式”來解決這個問題——當EurekaServer節點在短時間內丟失過多客戶端時 (可能發生了網絡分區故障),那麼這個節點就會進入自我保護模式。一旦進入該模式,EurekaServer就會保護服務註冊表中的信息,不再刪除服務註冊表中的數據(也就是不會註銷任何微服務)。當網絡故障恢復後,該Eureka Server節點會自動退出自我保護模式。
在自我保護模式中,Eureka Server會保護服務註冊表中的信息,不再註銷任何服務實例。當它收到的心跳數重新恢復到閾值以上時,該Eureka Server節點就會自動退出自我保護模式。它的設計哲學就是寧可保留錯誤的服務註冊信息,也不盲目註銷任何可能健康的服務實例。
綜上,自我保護模式是一種應對網絡異常的安全保護措施。它的架構哲學是寧可同時保留所有微服務(健康的微服務和不健康的微服務都會保留),也不盲目註銷任何健康的微服務。使用自我保護模式,可以讓Eureka集羣更加的健壯、穩定。
在Spring Cloud中,可以使用eureka.server.enable-self-preservation = false 禁用自我保護模式。