文章目錄
- Eureka應用入門
- 一:沒有使用注冊中心搭建的分布式應用
-
- **1)服務消費者(user服務) & 提供者(order服務)**
- **2)如下圖**
- **3)服務發現原理初探**
- 二:Eureka入門
-
- **1)搭建eureka服務端**
- **2) 搭建eureka用戶端**
- 三: Eureka 部署架構
-
- 1) Eureka架構圖
- 2) Eureka配置的總要資訊講解
-
- ①: 服務注冊配置
- ②: 服務續約配置
- ③: 擷取服務配置 (前提,**eureka.client.fetch-registry為true**)
- ④: eureka 的自我保護功能
- ⑤: eureka 的高可用搭建
- ⑥: 安全配置
Eureka應用入門
一:沒有使用注冊中心搭建的分布式應用
1)服務消費者(user服務) & 提供者(order服務)
名詞 | 定義 |
---|---|
服務提供者 | 服務的被調用方(即:為其他服務提供服務的服務) |
服務消費者 | 服務的被調用方(即:以來其他服務的服務) |
2)如下圖
就是用發發起一個請求,通過使用者Id查詢到該使用者下的所有訂單資訊
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5GcuUDMwADMwYjN5EzMllzY2EmMzIzMilzY18CXzV2Zh1WavwVMBVSQ4USNFVCR4UyQ5UiNFVSRBVSRCVSNFVyLcJXZ0NXYt9CX3FmcvwFZ19Gbj9VZ09mbvwVZzlGdhJHcvwVbvNmLlVGdpd2Lc9CX6MHc0RHaiojIsJye.png)
比如現在我的使用者服務是占用(User服務)8081端口的服務, 此時我的服務提供方(order服務端口是8080)端口
我們可以通過RestTemplate 調用方式來進行調用
**//在使用者服務中調用 訂單服務**
ResponseEntity<List> responseEntity = restTemplate.getForEntity("http://localhost:8080/order/queryOrdersByUserId/"+userId,List.class);
缺點:
1)從上面看出的缺點就是,我們的在調用的時候,請求的Ip位址和端口是寫死的.
若此時,服務提供方(order)服務部署的機器換了端口或者是更換了部署機器的Ip,那麼我們需要修改代碼重新釋出部署.
2) 假設我們的order服務壓力過大,我們需要把order服務作為叢集,那麼意味着 order是多節點部署
比如原來的,我們隻有一台伺服器,現在有多台伺服器,那麼作為運維人員 需要在服務消費方進行手工維護一份系統資料庫(容易出錯)
3)有人馬上回駁我說,我可以通過ng來做負載均衡,對,我首先認為這是可行的,當時微服務成百上千的服務,難道我們要那成百上千
ng麼?或者使用一個Ng 那麼我們能想一下哪個ng的配置檔案有多麼複雜。
3)服務發現原理初探
其實,服務發現機制非常簡單,不妨用大家熟悉的MySQL(也可以用redis來做存儲)來類比——隻需一張表(圖中的registry表)即可實作服務發現
- 應用啟動時,自動往registry表中插入一條資料,資料包括服務名稱、IP、端口等資訊。
- 應用停止時,自動把自己在registry表中的資料的status設為
。DOWN
- 服務調用,每次調用前,去mysql中去查詢 select * from register where server_name=‘服務名稱’ and status='UP’的記錄,然後替換原來的調用路徑位址
缺點: 上面這個畢竟是一個很簡陋的服務注冊中心
缺點1: 若目前服務當機,我們必須要把自己的對應的資料标記為down
缺點2:服務每次調用都要發送select 語句,mysql的壓力很大
缺點3:若mysql(服務注冊中心挂了,我們也應該提供服務調用)
真正的服務注冊發現元件應該滿足哪些條件才稱為一個合格的服務發現注冊元件
1) 提供一個服務注冊接口,其他微服務啟動的時候,把自己的IP,端口都在服務端注冊下來
2) 提供一個服務發現接口,也就是微服務可以通過service_id 來擷取到 對應微服務的網絡位址和端口
3) 各個微服務與服務注冊元件,使用心跳檢查機制,若服務注冊元件長時間和某微服務 沒有通信,那麼就應該剔除服務
4) 用戶端緩存,各個微服務将需要調用服務的位址緩存在本地,并使用一定機制更新(例如定時任務更新、事件推送更新等)。這樣既能降低服務發現元件的壓力,同 時,即使服務發現元件出問題,也不會影響到服務之間的調用
...................................................................
二:Eureka入門
** eureka分為服務端和用戶端**
1)搭建eureka服務端
三闆斧:
①加依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency
②:寫注解 在主啟動類上 寫上@EnableEurekaServer注解
@EnableEurekaServer
public class EurekaServerApplication {
}
③:編寫配置檔案
#eureka服務端應用的端口預設是8761
server.port=9000
#表示是否将自己注冊到Eureka Server,預設為true,由于目前應用就是Eureka Server,故而設為false
eureka.client.register-with-eureka=false
# 表示是否從Eureka Server擷取注冊資訊,預設為true,因為這是一個單點的Eureka Server,不需要同步其他的Eureka Server節點的資料,故而設為false
eureka.client.fetch-registry=false
#暴露給其他eureka client 的注冊位址
eureka.client.service-url.defaultZone: http://localhost:9000/eureka/
2) 搭建eureka用戶端
服務消費者 ms-consumer-user-8001
①:加依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
②:加入注解@EnableDiscoveryClient
@EnableDiscoveryClient
public class EurekaClientApplication {
}
③:編寫配置檔案
server.port=8001
#注冊到eureka服務端的微服務名稱
spring.application.name=ms-consumer-user
#注冊到eureka服務端的位址
eureka.client.service-url.defaultZone=http://localhost:9000/eureka/
#點選具體的微服務,右下角是否顯示ip
eureka.instance.prefer-ip-address=true
#顯示微服務的名稱
eureka.instance.instance-id=ms-consumer-user-8001
mybatis.configuration.map-underscore-to-camel-case=true
#配置資料庫
spring.datasource.url=jdbc:mysql://localhost:3306/rebirth
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root
logging.level.com.tuling.dao=debug
④: 調用 使用RestTemplate (調用的時候不再是通過Ip 和位址發起調用,而是通過微服務名稱進行調用
需要加入@LoadBanlance 注解
@RequestMapping("/queryUserInfoById/{userId}")
public UserInfoVo queryUserInfoById(@PathVariable("userId") Integer userId) {
User user = userServiceImpl.queryUserById(userId);
ResponseEntity<List> responseEntity = restTemplate.getForEntity("http://MS-PROVIDER-ORDER/order/queryOrdersByUserId/"+userId,List.class);
List<OrderVo> orderVoList = responseEntity.getBody();
UserInfoVo userInfoVo = new UserInfoVo();
userInfoVo.setOrderVoList(orderVoList);
userInfoVo.setUserName(user.getUserName());
return userInfoVo;
}
@Configuration
public class MainConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
三: Eureka 部署架構
1) Eureka架構圖
首先,大家看到這個圖 腦瓜子是不是嗡嗡嗡的?什麼鬼 us-east-1c us-east-1d us-east-1e是什麼東西??
我們首先需要了解一下 aws(amazon web service) 可以類比中國的阿裡雲伺服器.
Region(us-east-1,) 可以類比于 阿裡雲的不同區域,我們在買阿裡雲伺服器的時候,是不是需要你選擇區域麼?各個Region 之間的内網是不相通的
Availabitlity zone 可用區(us-east-1c us-east-1d us-east-1e) 可以了解為 我們 一個地區比如華南地區,不同城市的機房,内網是相通的
**比如華南1 華東1 2 ,華北12345 **
- Eureka Server提供服務發現的能力,各個微服務啟動時,會向Eureka Server注冊自己的資訊(例如IP、端口、微服務名稱等),Eureka Server會存儲這些資訊;
- Eureka Client是一個Java用戶端,用于簡化與Eureka Server的互動(啟動的時候,會向server注冊自己的資訊)
- 微服務啟動後 renew,會周期性(預設30秒)地向Eureka Server發送心跳以續約自己的“租期”;
- 如果Eureka Server在一定時間内沒有接收到某個微服務執行個體的心跳(最後一次續約時間開始計算),Eureka Server将會登出該執行個體(預設90秒);
- 預設情況下,Eureka Server同時也是Eureka Client。多個Eureka Server執行個體,互相之間通過增量複制的方式,來實作服務系統資料庫中資料的同步。Eureka Server預設保證在90秒内,Eureka Server叢集内的所有執行個體中的資料達到一緻(從這個架構來看,Eureka Server所有執行個體所處的角色都是對等的,沒有類似Zookeeper、選舉過程,也不存在主從,所有的節點都是主節點。Eureka官方将Eureka Server叢集中的所有執行個體稱為“對等體(peer)”)
- Eureka Client會緩存服務系統資料庫中的資訊。這種方式有一定的優勢——首先,微服務無需每次請求都查詢Eureka Server,進而降低了Eureka Server的壓力;其次,即使Eureka Server所有節點都宕掉,服務消費者依然可以使用緩存中的資訊找到服務提供者并完成調用
2) Eureka配置的總要資訊講解
①: 服務注冊配置
eureka.client.register-with-eureka=true
該項配置說明,是否向注冊中心注冊自己,在非叢集環境下設定為false,表示自己不注冊自己
eureka.client.fetch-registry=true
該項配置說明,注冊中心隻要維護微服務執行個體清單,非叢集環境下,不需要作檢索服務,所有也設定為false
②: 服務續約配置
eureka.instance.lease-renewal-interval-in-seconds=30(預設)
該配置說明,服務提供者會維持一個心跳告訴eureka server 我還活着,這個就是一個心跳周期
eureka.instance.lease-expiration-duration-in-seconds=90(預設)
該配置說明,你的最後一次續約時間開始,往後推90s 還沒接受到你的心跳,那麼我就需要把你剔除.
③: 擷取服務配置 (前提,eureka.client.fetch-registry為true)
eureka.client.registry-fetch-interval-seconds=30
緩存在調用方的微服務執行個體清單重新整理時間
④: eureka 的自我保護功能
預設情況下,若eureka server 在一段時間内(90s)沒有接受到某個微服務執行個體的心跳,那麼eureka server 就會剔除
該執行個體,當時由于網絡分區故障,導緻eureka server 和 服務之間無法通信,此時這個情況就變得很可怕—因為微服務是執行個體健康的
,本不應登出該執行個體.
那麼通過eureka server 自我保護模式就起作用了,當eureka server節點短時間(15min是否低于85%)丢失過多用戶端是(由于網絡分區),那麼該eureka server節點就會進入自我保護模式,eureka server 就會自動保護系統資料庫中的微服務執行個體,不再删除該系統資料庫中微服務的資訊,等到網絡恢複,eureka server 節點就會退出自我保護功能(甯可放過一千,不要錯殺一個)
⑤: eureka 的高可用搭建
啟動二個eureka server 9000端口 和9001端口
5.1) 9000 端口的工程配置
server.port=9000
#表示是否将自己注冊到Eureka Server 表示9000的服務端需要向9001工程注冊自己
eureka.client.register-with-eureka=true
# 表示是否從Eureka Server擷取注冊資訊,預設為true,需要從9001上同步資料
eureka.client.fetch-registry=true
講自己注冊到9001上去
eureka.client.service-url.defaultZone: http://www.eureka9001.com:9001/eureka/
5.2) 9001端口配置
server.port=9001
#表示是否将自己注冊到Eureka Server 表示9001的服務端需要向9000工程注冊自己
eureka.client.register-with-eureka=true
# 表示是否從Eureka Server擷取注冊資訊,預設為true,需要從9000上同步資料
eureka.client.fetch-registry=true
講自己注冊到9000上去
eureka.client.service-url.defaultZone: http://www.eureka9000.com:9000/eureka/
5.3) 微服務提供者配置,需要向二個注冊中心進行注冊
eureka.client.service-url.defaultZone=http://www.eureka9000.com:9000/eureka/,http://www.eureka9001.com:9001/eureka/
5.4)截圖
⑥: 安全配置
我們現在通路eureka server 直接通路 沒有授權
6.1)導入安全配置 依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
6.2)修改yml配置檔案
//注冊的時候需要帶入 使用者名 密碼 基本格式為 http:使用者名:密碼@ip:端口/eureka/
eureka.client.service-url.defaultZone: http://${spring.security.user.name}:${spring.security.user.name}@www.eureka9000.com:9000/eureka/
//開啟預設的認真
spring.security.basic.enable=true
spring.security.user.name=root
spring.security.user.password=123456
===============================================================用戶端配置
注冊位址修改為這個
eureka.client.service-url.defaultZone=http://${security.login.username}:${security.login.pass}@www.eureka9000.com:9000/eureka/