同一個服務部署了多個執行個體,在通過網關調用時會随機調用其中一個。但是,當某個服務挂掉之後,依然在注冊中心中,依然會随機被調用到,調用時便會逾時報錯。(主要是開發測試或者示範時需要立即将失效的從注冊中心剔除。)
則:1、需要在注冊中心,将eureka.server.eviction-interval-timer-in-ms改小,預設60秒,配置檔案中機關是毫秒。
eureka:
instance:
hostname: localhost
# 過期時間,預設90s, 可不配置
lease-expiration-duration-in-seconds: 90
# 續約時間,預設30s,可不配置
lease-renewal-interval-in-seconds: 30
# ip位址優先
prefer-ip-address: true
server:
# 關閉注冊中心自我保護模式,避免注冊中心不移除失效的服務,預設為true
enable-self-preservation: true
# 去除失效服務的時間間隔(毫秒)
eviction-interval-timer-in-ms: 4000
client:
# 啟用eureka用戶端,預設為true, 可不配置
enabled: true
# 取注冊資訊,預設為true,可不配置
fetchRegistry: false
# 兩個心跳參數,預設都是30s,可不配置
instance-info-replication-interval-seconds: 30
registry-fetch-interval-seconds: 30
# 注冊到注冊中心,預設為true,可不配置
registerWithEureka: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
2、還需要在業務微服務中,将過期時間預設90秒和續約時間預設30秒改小。
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka
instance:
instance-id: ${spring.cloud.client.ip-address}:${server.port}
prefer-ip-address: true #以IP位址注冊到服務中心
ip-address: 192.168.217.211
non-secure-port: 8767
#Eureka用戶端向服務端發送心跳的時間間隔,機關為秒(用戶端告訴服務端自己會按照該規則),預設30
lease-renewal-interval-in-seconds: 10
#Eureka服務端在收到最後一次心跳之後等待的時間上限,機關為秒,超過則剔除(用戶端告訴服務端按照此規則等待自己),預設90
lease-expiration-duration-in-seconds: 30
注意:更改Eureka更新頻率将打破伺服器的自我保護功能
其他幾種主動下線服務的方式
1. 直接停掉服務。
預設情況下,如果Eureka Server在90秒沒有收到Eureka客戶的續約,它會将執行個體從其系統資料庫中删除。但這種做法的不好之處在于, 用戶端已經停止了運作,但仍然在注冊中心的清單中。 雖然通過一定的負載均衡政策或使用熔斷器可以讓服務正常進行,但有沒有方法讓注冊中心馬上知道服務已經下線呢?
2.為了讓注冊中心馬上知道服務要下線, 可以向eureka 注冊中心發送delete 請求
格式為 /eureka/apps/{application.name}/
下面是下線一個hello-service的例子。
下圖是用postman 發送delete請求
值得注意的是,Eureka用戶端每隔一段時間(預設30秒)會發送一次心跳到注冊中心續約。如果通過這種方式下線了一個服務,而沒有及時停掉的話,該服務很快又會回到服務清單中。
是以,可以先停掉服務,再發送請求将其從清單中移除。
3. 用戶端主動通知注冊中心下線
如果你的eureka用戶端是是一個spring boot應用,可以通過調用以下代碼通知注冊中心下線。
DiscoveryManager.getInstance().shutdownComponent();
例子如下,
@RestController
public class HelloController {
@Autowired
private DiscoveryClient client;
@RequestMapping(value = "/hello", method = RequestMethod.GET)
public String index() {
java.util.List<ServiceInstance> instances = client.getInstances("hello-service");
return "Hello World";
}
@RequestMapping(value = "/offline", method = RequestMethod.GET)
public void offLine(){
DiscoveryManager.getInstance().shutdownComponent();
}
}
文章轉載:https://blog.csdn.net/itwxming/article/details/91576288
文章轉載:https://blog.csdn.net/xiaobao5214/article/details/81263445