Spring Cloud Eureka

服務(wù)發(fā)現(xiàn)

  • 談到服務(wù)發(fā)現(xiàn),阿里得Dubbo經(jīng)典架構(gòu)圖如下:
  • 服務(wù)治理,發(fā)現(xiàn)Spring Cloud Eureka

  • 1 首先在pom.xml中引入對(duì)應(yīng)依賴

  • 2 在主入口Application類中加入@EnableEurekaServer注解

  • 3 在配置文件中對(duì)服務(wù)中心進(jìn)行配置

  • 4 運(yùn)行程序體驗(yàn)Eureka服務(wù)發(fā)現(xiàn)

  • 創(chuàng)建spring-cloud-01-eureka-a項(xiàng)目 pom中引入依賴

<dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
  • 在主入口配置 @EnableEurekaServer注解
@EnableEurekaServer //啟用服務(wù)器的配置中心
@SpringBootApplication
public class EurekaApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaApplication.class, args);
    }
}
  • 在application.properties中配置
server.port=1000
eureka.client.service-url.defaultZone=http://eureka2:1000/eureka/
eureka.instance.hostname=eureka1
#客戶端向服務(wù)器(注冊(cè)中心發(fā)送心跳得時(shí)間間隔)
eureka.instance.lease-renewal-interval-in-seconds=10  
#服務(wù)器(注冊(cè)中心)租期到期的時(shí)間, 也就是說(shuō)服務(wù)器在收到最后一次心跳的時(shí)間上線
eureka.instance.lease-expiration-duration-in-seconds=120
  • 訪問(wèn)地址 localhost:1000 如圖
Eureka.png

服務(wù)提供者 Provider

  • 實(shí)現(xiàn)了服務(wù)發(fā)現(xiàn)注冊(cè)中心,接下來(lái)需要把自己得應(yīng)用服務(wù)注冊(cè)到SpringCloud Eureka注冊(cè)中心上
    1. 對(duì)pom.xml進(jìn)行配置
    1. 在主入口Application類中加入@EnableDiscoveryClient注解
  • 3 在配置文件中對(duì)服務(wù)中心進(jìn)行配置
  • 4 最后先運(yùn)行Eureka服務(wù),在運(yùn)行Provider服務(wù)提供者。然后觀察Eureka信息
  • 創(chuàng)建spring-cloud-01-provider項(xiàng)目 pom中引入依賴
<dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
</dependencies>
  • 在主入口配置 @EnableDiscoveryClient注解
@EnableDiscoveryClient    
@SpringBootApplication
public class ProviderApplication {

    public static void main(String[] args) {
        SpringApplication.run(ProviderApplication.class, args);
    }
}
  • 在application.properties中配置
spring.application.name=provider-service
server.context-path=/provider
server.port=2001
eureka.client.service-url.defaultZone=http://eureka1:1000/eureka/
  • 創(chuàng)建IndexController類給consumer端調(diào)用
@RestController
public class IndexController {


    @RequestMapping(value = "/hello",method = {RequestMethod.GET})
    public String hello(){
        return "hello world";
    }
}

服務(wù)消費(fèi)者 consumer

  • consumer和Provider 配置一樣
  • 將consumer端也注冊(cè)到服務(wù)中心
  • 主入口
@EnableDiscoveryClient
@SpringBootApplication
public class ConsumerApplication {

    @Bean
    @LoadBalanced //自動(dòng)負(fù)載均衡 機(jī)制是通過(guò) application name 去尋找服務(wù)發(fā)現(xiàn) 然后去做負(fù)載均衡
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }
}
@RestController
public class IndexController {

    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping(value = "/getAppNameUrl", method = {RequestMethod.GET})
    public String getApplicationNameUrl(){
         ResponseEntity<String> response  = restTemplate.getForEntity("http://provider-service/provider/hello",String.class);
        System.err.println("body:" + response.getBody());
        return "調(diào)用成功";
    }

    @RequestMapping(value = "/getUrl", method = {RequestMethod.GET})
    public String getUrl() {
        RestTemplate rest = new RestTemplate();
        ResponseEntity<String> response = rest.getForEntity("http://localhost:2001/provider/hello", String.class);
        System.err.println("body:" + response.getBody());
        return "調(diào)用成功";
    }
}
  • 啟動(dòng)consumer端
 http://localhost:2000/consumer/getUrl 調(diào)用P端服務(wù)是通過(guò)路徑調(diào)用得
 http://localhost:2000/consumer/getAppNameUrl 是通過(guò)P 端得application name調(diào)用得

高可用Eureka服務(wù)注冊(cè)中心

 在微服務(wù)架構(gòu)環(huán)境中,一個(gè)非常關(guān)鍵部分就是高可用性,需要充分考慮發(fā)生故障得路徑,必須對(duì)
 各個(gè)組件進(jìn)行高可用,只需要建立兩個(gè)Eureka服務(wù),把兩個(gè)注冊(cè)中心地址相互配置到對(duì)方地址即可。
 在P、C端加上eureka.client.service-url.defaultZone=http://eureka1:1000/eureka/,http://eureka2:1001/eureka/
 當(dāng)一個(gè)服務(wù)中心宕掉,還可以訪問(wèn)

服務(wù)發(fā)現(xiàn)注冊(cè)機(jī)制

  • 服務(wù)注冊(cè):服務(wù)提供者在啟動(dòng)時(shí)會(huì)通過(guò)發(fā)送REST請(qǐng)求得方式將自己注冊(cè)到Eureka服務(wù)器上,同時(shí)帶上了自身服務(wù)得一些元素信息。Eureka收到這個(gè)Rest請(qǐng)求后,將數(shù)據(jù)信息存儲(chǔ)在一個(gè)雙層結(jié)構(gòu)Map中,其中一層得Key是服務(wù)名,第二層得Key是具體服務(wù)實(shí)例名。

  • 服務(wù)同步: 如果所示:這兩個(gè)服務(wù)提供者分別注冊(cè)到了兩個(gè)不同得注冊(cè)中心上,他們得信息分別被兩個(gè)服務(wù)注冊(cè)中心所維護(hù),此時(shí)由于服務(wù)注冊(cè)中心之間因?yàn)榛ハ嘧?cè)服務(wù)得關(guān)系,當(dāng)服務(wù)提供者發(fā)送注冊(cè)請(qǐng)求到一個(gè)服務(wù)注冊(cè)中心得時(shí)候,它會(huì)將該請(qǐng)求轉(zhuǎn)發(fā)給集群得其他注冊(cè)中心,從而實(shí)現(xiàn)注冊(cè)中心之間得服務(wù)同步過(guò)程。通過(guò)服務(wù)同步,兩個(gè)服務(wù)提供者得服務(wù)信息就可以通過(guò)這兩臺(tái)服務(wù)注冊(cè)中心得任意一臺(tái)獲取到。

  • 服務(wù)續(xù)約: 服務(wù)注冊(cè)完成后,服務(wù)提供者會(huì)維護(hù)一個(gè)心跳來(lái)持續(xù)告訴注冊(cè)中心“我還活者”防止注冊(cè)中心“剔除該服務(wù)”也就是將服務(wù)列表排除出去。

  • 服務(wù)調(diào)用:消費(fèi)者獲得清單后,通過(guò)服務(wù)名可以獲得具體提供服務(wù)得實(shí)例名和改實(shí)例得元數(shù)據(jù)信息,因?yàn)橛羞@些服務(wù)實(shí)例得詳細(xì)信息,所以客戶端可以根據(jù)自己得需要決定調(diào)用哪個(gè)實(shí)例,在Ribbon中會(huì)默認(rèn)采用輪詢得方式進(jìn)行服務(wù)調(diào)用,從而實(shí)現(xiàn)負(fù)載均衡。

  • 服務(wù)下線:在系統(tǒng)運(yùn)行中必然會(huì)出現(xiàn)關(guān)閉或重啟某個(gè)實(shí)例得情況,在關(guān)閉服務(wù)期間,我們自然不希望調(diào)用到已經(jīng)下線得服務(wù)實(shí)例,所以客戶端程序中,當(dāng)服務(wù)實(shí)例正常關(guān)閉操作時(shí),它會(huì)出發(fā)一個(gè)服務(wù)下線得Rest請(qǐng)求給Eureka,通知其下線,當(dāng)然注冊(cè)中心收到該請(qǐng)求后,會(huì)出發(fā)一個(gè)服務(wù)下先得Rest請(qǐng)求給Eureka,通知其下線,當(dāng)然注冊(cè)中心收到該請(qǐng)求后把其服務(wù)列表狀態(tài)改為下線,并把該時(shí)間傳播給齊群其他節(jié)點(diǎn)。當(dāng)出現(xiàn)非正常下線時(shí),注冊(cè)中心可能并沒(méi)有收到正常得下線通知請(qǐng)求,而這種情況,我們得Eureka自己會(huì)有一個(gè)內(nèi)部得定時(shí)任務(wù),每隔一段時(shí)間定時(shí)檢查超時(shí)得清單進(jìn)行剔除。

  • 最后Eureka其實(shí)沒(méi)有Provider Consumer 之分,可以當(dāng)P端 也可以當(dāng)C端。兩者可以互相調(diào)用。

下節(jié)Ribbon

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容