什麼是服務治理
在傳統rpc遠端調用中,服務與服務依賴關系,管理比較複雜,是以需要使用服務治理,
管理服務與服務之間依賴關系,
可以實作服務調用、負載均衡、容錯等,實作服務發現與注冊。
什麼是服務注冊與發現
在服務注冊與發現中,有一個注冊中心,當伺服器啟動的時候,會把目前自己伺服器的資訊 比如 服務位址通訊位址等以别名方式注冊到注冊中心上。
另一方(消費者|服務提供者),以該别名的方式去注冊中心上擷取到實際的服務通訊位址,讓後在實作本地rpc調用遠端。
一、搭建 erueka 注冊中心環境
1、建立springboot 項目,springcloud-erueka

2、maven 全部依賴資訊
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>springcloud-erueka</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springcloud-erueka</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<!-- 管理依賴 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.M7</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!--SpringCloud eureka-server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
<!-- 注意: 這裡必須要添加, 否者各種依賴有問題 -->
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3、yml 配置
###服務端口号
server:
port: 8100
###eureka 基本資訊配置
eureka:
instance:
hostname: 127.0.0.1 # 注冊到eurekaip位址
client:
serviceUrl:
#注冊中心位址
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
register-with-eureka: false #因為自己是為注冊中心,不需要自己注冊自己
fetch-registry: false #因為自己是為注冊中心,不需要檢索服務
4、啟動類添加 @EnableEurekaServer
@SpringBootApplication
@EnableEurekaServer
public class SpringcloudEruekaApplication {
public static void main(String[] args) {
SpringApplication.run(SpringcloudEruekaApplication.class, args);
}
}
5、啟動項目通路 ,http://localhost:8100/ (ip+端口)
出現如下搭建成功
二、搭建消費和服務項目
1、建立springboot項目
springcloud-member ,springcloud-order ,配置都相同
2、maven 配置
<!-- 管理依賴 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.M7</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- SpringBoot整合Web元件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- SpringBoot整合eureka用戶端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
<!-- 注意: 這裡必須要添加, 否者各種依賴有問題 -->
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
3、yml 配置
服務名稱不同
pringcloud-order --> name: app-order
pringcloud-member --> name: app-member
其他相同,如下:修改服務名稱同上
###服務啟動端口号
server:
port: 8000
spring:
application:
name: app-order # 服務名稱(服務注冊到eureka名稱)
### 服務注冊
eureka:
client:
service-url:
defaultZone: http://localhost:8100/eureka # 注冊中心eureka位址
register-with-eureka: true # 因為該應用為注冊中心,不會注冊自己
fetch-registry: true # 是否需要從eureka上擷取注冊資訊
4、啟動類添加@EnableEurekaClient 和 注入RestTemplate
所有客服端相同
@SpringBootApplication
@EnableEurekaClient //Eureka 用戶端
public class SpringcloudOrderApplication {
public static void main(String[] args) {
SpringApplication.run(SpringcloudOrderApplication.class, args);
}
/**
* TODO RestTemplate = rest,http風格的,api調用工具
*
* @return org.springframework.web.client.RestTemplate
* @date 2019/12/6 0006 12:02
*/
@Bean //注入springboot容器
@LoadBalanced //讓RestTemplate在請求時擁有用戶端負載均衡的能力
RestTemplate restTemplate() {
return new RestTemplate();
}
}
5、生産者 member項目添加方法 getMember
@RestController
public class memberController {
@RequestMapping("getMember")
public String getMember(){
return "memberController 的Api 接口";
}
}
結構如下
6、消費者 order 項目添加方法調用生産者方法
http://app-member/getMember 中的 app-member 等于pringcloud-member 服務名,也就是serviceId
@RestController
public class OrderController {
@Autowired
private RestTemplate restTemplate;
@RequestMapping("/getorder")
public String getOrder() {
// order 使用rpc 遠端調用技術 調用 會員服務
String memberUrl = "http://app-member/getMember";
//調用接口
String result = restTemplate.getForObject(memberUrl, String.class);
System.out.println("會員服務調用訂單服務,result:" + result);
return result;
}
}
7、啟動項目,先啟動erueka,在啟動客服端
8、測試結果
http://win-cdi45048l28 等同與Ip,可以寫為ip
三、搭建高可用,叢集
建立兩個erueka項目叢集,建立項目同一,看上方
1、客服端叢集預設使用輪訓機制,直接注冊多個相關name的服務即可
2、注冊中心叢集預設主從模式,當主當機了,自動切換備機
1、erueka-A 注冊中心,yml配置
###服務端口号
server:
port: 8100
spring:
application:
name: eureka-server # 叢集的所有erueka 項目名稱必須相同
###eureka 基本資訊配置
eureka:
instance:
hostname: 127.0.0.1 # 注冊到eurekaip位址
client:
serviceUrl:
#注冊中心位址
defaultZone: http://127.0.0.1:8200/eureka/ # 叢集設定為另一台或者多台eureka注冊中心,多個叢集,逗号分隔
register-with-eureka: true # 叢集把自己注冊到另外一台eureka注冊中心,設定為true
fetch-registry: true # 叢集需要檢索服務,設定為true'
2、erueka-B 注冊中心,yml配置
端口: 8200 ,注冊到http://127.0.0.1:8100/eureka/
###服務端口号
server:
port: 8200
spring:
application:
name: eureka-server # 叢集的所有erueka 項目名稱必須相同
###eureka 基本資訊配置
eureka:
instance:
hostname: 127.0.0.1 # 注冊到eurekaip位址
client:
serviceUrl:
#注冊中心位址
defaultZone: http://127.0.0.1:8100/eureka/ # 叢集設定為另一台或者多台eureka注冊中心,多個叢集,逗号分隔
register-with-eureka: true # 叢集把自己注冊到另外一台eureka注冊中心,設定為true
fetch-registry: true # 叢集需要檢索服務,設定為true'
3、客服端使用叢集版erueka
defaultZone: http://localhost:8100/eureka,http://localhost:8200/eureka # 配置為多個位址即可
如:
server:
port: 8000
spring:
application:
name: app-member
###單機位址
#eureka:
# client:
# service-url:
# defaultZone: http://localhost:8100/eureka
###叢集位址
eureka:
client:
service-url:
defaultZone: http://localhost:8100/eureka,http://localhost:8200/eureka
register-with-eureka: true
fetch-registry: true
這裡就不示範了,很簡單的
四、erueka 自我保護機制
1、緩存機制
消費者啟動的時候,使用服務别名,會發送一個rest請求到服務注冊中心擷取對應的服務資訊,讓後會緩存到本地jvm用戶端中,同時用戶端每隔30秒從伺服器上更新一次。
可以通過 fetch-inte vall-seconds=30參數進行修以
通過eureka.client .registry該參數預設值為30, 機關為秒。
## 修改從注冊中心獲得的位址在本地的緩存時間
fetch-inte vall-seconds=30 || eureka.client.registry=30
自我保護機制
預設情況下,EurekaClient會定時向EurekaServer端發送心跳,如果EurekaServer在一定時間内沒有收到EurekaClient發送的心跳,便會把該執行個體從注冊服務清單中剔除(預設是90秒),但是在短時間内丢失大量的執行個體心跳,這時候EurekaServer會開啟自我保護機制,Eureka不會踢出該服務。
關閉自我保護機制,服務端yml 添加配置
server:
# 測試時關閉自我保護機制,保證不可用服務及時踢出
enable-self-preservation: false
eviction-interval-timer-in-ms: 2000 # 踢出執行的線程時間間隔
完整如下:
eureka:
instance:
###注冊中心ip位址
hostname: 127.0.0.1
client:
serviceUrl:
##注冊位址
defaultZone: http://${eureka.instance.hostname}:8100/eureka/
####因為自己是注冊中心,是否需要将自己注冊給自己的注冊中心(叢集的時候是需要是為true)
register-with-eureka: false
###因為自己是注冊中心, 不需要去檢索服務資訊
fetch-registry: false
server:
# 測試時關閉自我保護機制,保證不可用服務及時踢出
enable-self-preservation: false
eviction-interval-timer-in-ms: 2000 # 踢出執行的線程時間間隔
關閉自我保護機制,用戶端yml 添加配置
# 心跳檢測檢測與續約時間
# 測試時将值設定設定小些,保證服務關閉後注冊中心能及時踢出服務
instance:
###Eureka用戶端向服務端發送心跳的時間間隔,機關為秒(用戶端告訴服務端自己會按照該規則)
lease-renewal-interval-in-seconds: 1
####Eureka服務端在收到最後一次心跳之後等待的時間上限,機關為秒,超過則剔除(用戶端告訴服務端按照此規則等待自己)
lease-expiration-duration-in-seconds: 2
完整如下:
eureka:
client:
service-url:
##### 目前會員服務注冊到eureka服務位址
# defaultZone: http://localhost:8100/eureka,http://localhost:9100/eureka
defaultZone: http://localhost:8100/eureka
### 需要将我的服務注冊到eureka上
register-with-eureka: true
####需要檢索服務
fetch-registry: true
registry-fetch-interval-seconds: 30
# 心跳檢測檢測與續約時間
# 測試時将值設定設定小些,保證服務關閉後注冊中心能及時踢出服務
instance:
###Eureka用戶端向服務端發送心跳的時間間隔,機關為秒(用戶端告訴服務端自己會按照該規則)
lease-renewal-interval-in-seconds: 1
####Eureka服務端在收到最後一次心跳之後等待的時間上限,機關為秒,超過則剔除(用戶端告訴服務端按照此規則等待自己)
lease-expiration-duration-in-seconds: 2
關閉自我保護機制的目的是為了本地開發,
解決項目經常重新啟動,eureka不會自動剔除,及時更新的問題
,
本地開發環境可以開啟 --> 頻繁修改代碼的項目建議開啟
生産環境建議開啟 —>預設開啟)