《springcloud 一》搭建註冊中心,服務提供者,服務消費者

x號開發者發表於2019-04-09

註冊中心環境搭建

Maven依賴資訊  

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
    </parent>
    <!-- 管理依賴 -->
    <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>

application.yml

###服務埠號
server:
  port: 8100
###eureka 基本資訊配置
eureka:
  instance:
    ###註冊到eurekaip地址
    hostname: 127.0.0.1
  client:
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
###因為自己是為註冊中心,不需要自己註冊自己
    register-with-eureka: false
###因為自己是為註冊中心,不需要檢索服務
    fetch-registry: false

啟動Eureka服務

@EnableEurekaServer
@SpringBootApplication
public class AppEureka {

    public static void main(String[] args) {
        SpringApplication.run(AppEureka.class, args);
    }

}

 

註冊服務提供者

Maven依賴資訊

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
    </parent>
    <!-- 管理依賴 -->
    <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>

application.yml

###服務啟動埠號
server:
  port: 8000
###服務名稱(服務註冊到eureka名稱)  
spring:
    application:
        name: app-itmayiedu-member
###服務註冊到eureka地址
eureka:
  client:
    service-url:
           defaultZone: http://localhost:8100/eureka

           
###因為該應用為註冊中心,不會註冊自己
    register-with-eureka: true
###是否需要從eureka上獲取註冊資訊
    fetch-registry: true

服務介面

@RestController
public class MemberController {

    @RequestMapping("/getMember")
    public String getMember() {
        return "this is getMember";
    }
}

啟動會員服務

@SpringBootApplication
@EnableEurekaClient
public class AppMember {

    public static void main(String[] args) {
        SpringApplication.run(AppMember.class, args);
    }

}

 

服務消費者

Maven依賴資訊

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
    </parent>
    <!-- 管理依賴 -->
    <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>

Application.yml配置

###服務啟動埠號
server:
  port: 8001
###服務名稱(服務註冊到eureka名稱)  
spring:
    application:
        name: app-itmayiedu-order
###服務註冊到eureka地址
eureka:
  client:
    service-url:
           defaultZone: http://localhost:8100/eureka

           
###因為該應用為註冊中心,不會註冊自己
    register-with-eureka: true
###是否需要從eureka上獲取註冊資訊
    fetch-registry: true

使用rest方式呼叫服務

@RestController
public class OrderController {
    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping("/getorder")
    public String getOrder() {
        // order 使用rpc 遠端呼叫技術 呼叫 會員服務
        String memberUrl = "http://app-itmayiedu-member/getMember";
        String result = restTemplate.getForObject(memberUrl, String.class);
        System.out.println("會員服務呼叫訂單服務,result:" + result);
        return result;
    }

}

 

啟動消費者服務

@SpringBootApplication
@EnableEurekaClient
public class AppOrder {

    public static void main(String[] args) {
        SpringApplication.run(AppOrder.class, args);
    }

    @Bean
    @LoadBalanced
    RestTemplate restTemplate() {
        return new RestTemplate();
    }

}

 

@LoadBalanced就能讓這個RestTemplate在請求時擁有客戶端負載均衡的能力

 

高可用註冊中心

 

在微服務中,註冊中心非常核心,可以實現服務治理,如果一旦註冊出現故障的時候,可能會導致整個微服務無法訪問,在這時候就需要對註冊中心實現高可用叢集模式。

 

Eureka高可用原理

 

預設情況下Eureka是讓服務註冊中心,不註冊自己

###註冊自己
    register-with-eureka: true
###需要去註冊中心上檢索服務
    fetch-registry: true

Eureka高可用實際上將自己作為服務向其他服務註冊中心註冊自己,這樣就可以形成一組相互註冊的服務註冊中心,從而實現服務清單的互相同步,達到高可用效果。

 

客戶端整合Eureka叢集

server:
  port: 8000
spring:
  application:
    name: app-itmayiedu-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

Eureka詳解

 

服務消費者模式

 

獲取服務

 消費者啟動的時候,使用服務別名,會傳送一個rest請求到服務註冊中心獲取對應的服務資訊,讓後會快取到本地jvm客戶端中,同時客戶端每隔30秒從伺服器上更新一次。

可以通過 fetch-inte vall-seconds=30引數進行修以通過eureka.client .registry該引數預設值為30 單位為秒。

 

 

 

服務下線

    在系統執行過程中必然會面臨關閉或重啟服務的某個例項的情況,在服務關閉期有我們自然不希望客戶端會繼續呼叫關閉了的例項。所以在客戶端程式中,當服務例項過正常的關閉操作時,它會觸發一個服務下線的REST請求給Eureka Server, 告訴服務日中心:“我要下線了”。服務端在接收到請求之後,將該服務狀態置為下線(DOWN),井該下線事件傳播出去。

 

服務註冊模式

 失效剔除

 有些時候,我們的服務例項並不一定會正常下線,可能由於記憶體溢位、網路故障氣因使得服務不能正常工作,而服務註冊中心並未收到“服務下線”的請求。為了從服務表中將這些無法提供服務的例項剔除,Eureka Server 在啟動的時候會建立一個定時任多預設每隔一一段時間(預設為60)將當前清單中超時(預設為90)沒有續約的服務除出去

 自我保護

 

 

預設情況下,EurekaClient會定時向EurekaServer端傳送心跳,如果EurekaServer在一定時間內沒有收到EurekaClient傳送的心跳,便會把該例項從註冊服務列表中剔除(預設是90秒),但是在短時間內丟失大量的例項心跳,這時候EurekaServer會開啟自我保護機制,Eureka不會踢出該服務。

 

產生的原因:

 

在開發測試時,需要頻繁地重啟微服務例項,但是我們很少會把eureka server一起重啟(因為在開發過程中不會修改eureka註冊中心),當一分鐘內收到的心跳數大量減少時,會觸發該保護機制。可以在eureka管理介面看到Renews thresholdRenews(last min),當後者(最後一分鐘收到的心跳數)小於前者(心跳閾值)的時候,觸發保護機制,會出現紅色的警告:

 

EMERGENCY!EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT.RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEGING EXPIRED JUST TO BE SAFE.

 

從警告中可以看到,eureka認為雖然收不到例項的心跳,但它認為例項還是健康的,eureka會保護這些例項,不會把它們從登錄檔中刪掉。

該保護機制的目的是避免網路連線故障,在發生網路故障時,微服務和註冊中心之間無法正常通訊,但服務本身是健康的,不應該登出該服務,如果eureka因網路故障而把微服務誤刪了,那即使網路恢復了,該微服務也不會重新註冊到eureka server了,因為只有在微服務啟動的時候才會發起註冊請求,後面只會傳送心跳和服務列表請求,這樣的話,該例項雖然是執行著,但永遠不會被其它服務所感知。所以,eureka server在短時間內丟失過多的客戶端心跳時,會進入自我保護模式,該模式下,eureka會保護登錄檔中的資訊,不在登出任何微服務,當網路故障恢復後,eureka會自動退出保護模式。自我保護模式可以讓叢集更加健壯。

但是我們在開發測試階段,需要頻繁地重啟發布,如果觸發了保護機制,則舊的服務例項沒有被刪除,這時請求有可能跑到舊的例項中,而該例項已經關閉了,這就導致請求錯誤,影響開發測試。所以,在開發測試階段,我們可以把自我保護模式關閉,只需在eureka server配置檔案中加上如下配置即可:

 

 

 

但在生產環境,不會頻繁重啟,所以,一定要把自我保護機制開啟,否則網路一旦終端,就無法恢復。

當然關於自我保護還有很多個性化配置,這裡不詳細說明。

 

注意考慮網路不可達情況下:呼叫介面冪等、重試、補償等。

 

 

關閉服務保護

 

Eureka伺服器端配置
###服務埠號
server:
  port: 8100
##定義服務名稱
spring:
  application:
    name: app-itmayiedu-eureka
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
Eureka客戶端配置
###訂單服務的埠號
server:
  port: 8001
###服務別名----服務註冊到註冊中心名稱 
spring:
  application:
    name: app-itmayiedu-order
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    

 

宣告式服務呼叫SpringCloud Feign             主流

feign介紹

Feign客戶端是一個web宣告式http遠端呼叫工具,提供了介面和註解方式進行呼叫。

 

 

環境搭建

 

Maven依賴資訊

    <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

feign客戶端介面

// name 指定服務名稱
@FeignClient(name = "app-itmayiedu-member")
public interface MemberApifeign {

    @RequestMapping("/getMember")
    public String getMember();

}

controller

    @Autowired
    private MemberApifeign memberApifeign;

    @RequestMapping("/feignMember")
    public String feignMember() {
        return memberApifeign.getMember();
    }

專案啟動加上@EnableFeignClients

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class AppOrder {
    public static void main(String[] args) {
        SpringApplication.run(AppOrder.class, args);

}

Ribbon配置

 

SpringCloud Feign客戶端Http呼叫工具,預設已經整合了Ribbon負載均衡客戶端。

 

 

配置Feign客戶端超時時間

###設定feign客戶端超時時間
ribbon:
###指的是建立連線所用的時間,適用於網路狀況正常的情況下,兩端連線所用的時間。
 ReadTimeout: 5000
###指的是建立連線後從伺服器讀取到可用資源所用的時間。 
 ConnectTimeout: 5000

 

 

@RestController

publicclass OrderController {

      @Autowired

      private RestTemplate restTemplate;

 

      @RequestMapping("/getorder")

      public String getOrder() {

           // order 使用rpc遠端呼叫技術 呼叫 會員服務

           String memberUrl = "http://app-itmayiedu-member/getMember";

           String result = restTemplate.getForObject(memberUrl, String.class);

           System.out.println("會員服務呼叫訂單服務,result:" + result);

           returnresult;

      }

 

}

 

 

相關文章