SpringCloud基礎概念(一)mysql
1、SpringCloud的幾大組件spring
2、微服務場景模擬sql
1.服務提供者(user-service-demo)數據庫
<1>依賴緩存
<2>application.yml網絡
<3>實體類pojomybatis
<4>mapper架構
<5>serviceapp
<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還需本身實現負載均衡
3、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)