二 、Eureka服務註冊與發現
1、服務的註冊與發現
關係調用說明:
-
服務生產者啓動時,向服務註冊中心註冊自己提供的服務
-
服務消費者啓動時,在服務註冊中心訂閱自己所需要的服務
-
註冊中心返回服務提供者的地址信息個消費者
-
消費者從提供者中調用服務
2、啓動eureka註冊中心
Eureka是Spring Cloud Netflix微服務套件中的一部分,可以與Springboot構建的微服務很容易的整合起來。
Eureka包含了服務器端和客戶端組件。服務器端,也被稱作是服務註冊中心,用於提供服務的註冊與發現。
Eureka支持高可用的配置,當集羣中有分片出現故障時,Eureka就會轉入自動保護模式,它允許分片故障期間繼續提供服務的發現和註冊,當故障分片恢復正常時,集羣中其他分片會把他們的狀態再次同步回來。
客戶端組件包含服務消費者與服務生產者。在應用程序運行時,Eureka客戶端向註冊中心註冊自身提供的服務並週期性的發送心跳來更新它的服務租約。同時也可以從服務端查詢當前註冊的服務信息並把他們緩存到本地並週期性的刷新服務狀態。
-
新創建一個
Module
,命名爲springcloud-eureka-7001
,項目結構如下: -
修改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"> <parent> <artifactId>springcloud</artifactId> <groupId>cn.org.july.springcloud</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>springcloud-eureka-7001</artifactId> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--注意:這裏是服務註冊中心,需要引入eureka的服務端 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> </dependencies> </project>
-
在
resources
目錄下新建application.yml
,文件,內容如下:server: port: 7001 eureka: instance: hostname: localhost client: registerWithEureka: false fetchRegistry: false serviceUrl: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ spring: application: name: eurka-server
-
創建包
cn.org.july.springcloud.eureka
,創建系統啓動類ApplicationEnreka
,@SpringBootApplication @EnableEurekaServer public class ApplicationEnreka { public static void main(String[] args) { SpringApplication.run(ApplicationEnreka.class, args); } }
注意:啓動類上需標明該類是Eureka服務端。
-
啓動後訪問http://localhost:7001/ 出現如下頁面服務註冊中心搭建成功。
注意:標註紅的的框框是 No instances available ,表示沒有實例註冊到該服務的註冊中上。
過一段時間,不操作,刷新頁面會看到一段紅色的描述。這個不是錯誤,是Eureka的自我保護。後面我們詳細講解。
3、將用戶微服務注入Eureka註冊中心
3.1、修改用戶微服務
pom修改
在原有pom.xml基礎上新增一下內容:
<!-- 將微服務provider側註冊進eureka -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
修改後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">
<parent>
<artifactId>springcloud</artifactId>
<groupId>cn.org.july.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>springcloud-provider-user-8001</artifactId>
<dependencies>
<!-- 引入API -->
<dependency>
<groupId>cn.org.july.springcloud</groupId>
<artifactId>springcloud-api</artifactId>
<version>${project.version}</version>
</dependency>
<!-- 單元測試 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<!-- 數據源 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<!-- 數據庫驅動-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- 日誌 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<!-- springBoot 集成 mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<!-- web模塊 -->
<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>
<!-- 將微服務provider側註冊進eureka -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
</project>
YML修改
在原application.yml
基礎上新增一下內容:
eureka:
client:
serviceUrl:
defaultZone: http://localhost:7001/eureka/
registerWithEureka: true
fetchRegistry: true
修改後全yml文件內容如下:
server:
port: 8001
mybatis:
type-aliases-package: cn.org.july.springcloudapi.entities #所以entity別名類所在路徑
spring:
application:
name: springcloud-user
datasource:
type: com.alibaba.druid.pool.DruidDataSource #當前數據源操作類型
driver-class-name: com.mysql.cj.jdbc.Driver #mysql驅動包
url: jdbc:mysql://127.0.0.1:3306/cloudDB01?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false #數據庫連接
username: root
password: root
dbcp2:
min-idle: 5 #數據庫連接池的最小維持連接數
initial-size: 5 #初始化連接數
max-total: 5 #最大連接數
max-wait-millis: 200 #等待連接獲取的最大超時時間
eureka:
client:
serviceUrl:
defaultZone: http://localhost:7001/eureka/
registerWithEureka: true
fetchRegistry: true
程序啓動類Application_provider_8001修改:
在Application_provider_8001
類中新增註解@EnableEurekaClient
,
修改後信息如下:
@SpringBootApplication
@EnableEurekaClient //本服務啓動後會自動註冊進eureka服務中
@MapperScan(basePackages = "cn.org.july.springcloud")
public class Application_provider_8001 {
public static void main(String[] args) {
SpringApplication.run(Application_provider_8001.class, args);
}
}
3.2、測試服務注入
1、首先啓動Eureka服務。
2、啓動用戶微服務。
3、在瀏覽器中打開http://127.0.0.1:7001.
可以看到,用戶微服務註冊成功。
Application 名稱對應配置關係如下:
3.3、註冊微服務信息完善
問題:
1、修復 問題一 不顯示服務名稱問題:
修改springcloud-provider-user-8001
服務中的yml文件,新增 instance-id: springcloud-user-8001
重新啓動服務,問題修改完成。
eureka:
client:
serviceUrl:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
registerWithEureka: true
fetchRegistry: true
instance:
instance-id: springcloud-user-8001
2、修復問題二 不顯示Ip地址:
修改springcloud-provider-user-8001
服務yml文件,新增 prefer-ip-address: true
節點,全部內容如下:
eureka:
client:
serviceUrl:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
registerWithEureka: true
fetchRegistry: true
instance:
instance-id: springcloud-user-8001
prefer-ip-address: true
重啓服務,問題修改完成。
3、點擊服務名稱,頁面跳轉404頁面。
修復方案如下:
a、修改springcloud-provider-user-8001
服務pom文件新增如下內容:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
完整pom文件
<?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">
<parent>
<artifactId>springcloud</artifactId>
<groupId>cn.org.july.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>springcloud-provider-user-8001</artifactId>
<dependencies>
<!-- 引入API -->
<dependency>
<groupId>cn.org.july.springcloud</groupId>
<artifactId>springcloud-api</artifactId>
<version>${project.version}</version>
</dependency>
<!-- 單元測試 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<!-- 數據源 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<!-- 數據庫驅動-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- 日誌 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<!-- springBoot 集成 mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<!-- web模塊 -->
<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>
<!-- actuator監控信息完善 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- 將微服務provider側註冊進eureka -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
</project>
b、修改springcloud-provider-user-8001
yml文件修改內容如下:新增info節點
info:
app.name: springcloud-user
company.name: www.july.com
build.artifactId: springcloud
build.version: 1.0-SNAPSHOT
完整yml文件如下:
server:
port: 8001
mybatis:
type-aliases-package: cn.org.july.springcloudapi.entities #所以entity別名類所在路徑
spring:
application:
name: springcloud-user
datasource:
type: com.alibaba.druid.pool.DruidDataSource #當前數據源操作類型
driver-class-name: com.mysql.cj.jdbc.Driver #mysql驅動包
url: jdbc:mysql://127.0.0.1:3306/cloudDB01?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false #數據庫連接
username: root
password: root
dbcp2:
min-idle: 5 #數據庫連接池的最小維持連接數
initial-size: 5 #初始化連接數
max-total: 5 #最大連接數
max-wait-millis: 200 #等待連接獲取的最大超時時間
eureka:
client:
serviceUrl:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
registerWithEureka: true
fetchRegistry: true
instance:
instance-id: springcloud-user-8001
prefer-ip-address: true
info:
app.name: springcloud-user
company.name: www.july.com
build.artifactId: springcloud
build.version: 1.0-SNAPSHOT
問題修復完成,看下修改效果:
點擊服務名稱,顯示我們自己定義的服務信息。
4、Eureka集羣搭建
CAP原則(CAP定理):
CAP原則又稱CAP定理,指的是在一個分佈式系統中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分區容錯性),三者不可得兼。
CAP原則是NOSQL數據庫的基石。Consistency(一致性)。 Availability(可用性)。Partition tolerance(分區容錯性)。
分佈式系統的CAP理論:理論首先把分佈式系統中的三個特性進行了如下歸納:
一致性(C):在分佈式系統中的所有數據備份,在同一時刻是否同樣的值。(等同於所有節點訪問同一份最新的數據副本)
可用性(A):在集羣中一部分節點故障後,集羣整體是否還能響應客戶端的讀寫請求。(對數據更新具備高可用性)
分區容忍性(P):以實際效果而言,分區相當於對通信的時限要求。系統如果不能在時限內達成數據一致性,就意味着發生了分區的情況,必須就當前操作在C和A之間做出選擇。
4.1、集羣搭建
新建springcloud-eureka-7002,
springcloud-eureka-7003服務。copy
springcloud-eureka-7001`中配置。修改服務啓動端口分別爲7002,7003。修改系統主啓動類。
修改內容如下:
系統啓動類:
springcloud-eureka-7001
@SpringBootApplication
@EnableEurekaServer
public class ApplicationEureka7001 {
public static void main(String[] args) {
SpringApplication.run(ApplicationEureka7001.class, args);
}
}
springcloud-eureka-7002
@SpringBootApplication
@EnableEurekaServer
public class ApplicationEureka7002 {
public static void main(String[] args) {
SpringApplication.run(ApplicationEureka7002.class, args);
}
}
springcloud-eureka-7003
@SpringBootApplication
@EnableEurekaServer
public class ApplicationEureka7003 {
public static void main(String[] args) {
SpringApplication.run(ApplicationEureka7003.class, args);
}
}
4.2、修改映射配置
修改系統hosts文件
新增如下信息:
127.0.0.1 eureka7001.com
127.0.0.1 eureka7002.com
127.0.0.1 eureka7003.com
4.3、修改服務配置yml
springcloud-eureka-7001
server:
port: 7001
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/ # 單點http://${eureka.instance.hostname}:${server.port}/eureka/
spring:
application:
name: eurka-server
springcloud-eureka-7002
server:
port: 7002
eureka:
instance:
hostname: eureka7002.com
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7003.com:7003/eureka/ # 單點http://${eureka.instance.hostname}:${server.port}/eureka/
spring:
application:
name: eurka-server
springcloud-eureka-7003
server:
port: 7003
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/ # 單點http://${eureka.instance.hostname}:${server.port}/eureka/
spring:
application:
name: eurka-server
4.4、修改服務提供者springcloud-provider-user-8001
配置
將之前單點連接替換成集羣地址,完整yml文件如下:
server:
port: 8001
mybatis:
type-aliases-package: cn.org.july.springcloudapi.entities #所以entity別名類所在路徑
spring:
application:
name: springcloud-user
datasource:
type: com.alibaba.druid.pool.DruidDataSource #當前數據源操作類型
driver-class-name: com.mysql.cj.jdbc.Driver #mysql驅動包
url: jdbc:mysql://127.0.0.1:3306/cloudDB01?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false #數據庫連接
username: root
password: root
dbcp2:
min-idle: 5 #數據庫連接池的最小維持連接數
initial-size: 5 #初始化連接數
max-total: 5 #最大連接數
max-wait-millis: 200 #等待連接獲取的最大超時時間
eureka:
client:
serviceUrl:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
registerWithEureka: true
fetchRegistry: true
instance:
instance-id: springcloud-user-8001
prefer-ip-address: true
info:
app.name: springcloud-user
company.name: www.july.com
build.artifactId: springcloud
build.version: 1.0-SNAPSHOT
啓動Eureka服務,啓動服務提供者服務,在瀏覽器中輸入 http://127.0.0.1:7001
訪問http://127.0.0.1:7002
我們可以看到,訪問任一節點都可以看到微服務springcloud-provider-user-8001
註冊成功,並Eureka關聯另外兩個節點信息。故我們的eureka集羣搭建成功。