SpringCloud服務(wù)治理-Eureka

什么是Eureka?

Eureka是Springcloud提供的服務(wù)注冊與發(fā)現(xiàn)組件,它的主要功能是提供一個注冊中心來為各個微服務(wù)之間的相互調(diào)用提供便捷

Eureka的角色組成

Eureka組件包含兩個角色,分別是Eureka Server和Eureka Client。

  • Eureka Server:Client微服務(wù)啟動后,在Eureka Server中進(jìn)行注冊,Eureka Server通過一個注冊表來存儲微服務(wù)的相關(guān)信息
  • Eureka Client:Client微服務(wù)啟動后,向Eureka Server發(fā)送心跳(默認(rèn)為30秒),如果Eureka Server在多個心跳周期內(nèi)(默認(rèn)為90秒)沒有收到該Client發(fā)送的心跳信息,將會在注冊表中剔除該服務(wù),默認(rèn)配置信息如下:
  instance:
    # Eureka客戶端向服務(wù)端發(fā)送心跳的時間間隔,默認(rèn)為30秒
    lease-renewal-interval-in-seconds: 30
    # Eureka客戶端在接收到客戶端最后一次心跳后等待時間(超時將剔除服務(wù))
    lease-expiration-duration-in-seconds: 90

創(chuàng)建Eureka Server服務(wù)

1.在項(xiàng)目中添加依賴

<dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
     <version>2.2.2.RELEASE</version>
</dependency>

2.配置啟動類,在啟動類上添加@EnableEurekaServer注解

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class,args);
    }
}

3.添加yaml配置

server:
  port: 7001
spring:
  application:
    name: eureka-server
eureka:
  instance:
    # eureka服務(wù)端的實(shí)例名稱
    hostname: localhost
  client:
    # false表示不向服務(wù)端注冊自己
    register-with-eureka: false
    # false表示不需要檢索服務(wù),因?yàn)樽约壕褪亲灾行?    fetch-registry: false
    # client端向服務(wù)端發(fā)起注冊的地址
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

4.啟動服務(wù),訪問注冊中心地址,效果如下


image.png

創(chuàng)建Eureka Client服務(wù)

1.在項(xiàng)目中添加依賴

<dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
     <version>2.2.2.RELEASE</version>
</dependency>

2.配置啟動類,在啟動類上添加@EnableEurekaClient注解

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

3.添加yml配置

server:
  port: 7002
spring:
  application:
    name: eureka-client
eureka:
  instance:
    hostname: loclhost
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:7001/eureka/

4.啟動服務(wù),訪問注冊中心地址,效果如下


image.png

可以看到客戶端服務(wù)已經(jīng)注冊成功

自我保護(hù)機(jī)制

在上面的圖示中,我們可以看到有一長串的紅色字體,這表示Eureka開啟了自我保護(hù)機(jī)制

EurekaServer將會嘗試保護(hù)其服務(wù)注冊表中的信息,不再刪除服務(wù)注冊表中的數(shù)據(jù),也就是不會注銷任何服務(wù)

為什么需要自我保護(hù)

因?yàn)槲⒎?wù)是分布部署的,不同的微服務(wù)可能部署在不同的機(jī)器上,如果微服務(wù)本身是正常的,但是由于機(jī)器之間的網(wǎng)絡(luò)故障導(dǎo)致了該服務(wù)與EurakaServer之間不能正常通信,所以當(dāng)EurakaSever節(jié)點(diǎn)在短時間內(nèi)丟失過多的客戶端連接時,就會進(jìn)入自我保護(hù)模式,不會立即剔除服務(wù)
所以,自我保護(hù)機(jī)制實(shí)際上是作用于網(wǎng)絡(luò)容錯的

如何關(guān)閉自我保護(hù)機(jī)制

在EurekaSever的配置中添加如下配置
application.yml

  server:
    # 默認(rèn)開啟了自我保護(hù)機(jī)制,設(shè)置為false表示關(guān)閉
    enable-self-preservation: false
    # 剔除服務(wù)的時間
    eviction-interval-timer-in-ms: 2000

關(guān)閉后效果展示


image.png

說明自我保護(hù)模式已經(jīng)關(guān)閉

Eureka集群

為什么要搭建Eureka集群

搭建Eureka集群的目的是為了實(shí)現(xiàn)負(fù)載均衡和故障容錯,以達(dá)到高可用的效果

如何搭建Eureka集群

集群原理:相互注冊
集群搭建:
1.按照創(chuàng)建Eureka Server服務(wù)的方式創(chuàng)建多個Eureka Server服務(wù)
比如:創(chuàng)建三個EurekaServer服務(wù):EurekaServer-7001、EurekaServer-7002、EurekaServer-7003
2.其余步驟沒有任何變化,只需要更改yml中的Eureka部分的配置即可

EurekaServer-7001的Eureka部分的配置

eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:7002/eureka/,http://localhost:7003/eureka/

EurekaServer-7002的Eureka部分的配置

eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:7001/eureka/,http://localhost:7003/eureka/

EurekaServer-7003的Eureka部分的配置

eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/

啟動上面的三個EurekaServer服務(wù),Eureka集群就已經(jīng)運(yùn)行起來了

其他微服務(wù)注冊到Eureka集群

因?yàn)橐獙⒎?wù)注冊到Eureka集群,所以EurekaClient的地址就必須指向集群的地址
yml中Eureka的地址配置如下:

eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/,http://localhost:7003/eureka/

即同時指定多個EurekaServer的地址,每個地址之間用,分隔

集群的負(fù)載均衡

在Eureka集群搭建的時候,說過Eureka集群能夠?qū)崿F(xiàn)服務(wù)的負(fù)載均衡,那么具體如何實(shí)現(xiàn)呢?
首先要實(shí)現(xiàn)負(fù)載均衡至少需要兩個條件:
1.需要一個集群對外提供服務(wù)
2.需要一種負(fù)載均衡機(jī)制來選擇去集群中的哪一臺機(jī)器上去獲取服務(wù)


集群準(zhǔn)備:
創(chuàng)建一個服務(wù)提供者,并改動端口,啟動多個服務(wù)

image.png

方法如上圖所示,編輯配置項(xiàng)
1.點(diǎn)擊左側(cè)的+,添加一個服務(wù)
2.給服務(wù)區(qū)一個名字,指定主啟動類,添加VM參數(shù)指定端口
3.啟動該服務(wù)
啟動完成后,去注冊中心查看服務(wù)
image.png

可以看到一個服務(wù)名稱對應(yīng)了多個服務(wù)地址
服務(wù)提供者代碼
Application.java

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

ProviderController.java

@RestController
@RequestMapping("provider")
public class ProviderController {
    @Value("${server.port}")
    private String port;
    @GetMapping("port")
    public String getPort(){
        return port;
    }
}

application.yml

server:
  port: 8001
spring:
  application:
    name: sword-provider
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/,http://localhost:7003/eureka/

負(fù)載均衡機(jī)制準(zhǔn)備:
創(chuàng)建一個服務(wù)消費(fèi)者,來消費(fèi)Provider提供的服務(wù)
ConsumerApplication.java

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

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

使用@Bean注解聲明一個RestTemplate的bean,并在該bean上添加了@LoadBalanced注解,該注解默認(rèn)提供了輪詢機(jī)制的負(fù)載均衡算法
ConsumerController.java

@RestController
@RequestMapping("consumer")
public class ConsumerController {
    @Autowired
    private RestTemplate restTemplate;
    private String Url="http://sword-provider";
    @GetMapping("port")
    public String getPort(){
        return restTemplate.getForObject(Url+"/provider/port",String.class);
    }
}

使用template調(diào)用遠(yuǎn)程服務(wù),可以看到遠(yuǎn)程服務(wù)的url地址指向的是Provider的服務(wù)名
application.yml

server:
  port: 9001
spring:
  application:
    name: sword-consumer
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/,http://localhost:7003/eureka/
    register-with-eureka: true
    fetch-registry: true

啟動consumer服務(wù),并訪問接口:http://localhost:9001/consumer/port
多次刷新該接口,可以看到頁面的返回值在8001和8002之間來回切換,說明消費(fèi)者服務(wù)在訪問的服務(wù)提供者的時候,請求了不同的服務(wù)提供者,說明負(fù)載均衡效果達(dá)到

actuator完善服務(wù)信息

actuator的作用主要有兩個:主機(jī)名修改、訪問信息提供ip提示
依賴

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

主機(jī)名修改

在euraka的配置信息中添加instance-id配置

  client:
    service-url:
      defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/,http://localhost:7003/eureka/
    register-with-eureka: true
    fetch-registry: true
  # 添加instance-id配置,以修改注冊信息中顯示的主機(jī)名
  instance:
    instance-id: sword-consumer-9001
image.png

可以看到主機(jī)名稱已經(jīng)改變
通過接口查看微服務(wù)的狀態(tài)


image.png

顯示ip地址提示

  instance:
    instance-id: sword-consumer-9001
    # 添加ip地址顯示
    prefer-ip-address: true
image.png

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

功能:對于注冊進(jìn)注冊中心的微服務(wù),可以通過服務(wù)發(fā)現(xiàn)來獲得該服務(wù)的信息
在服務(wù)提供者微服務(wù)的controller中添加如下代碼:
Controller.java

    @Resource
    private DiscoveryClient discoveryClient;
    @GetMapping("services")
    public List<ServiceInstance> getServices(){
        //獲取服務(wù)名稱列表
        List<String> services = discoveryClient.getServices();
        for (String s:services){
            System.out.println("--item:"+s);
        }
        //獲取服務(wù)實(shí)例信息
        List<ServiceInstance> instances = discoveryClient.getInstances("SWORD-PROVIDER");
        return instances;
    }

在主啟動類上添加@EnableDiscoveryClient注解

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

啟動程序,并訪問http://localhost:8001/provider/services,就可以獲得服務(wù)的相關(guān)信息

image.png

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

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