Spring Cloud Five: Eureka self-protection, health check, event monitoring use

One, Eureka metadata

1. Obtain from EurekaServer

Start EurekaServier, start EurekaClient to register to EurekaServer

Visit http://euk-server1:7001/eureka/apps/EurekaClient to obtain EurekaClient instance information:

<application>
<name>EUREKACLIENT</name>
<instance>
<instanceId>192.168.1.39:EurekaClient:7004</instanceId>
<hostName>euk-client1</hostName>
<app>EUREKACLIENT</app>
<ipAddr>192.168.1.39</ipAddr>
<status>UP</status>
<overriddenstatus>UNKNOWN</overriddenstatus>
<port enabled="true">7004</port>
<securePort enabled="false">443</securePort>
<countryId>1</countryId>
<dataCenterInfo class="com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo">
<name>MyOwn</name>
</dataCenterInfo>
<leaseInfo>
<renewalIntervalInSecs>30</renewalIntervalInSecs>
<durationInSecs>90</durationInSecs>
<registrationTimestamp>1605853910599</registrationTimestamp>
<lastRenewalTimestamp>1605872603029</lastRenewalTimestamp>
<evictionTimestamp>0</evictionTimestamp>
<serviceUpTimestamp>1605853910599</serviceUpTimestamp>
</leaseInfo>
<metadata>
<management.port>7004</management.port>
</metadata>
<homePageUrl>http://euk-client1:7004/</homePageUrl>
<statusPageUrl>http://euk-client1:7004/actuator/info</statusPageUrl>
<healthCheckUrl>http://euk-client1:7004/actuator/health</healthCheckUrl>
<vipAddress>EurekaClient</vipAddress>
<secureVipAddress>EurekaClient</secureVipAddress>
<isCoordinatingDiscoveryServer>false</isCoordinatingDiscoveryServer>
<lastUpdatedTimestamp>1605853910599</lastUpdatedTimestamp>
<lastDirtyTimestamp>1605853910549</lastDirtyTimestamp>
<actionType>ADDED</actionType>
</instance>
</application>

2. Get metadata by handwriting

Create a new HelloController in EurekaClient

@RestController
public class HelloController {
    
    
    @Autowired
    private EurekaDiscoveryClient eurekaDiscoveryClient;

    @RequestMapping("/getInstance")
    public List<ServiceInstance> getInstance(String clientName) {
    
    
        List<ServiceInstance> instances = eurekaDiscoveryClient.getInstances(clientName);
        return instances;
    }

    @RequestMapping("/hello")
    public String hello(){
    
    
        return "hello";
    }
}

Request access:

http://euk-client1:7004/getInstance?clientName=EurekaClient

Output (representing the instance information of EurekaClient in EurekaService):

[{
    
    
	"metadata": {
    
    
		"management.port": "7004"
	},
	"secure": false,
	"uri": "http://euk-client1:7004",
	"serviceId": "EUREKACLIENT",
	"instanceId": "192.168.1.39:EurekaClient:7004",
	"instanceInfo": {
    
    
		"instanceId": "192.168.1.39:EurekaClient:7004",
		"app": "EUREKACLIENT",
		"appGroupName": null,
		"ipAddr": "192.168.1.39",
		"sid": "na",
		"homePageUrl": "http://euk-client1:7004/",
		"statusPageUrl": "http://euk-client1:7004/actuator/info",
		"healthCheckUrl": "http://euk-client1:7004/actuator/health",
		"secureHealthCheckUrl": null,
		"vipAddress": "EurekaClient",
		"secureVipAddress": "EurekaClient",
		"countryId": 1,
		"dataCenterInfo": {
    
    
			"@class": "com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo",
			"name": "MyOwn"
		},
		"hostName": "euk-client1",
		"status": "UP",
		"overriddenStatus": "UNKNOWN",
		"leaseInfo": {
    
    
			"renewalIntervalInSecs": 30,
			"durationInSecs": 90,
			"registrationTimestamp": 1605873533416,
			"lastRenewalTimestamp": 1605873533416,
			"evictionTimestamp": 0,
			"serviceUpTimestamp": 1605873533416
		},
		"isCoordinatingDiscoveryServer": false,
		"metadata": {
    
    
			"management.port": "7004"
		},
		"lastUpdatedTimestamp": 1605873533416,
		"lastDirtyTimestamp": 1605873533392,
		"actionType": "ADDED",
		"asgName": null
	},
	"scheme": "http",
	"host": "euk-client1",
	"port": 7004
}]

3. Custom metadata

Standard metadata: hostname, ip, port, health check and other information. Will be published to the registry for inter-service calls

Custom metadata: Remote clients access custom attributes.

eureka.instance.metadata-map:
  自定义key:自定义value

application.yaml

spring:
  application:
    name: EurekaClient
server:
  port: 7004
eureka:
  instance:
    hostname: euk-client1
    metadata-map: 
      bobo: 爱学习
  client:
    service-url:
      defaultZone: http://euk-server1:7001/eureka/

3-1: Visit EurekaServer to get metadata information defined by yourself:

http://euk-server1:7001/eureka/apps/EurekaClient
<application>
<name>EUREKACLIENT</name>
<instance>
<instanceId>192.168.1.39:EurekaClient:7004</instanceId>
<hostName>euk-client1</hostName>
<app>EUREKACLIENT</app>
<ipAddr>192.168.1.39</ipAddr>
<status>UP</status>
<overriddenstatus>UNKNOWN</overriddenstatus>
<port enabled="true">7004</port>
<securePort enabled="false">443</securePort>
<countryId>1</countryId>
<dataCenterInfo class="com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo">
<name>MyOwn</name>
</dataCenterInfo>
<leaseInfo>
<renewalIntervalInSecs>30</renewalIntervalInSecs>
<durationInSecs>90</durationInSecs>
<registrationTimestamp>1605874332212</registrationTimestamp>
<lastRenewalTimestamp>1605874452194</lastRenewalTimestamp>
<evictionTimestamp>0</evictionTimestamp>
<serviceUpTimestamp>1605874332212</serviceUpTimestamp>
</leaseInfo>
<metadata>
<bobo>爱学习</bobo>
<management.port>7004</management.port>
</metadata>
<homePageUrl>http://euk-client1:7004/</homePageUrl>
<statusPageUrl>http://euk-client1:7004/actuator/info</statusPageUrl>
<healthCheckUrl>http://euk-client1:7004/actuator/health</healthCheckUrl>
<vipAddress>EurekaClient</vipAddress>
<secureVipAddress>EurekaClient</secureVipAddress>
<isCoordinatingDiscoveryServer>false</isCoordinatingDiscoveryServer>
<lastUpdatedTimestamp>1605874332212</lastUpdatedTimestamp>
<lastDirtyTimestamp>1605874332191</lastDirtyTimestamp>
<actionType>ADDED</actionType>
</instance>
</application>

3-2: Obtain the metadata information of EurekaClint1 through EurekaClient2

@RestController
public class HelloController {
    
    

    @Autowired
    private EurekaDiscoveryClient eurekaDiscoveryClient;

    @RequestMapping("/meta-data")
    public Map<String, String> getMetaDataInfo(String applicationName) {
    
    
        Map<String, String> result = new HashMap<>();
        List<ServiceInstance> instances = eurekaDiscoveryClient.getInstances(applicationName);
        for (ServiceInstance instance : instances) {
    
    
            Map<String, String> metadata = instance.getMetadata();
            for (String s : metadata.keySet()) {
    
    
                result.put(s, metadata.get(s));
            }
        }
        return result;
    }
}

access:

http://euk-client2:7005/meta-data?applicationName=EurekaClient

Output:

{
    
    "bobo":"爱学习","management.port":"7005"}

Second, Eureka self-protection

By default, Eureka Server does not receive a microservice heartbeat within a certain period of time, and will log out a microservice (90S). But when the network fails, the microservice and the server cannot communicate normally, the above behavior is very dangerous, because the microservice is normal and should not be logged out.

Eureka Server solves the whole problem through the self-protection mode. When the server loses too many clients in a short period of time, the server will enter the self-protection mode to protect the microservices in the registry from being logged out. When the network failure is restored, exit the self-protection mode.

Idea: I would rather keep the healthy and unhealthy than blindly write off any healthy services.

Turn off self-protection:

eureka:
  server: 
    enable-self-preservation: false

The triggering conditions of the self-protection mechanism:

When the number of heartbeats per minute (renewsLastMin) is less than numberOfRenewsPerMinThreshold and the automatic protection mode switch is turned on (eureka.server.enable-self-preservation = true ), the self-protection mechanism is triggered and the lease is no longer automatically expired.

numberOfRenewsPerMinThreshold = expectedNumberOfRenewsPerMin * 续租百分比( eureka.server.renewalPercentThreshold, 默认0.85 )
expectedNumberOfRenewsPerMin = 当前注册的应用实例数 x 2

为什么乘以 2:
默认情况下,注册的应用实例每半分钟续租一次,那么一分钟心跳两次,因此 x 2 。

服务实例数:10个,期望每分钟续约数:10 * 2=20,期望阈值:20*0.85=17,自我保护少于17时 触发。

Three, multiple network card options

1. ip registration

eureka:
  instance:
    prefer-ip-address: true
表示将自己的ip注册到EurekaServer上。不配置或false,表示将操作系统的hostname注册到server

2. The server has multiple network cards, eh0, eh1, and eh2. Only eh0 can be accessed by other external services, and the Eureka client registers eh1 and eh2 on the Eureka server, so other services cannot access the microservice.

3. Specify ip

eureka:
  instance:
    prefer-ip-address: true
    ip-address: 实际能访问到的Ip

If the ip-address at this time is set, this ip is found in the metadata, and other services are also called through this ip.

Fourth, Eureka health check

Because server and client maintain service status through heartbeat, only services whose status is UP can be accessed. Look at the status in the eureka interface.

For example, the heartbeat has been normal and the service has been up, but the service DB cannot be connected and the service cannot be provided normally.

At this point, we need to synchronize the health status of the microservice to the server. Just start the health check of eureka. In this way, the microservice will synchronize its health status to eureka. The configuration is as follows.

Configure on the client side: Propagate your health status to the server.

eureka:
  client:
    healthcheck:
      enabled: true

Five, Eureka configuration

EurekaServerConfigBean: Eureka Server deployment.

​ EurekaInstanceConfigBean: Eureka Client instance configuration.

​ EurekaClientConfigBean: Eureka Client client and server interactive configuration.

eureka:
  # EurekaServerConfigBean
  server: 
  	#关闭自我保护
    enable-self-preservation: false
    #清理服务间隔时间,毫秒
    eviction-interval-timer-in-ms: 5000
    
  # EurekaClientConfigBean
  client:
    healthcheck:
      #开启健康检查,需要引入actuator
      enabled: true
      
  # EurekaInstanceConfigBean
  instance: 
    #发送心跳给server的频率,每隔这个时间会主动心跳一次
    lease-renewal-interval-in-seconds: 1      
    #Server从收到client后,下一次收到心跳的间隔时间。超过这个时间没有接收到心跳EurekaServer就会将这个实例剔除
    lease-expiration-duration-in-seconds: 1   
client:
eureka: 

  

Six, Eureka listens to events

EurekaInstanceCanceledEvent service offline event

EurekaInstanceRegisteredEvent service registration event

EurekaInstanceRenewedEvent service renewed event

EurekaRegistryAvailableEvent registry available events

EurekaServerStartedEvent registry started

If you monitor the EurekaInstanceRegisteredEvent service registration event on the server side, you will receive the event when a service is registered:

@Component
public class CustomEvent {
    
    
    @EventListener
    public void listen(EurekaInstanceRegisteredEvent e){
    
    
        System.out.println(e.getInstanceInfo().getInstanceId()+"-------------->上线了");
    }
}

Seven, Eureka defects

Since the synchronous replication between clusters is carried out through HTTP, based on the unreliability of the network, the registry information between the Eureka Servers in the cluster will inevitably have unsynchronized time nodes, which does not meet the C (data consistency) in the CAP.

Guess you like

Origin blog.csdn.net/u013277209/article/details/109864918