筆記76 微服務筆記3
SpringCloud基礎概念(一)
一、SpringCloud的幾大組件
- Eureka:註冊中心
- Zuul:網關服務
- Ribbon:負載均衡
- Feign:服務調用
- Hystix:熔斷器
二、微服務場景模擬
1.服務提供者(user-service-demo)
<1>依賴
<2>application.yml
<3>實體類pojo
<4>mapper
<5>service
<6>controller
2.服務調用者(consumer-demo)
<1>依賴,剔除mybatis相關數據庫依賴。
<2>首先在啟動器中註冊RestTemplate用來發送http請求。
1 @Bean 2 public RestTemplate restTemplate() { 3 // 這次我們使用了OkHttp客戶端,只需要註入工廠即可 4 return new RestTemplate(new OkHttp3ClientHttpRequestFactory()); 5 }
<3>編寫DAO,註意,這裏不調用mapper查詢數據庫了,直接通過RestTemplate遠程查詢user-service-demo中的接口。
<4>編寫service,使用DAO請求數據。
<5>編寫controller。
3.存在的問題
-
-
-
consumer需要記憶user-service的地址,如果出現變更,可能得不到通知,地址將失效
-
consumer不清楚user-service的狀態,服務宕機也不知道
-
user-service只有1臺服務,不具備高可用性
-
即便user-service形成集群,consumer還需自己實現負載均衡
-
三、Eureka註冊中心
1.原理圖
-
-
-
提供者:啟動後向Eureka註冊自己信息(地址,提供什麽服務)
-
消費者:向Eureka訂閱服務,Eureka會將對應服務的所有提供者地址列表發送給消費者,並且定期更新
-
心跳(續約):提供者定期通過http方式向Eureka刷新自己的狀態
-
2.基礎架構
-
-
服務註冊中心
Eureka的服務端應用,提供服務註冊和發現功能,就是剛剛我們建立的eureka-demo
-
服務提供者
提供服務的應用,可以是SpringBoot應用,也可以是其它任意技術實現,只要對外提供的是Rest風格服務即可。本例中就是我們實現的user-service-demo
-
服務消費者
消費應用從註冊中心獲取服務列表,從而得知每個服務方的信息,知道去哪裏調用服務方。本例中就是我們實現的consumer-demo
-
3.編寫EurekaServer
<1>編寫啟動類
1 @SpringBootApplication 2 @EnableEurekaServer // 聲明這個應用是一個EurekaServer 3 public class EurekaDemoApplication { 4 5 public static void main(String[] args) { 6 SpringApplication.run(EurekaDemoApplication.class, args); 7 } 8 }
<2>編寫配置
1 server: 2 port: 10086 # 端口 3 spring: 4 application: 5 name: eureka-server # 應用名稱,會在Eureka中顯示 6 eureka: 7 client: 8 register-with-eureka: false # 是否註冊自己的信息到EurekaServer,默認是true 9 fetch-registry: false # 是否拉取其它服務的信息,默認是true 10 service-url: # EurekaServer的地址,現在是自己的地址,如果是集群,需要加上其它Server的地址。 11 defaultZone: http://127.0.0.1:${server.port}/eureka 12 server: 13 eviction-interval-timer-in-ms: 5000 #每隔5秒剔除一次失效的服務 14 enable-self-preservation: false #關閉自我保護
4.將user-service註冊到Eureka
<1>添加SpringCloud依賴
<2>然後再添加Eureak客戶端依賴
<3>
<4>配置信息
1 server: 2 port: 8086 3 mybatis: 4 type-aliases-package: com.liyuanjun.demo.userservicedemo.pojo 5 spring: 6 datasource: 7 url: jdbc:mysql://127.0.0.1:3306/sh?characterEncoding=UTF-8&useSSL=false 8 username: root 9 password: 123456 10 hikari: 11 maximum-pool-size: 20 12 minimum-idle: 10 13 application: 14 name: user-service #服務名字 15 16 eureka: 17 client: 18 service-url: 19 defaultZone: http://127.0.0.1:10086/eureka,http://127.0.0.1:10086/eureka 20 instance: 21 lease-expiration-duration-in-seconds: 10 # 10秒即過期 22 lease-renewal-interval-in-seconds: 5 # 5秒一次心跳 23 instance-id: ${spring.application.name}:${server.port}
4.消費者從Eureka獲取服務
<1>添加SpringCloud依賴
<2>添加Eureka客戶端
<3>在啟動類中開啟Eureka客戶端
<4>修改配置
1 server: 2 port: 8080 3 spring: 4 application: 5 name: consumer # 應用名稱 6 eureka: 7 client: 8 service-url: # EurekaServer地址 9 defaultZone: http://127.0.0.1:10086/eureka 10 instance: 11 prefer-ip-address: true # 當其它服務獲取地址時提供ip而不是hostname 12 ip-address: 127.0.0.1 # 指定自己的ip信息,不指定的話會自己尋找
<5>修改DAO,用DiscoveryClient類的方法,根據服務名稱,獲取服務實例:
1 @Autowired 2 private RestTemplate restTemplate; 3 4 @Autowired 5 private DiscoveryClient discoveryClient;// Eureka客戶端,可以獲取到服務實例信息 6 7 public List<User> queryUserByIds(List<Long> ids) { 8 List<User> users = new ArrayList<>(); 9 // String baseUrl = "http://localhost:8081/user/"; 10 // 根據服務名稱,獲取服務實例 11 List<ServiceInstance> instances = discoveryClient.getInstances("user-service"); 12 // 因為只有一個UserService,因此我們直接get(0)獲取 13 ServiceInstance instance = instances.get(0); 14 // 獲取ip和端口信息 15 String baseUrl = "http://"+instance.getHost() + ":" + instance.getPort()+"/user/"; 16 ids.forEach(id -> { 17 // 我們測試多次查詢, 18 users.add(this.restTemplate.getForObject(baseUrl + id, User.class)); 19 // 每次間隔500毫秒 20 try { 21 Thread.sleep(500); 22 } catch (InterruptedException e) { 23 e.printStackTrace(); 24 } 25 }); 26 return users; 27 }
5.高可用的Eureka Server——集群
1 eureka: 2 instance: 3 lease-expiration-duration-in-seconds: 90 4 lease-renewal-interval-in-seconds: 30
-
-
-
-
lease-expiration-duration-in-seconds:服務失效時間,默認值90秒
-
-
也就是說,默認情況下每個30秒服務會向註冊中心發送一次心跳,證明自己還活著。如果超過90秒沒有發送心跳,EurekaServer就會認為該服務宕機,會從服務列表中移除,可以根據實際情況進行調整。
1 eureka: 2 client: 3 registry-fetch-interval-seconds: 5
8.失效剔除和自我保護
<1>失效剔除
可以通過eureka.server.eviction-interval-timer-in-ms
參數對其進行修改,單位是毫秒。
<2>自我保護
關停一個服務,就會在Eureka面板看到一條警告:
這是觸發了Eureka的自我保護機制。當一個服務未按時進行心跳續約時,Eureka會統計最近15分鐘心跳失敗的服務實例的比例是否超過了85%。在生產環境下,因為網絡延遲等原因,心跳失敗實例的比例很有可能超標,但是此時就把服務剔除列表並不妥當,因為服務可能沒有宕機。Eureka就會把當前實例的註冊信息保護起來,不予剔除。生產環境下這很有效,保證了大多數服務依然可用。
但是這給我們的開發帶來了麻煩, 因此開發階段我們都會關閉自我保護模式:
1 eureka: 2 server: 3 enable-self-preservation: false # 關閉自我保護模式(缺省為打開) 4 eviction-interval-timer-in-ms: 1000 # 掃描失效服務的間隔時間(缺省為60*1000ms)
筆記76 微服務筆記3