筆記76 微服務筆記3

SpringCloud基礎概念(一)mysql

1、SpringCloud的幾大組件spring

  • Eureka:註冊中心
  • Zuul:網關服務
  • Ribbon:負載均衡
  • Feign:服務調用
  • Hystix:熔斷器

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中,咱們把url地址硬編碼到了代碼中,不方便後期維護

    • consumer須要記憶user-service的地址,若是出現變動,可能得不到通知,地址將失效

    • consumer不清楚user-service的狀態,服務宕機也不知道

    • user-service只有1臺服務,不具有高可用性

    • 即使user-service造成集羣,consumer還需本身實現負載均衡

3、Eureka註冊中心

1.原理圖

    • Eureka:就是服務註冊中心(能夠是一個集羣),對外暴露本身的地址

    • 提供者:啓動後向Eureka註冊本身信息(地址,提供什麼服務)

    • 消費者:向Eureka訂閱服務,Eureka會將對應服務的全部提供者地址列表發送給消費者,而且按期更新

    • 心跳(續約):提供者按期經過http方式向Eureka刷新本身的狀態

2.基礎架構

Eureka架構中的三個核心角色:

    • 服務註冊中心

      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>經過添加@EnableDiscoveryClient來開啓Eureka客戶端功能

<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——集羣

  多個Eureka Server之間也會互相註冊爲服務,當服務提供者註冊到Eureka Server集羣中的某個節點時,該節點會把服務的信息同步給集羣中的每一個節點,從而實現數據同步。所以,不管客戶端訪問到Eureka Server集羣中的任意一個節點,均可以獲取到完整的服務列表信息。

6.服務提供者

  服務提供者要向EurekaServer註冊服務,而且完成服務續約等工做。

<1>服務註冊

  服務提供者在啓動時,會檢測配置屬性中的:eureka.client.register-with-erueka=true參數是否正確,事實上默認就是true。若是值確實爲true,則會向EurekaServer發起一個Rest請求,並攜帶本身的元數據信息,Eureka Server會把這些信息保存到一個雙層Map結構中。第一層Map的Key就是服務名稱,第二層Map的key是服務的實例id。

<2>服務續約

  在註冊服務完成之後,服務提供者會維持一個心跳(定時向EurekaServer發起Rest請求),告訴EurekaServer:「我還活着」。這個咱們稱爲服務的續約(renew)。

有兩個重要參數能夠修改服務續約的行爲:

1 eureka:
2   instance:
3     lease-expiration-duration-in-seconds: 90
4     lease-renewal-interval-in-seconds: 30
      • lease-renewal-interval-in-seconds:服務續約(renew)的間隔,默認爲30秒

      • lease-expiration-duration-in-seconds:服務失效時間,默認值90秒

  也就是說,默認狀況下每一個30秒服務會向註冊中心發送一次心跳,證實本身還活着。若是超過90秒沒有發送心跳,EurekaServer就會認爲該服務宕機,會從服務列表中移除,能夠根據實際狀況進行調整。

7.服務消費者

<1>獲取服務列表

當服務消費者啓動是,會檢測eureka.client.fetch-registry=true參數的值,若是爲true,則會從Eureka Server服務的列表只讀備份,而後緩存在本地。而且每隔30秒會從新獲取並更新數據。咱們能夠經過下面的參數來修改: 

1 eureka:
2   client:
3     registry-fetch-interval-seconds: 5

8.失效剔除和自我保護

<1>失效剔除

  有些時候,咱們的服務提供方並不必定會正常下線,可能由於內存溢出、網絡故障等緣由致使服務沒法正常工做。Eureka Server須要將這樣的服務剔除出服務列表。所以它會開啓一個定時任務,每隔60秒對全部失效的服務(超過90秒未響應)進行剔除。能夠經過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)
相關文章
相關標籤/搜索