Eureka principle
eureka comes from ancient Greek words, meaning "discovered"
eureka is divided into two parts, Server side and Client side
Register
Service registration
The instance that wants to participate in service registration discovery needs to register information with Eureka server first
Registration is submitted when the first heartbeat occurs
Renew
Renewal, heartbeat
Eureka customers need to send a heartbeat every 30 seconds to renew the update and notify Eureka that the server instance is still active. If the server does not see the update within 90 seconds, it deletes the instance from its registry
Fetch Registry
Eureka client obtains registry information from the server and caches it locally.
The client then uses this information to find other services.
This information can be updated periodically (every 30 seconds) by obtaining incremental updates between the previous acquisition cycle and the current acquisition cycle.
The node information is saved in the server for a longer time (about 3 minutes), so the same instance may be returned again when obtaining the node information. Eureka client automatically handles duplicate information.
After obtaining the increment, Eureka client coordinates the information with the server by comparing the instance count returned by the server. If the information does not match for some reason, it obtains the whole registry information again.
Cancel
The Eureka client sends a cancellation request to the Eureka server when it is shut down. This will remove the instance from the instance registry of the server, effectively removing the instance from traffic.
Time Lag
Synchronization time delay
All operations from Eureka clients may take some time to be reflected on Eureka servers and then on other Eureka clients. This is because the payload cache on the Eureka server is refreshed periodically to reflect new information. Eureka clients also periodically acquire incremental. Therefore, it may take 2 minutes for the changes to propagate to all Eureka clients.
Communication mechanism
Communication mechanism
Rest request under Http protocol
By default, Eureka uses Jersey, Jackson and JSON to complete the communication between nodes
Service registration
Create a new web project and introduce starterspring cloud starter Netflix Eureka client
Client configuration options
#The default sending interval for renewal is 30 seconds, and the heartbeat interval is eureka.instance.lease-renewal-interval-in-seconds=5 #It indicates how long the eureka client takes to pull the service registration information. The default value is 30 seconds. For API gateway, if you want to quickly obtain the service registration status, you can reduce this value, such as 5 seconds eureka.client.registry-fetch-interval-seconds=5 # Renewal expiration time (default: 90 seconds) eureka.instance.lease-expiration-duration-in-seconds=60
Server side configuration options
#Turn off self-protection mode eureka.server.enable-self-preservation=false #Failure service interval eureka.server.eviction-interval-timer-in-ms=3000
Eureka alone
Rest service call
Official documents
https://github.com/Netflix/eureka/wiki/Eureka-REST-operations
Operation | HTTP action | Description |
---|---|---|
Register new application instance | POST /eureka/v2/apps/appID | Input: JSON/XMLpayload HTTPCode: 204 on success |
De-register application instance | DELETE /eureka/v2/apps/appID/instanceID | HTTP Code: 200 on success |
Send application instance heartbeat | PUT /eureka/v2/apps/appID/instanceID | HTTP Code: * 200 on success * 404 if instanceIDdoesn't exist |
Query for all instances | GET /eureka/v2/apps | HTTP Code: 200 on success Output: JSON/XML |
Query for all appID instances | GET /eureka/v2/apps/appID | HTTP Code: 200 on success Output: JSON/XML |
Query for a specific appID/instanceID | GET /eureka/v2/apps/appID/instanceID | HTTP Code: 200 on success Output: JSON/XML |
Query for a specific instanceID | GET /eureka/v2/instances/instanceID | HTTP Code: 200 on success Output: JSON/XML |
Take instance out of service | PUT /eureka/v2/apps/appID/instanceID/status?value=OUT_OF_SERVICE | HTTP Code: * 200 on success * 500 on failure |
Move instance back into service (remove override) | DELETE /eureka/v2/apps/appID/instanceID/status?value=UP (The value=UP is optional, it is used as a suggestion for the fallback status due to removal of the override) | HTTP Code: * 200 on success * 500 on failure |
Update metadata | PUT /eureka/v2/apps/appID/instanceID/metadata?key=value | HTTP Code: * 200 on success * 500 on failure |
Query for all instances under a particular vip address | GET /eureka/v2/vips/vipAddress | * HTTP Code: 200 on success Output: JSON/XML * 404 if the vipAddressdoes not exist. |
Query for all instances under a particular secure vip address | GET /eureka/v2/svips/svipAddress | * HTTP Code: 200 on success Output: JSON/XML * 404 if the svipAddressdoes not exist. |
/eureka/status service status
Requesting a url using a browser returns server status information
<com.netflix.eureka.util.StatusInfo> <generalStats> <environment>test</environment> <num-of-cpus>16</num-of-cpus> <total-avail-memory>526mb</total-avail-memory> <current-memory-usage>183mb (34%)</current-memory-usage> <server-uptime>00:00</server-uptime> </generalStats> <applicationStats> <registered-replicas></registered-replicas> <available-replicas></available-replicas> <unavailable-replicas></unavailable-replicas> </applicationStats> <instanceInfo> <instanceId>localhost</instanceId> <hostName>localhost</hostName> <app>UNKNOWN</app> <ipAddr>192.168.29.1</ipAddr> <status>UP</status> <overriddenstatus>UNKNOWN</overriddenstatus> <port enabled="true">8080</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>0</registrationTimestamp> <lastRenewalTimestamp>0</lastRenewalTimestamp> <evictionTimestamp>0</evictionTimestamp> <serviceUpTimestamp>0</serviceUpTimestamp> </leaseInfo> <metadata> <management.port>8080</management.port> <jmx.port>7649</jmx.port> </metadata> <homePageUrl>http://localhost:8080/</homePageUrl> <statusPageUrl>http://localhost:8080/actuator/info</statusPageUrl> <healthCheckUrl>http://localhost:8080/actuator/health</healthCheckUrl> <vipAddress>unknown</vipAddress> <secureVipAddress>unknown</secureVipAddress> <isCoordinatingDiscoveryServer>false</isCoordinatingDiscoveryServer> <lastUpdatedTimestamp>1586328420409</lastUpdatedTimestamp> <lastDirtyTimestamp>1586328420519</lastDirtyTimestamp> </instanceInfo> </com.netflix.eureka.util.StatusInfo>
If you need json format, you can add a request header Accept:application/json
{ "generalStats": { "environment": "test", "num-of-cpus": "16", "total-avail-memory": "517mb", "current-memory-usage": "45mb (8%)", "server-uptime": "00:03" }, "applicationStats": { "registered-replicas": "", "available-replicas": "", "unavailable-replicas": "" }, "instanceInfo": { "instanceId": "localhost", "hostName": "localhost", "app": "UNKNOWN", "ipAddr": "192.168.29.1", "status": "UP", "overriddenStatus": "UNKNOWN", "port": { "$": 8080, "@enabled": "true" }, "securePort": { "$": 443, "@enabled": "false" }, "countryId": 1, "dataCenterInfo": { "@class": "com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo", "name": "MyOwn" }, "leaseInfo": { "renewalIntervalInSecs": 30, "durationInSecs": 90, "registrationTimestamp": 0, "lastRenewalTimestamp": 0, "evictionTimestamp": 0, "serviceUpTimestamp": 0 }, "metadata": { "management.port": "8080", "jmx.port": "7649" }, "homePageUrl": "http://localhost:8080/", "statusPageUrl": "http://localhost:8080/actuator/info", "healthCheckUrl": "http://localhost:8080/actuator/health", "vipAddress": "unknown", "secureVipAddress": "unknown", "isCoordinatingDiscoveryServer": "false", "lastUpdatedTimestamp": "1586328420409", "lastDirtyTimestamp": "1586328420519" }
View the service information registered with eureka
get: {ip:port}/eureka/apps
Check the specific services registered to eureka
get: {ip:port}/eureka/apps/{appname}/{id}
Service renewal
put: {ip:port}/eureka/apps/{appname}/{id}?lastDirtyTimestamp={}&status=up
Change service status
put: {ip:port}/eureka/apps/{appname}/{id}/status?lastDirtyTimestamp={}&value={UP/DOWN}
Corresponding to eureka source code: instanceresource statusUpdate
Delete status update
delete: {ip:port}/eureka/apps/{appname}/{id}/status?lastDirtyTimestamp={}&value={UP/DOWN}
Delete service
delete: {ip:port}/eureka/apps/{appname}/{id}
metadata
Eureka has two kinds of metadata: standard metadata and custom metadata.
Standard metadata: host name, IP address, port number, status page, health check and other information, which will be published in the service registry for calls between services.
Custom metadata: you can use Eureka instance. Metadata map configuration. These metadata can be accessed in the remote client, but generally do not change the client behavior unless the client knows the meaning of the metadata.
You can set custom metadata for the current service in the configuration file, which can be personalized for later users
Metadata can be configured on eureka server and eureka client
eureka.instance.metadata-map.dalao=mashibing
Server:
client:
{ "applications": { "versions__delta": "1", "apps__hashcode": "UP_2_", "application": [ { "name": "EUREKA-CONSUMER", "instance": [ { "instanceId": "localhost:Eureka-Consumer:9001", "hostName": "localhost", "app": "EUREKA-CONSUMER", "ipAddr": "192.168.29.1", "status": "UP", "overriddenStatus": "UNKNOWN", "port": { "$": 9001, "@enabled": "true" }, "securePort": { "$": 443, "@enabled": "false" }, "countryId": 1, "dataCenterInfo": { "@class": "com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo", "name": "MyOwn" }, "leaseInfo": { "renewalIntervalInSecs": 30, "durationInSecs": 90, "registrationTimestamp": 1586331982283, "lastRenewalTimestamp": 1586331982283, "evictionTimestamp": 0, "serviceUpTimestamp": 1586331982283 }, "metadata": { "dalao": "mashibing666", "management.port": "9001", "jmx.port": "10158" }, "homePageUrl": "http://localhost:9001/", "statusPageUrl": "http://localhost:9001/actuator/info", "healthCheckUrl": "http://localhost:9001/actuator/health", "vipAddress": "Eureka-Consumer", "secureVipAddress": "Eureka-Consumer", "isCoordinatingDiscoveryServer": "false", "lastUpdatedTimestamp": "1586331982283", "lastDirtyTimestamp": "1586331982260", "actionType": "ADDED" }, { "instanceId": "localhost:Eureka-Consumer:9000", "hostName": "localhost", "app": "EUREKA-CONSUMER", "ipAddr": "192.168.29.1", "status": "UP", "overriddenStatus": "UNKNOWN", "port": { "$": 9000, "@enabled": "true" }, "securePort": { "$": 443, "@enabled": "false" }, "countryId": 1, "dataCenterInfo": { "@class": "com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo", "name": "MyOwn" }, "leaseInfo": { "renewalIntervalInSecs": 30, "durationInSecs": 90, "registrationTimestamp": 1586331637223, "lastRenewalTimestamp": 1586332057220, "evictionTimestamp": 0, "serviceUpTimestamp": 1586331637223 }, "metadata": { "dalao": "mashibing", "management.port": "9000", "jmx.port": "10000" }, "homePageUrl": "http://localhost:9000/", "statusPageUrl": "http://localhost:9000/actuator/info", "healthCheckUrl": "http://localhost:9000/actuator/health", "vipAddress": "Eureka-Consumer", "secureVipAddress": "Eureka-Consumer", "isCoordinatingDiscoveryServer": "false", "lastUpdatedTimestamp": "1586331637223", "lastDirtyTimestamp": "1586331637182", "actionType": "ADDED" } ] } ] } }
EurekaClient
eureka client can obtain the registrant information on eureka server at the client
org.springframework.cloud.client.discovery and com netflix. discovery. DiscoveryClient
org.springframework.cloud.client.discovery is an abstract encapsulation of the registry client by spring cloud, which provides common functions
org.springframework.cloud.client.discovery defines the client interface used for service discovery. It is the core interface used by the client for service discovery. It is the top-level interface used by spring cloud for service discovery. Its status can be seen in common. There are specific implementation classes in Netflix Eureka and consult.
Represents a read operation common to service discovery, such as in eureka or consumer.
have String description();//Gets the description of the implementation class. List<String> getServices();//Get all service instance IDs. List<ServiceInstance> getInstances(String serviceId);//Query the service instance information list through the service id.
com.netflix.discovery.DiscoveryClient is the interface of Eureka registry client, with more functions
Self protection mechanism
mechanism
Eureka belongs to AP in CAP theory, that is, when network partition is generated, Eureka guarantees the availability of the system, but does not guarantee the consistency of data in the system
It is enabled by default, which is a way of fault tolerance on the server side, that is, if the heartbeat does not arrive in a short time, the nodes in the service list will not be removed
EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.
By default, if Eureka Server does not receive a microservice heartbeat within a certain period of time, it will log off a microservice (90S). However, when the network fails, the micro service and the Server cannot communicate normally, and the above behavior is very dangerous, because the micro service is normal and should not be logged off.
Eureka Server solves the whole problem through self-protection mode. When the Server loses too many clients in a short time, the Server will enter self-protection mode and protect the micro services in the registry from being logged off. When the network fault recovers, exit the self-protection mode.
Thought: it's better to keep healthy and unhealthy than cancel any healthy services blindly.
Self protection trigger
The protection mechanism will be triggered when the number of client renewals per minute is less than 85% of the total number of clients
Trigger conditions of 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 will be triggered and the lease will no longer expire automatically.)
numberOfRenewsPerMinThreshold = expectedNumberOfRenewsPerMin * renewal percentage (eureka.server.renewalPercentThreshold, 0.85 by default)
expectedNumberOfRenewsPerMin = number of currently registered application instances x 2
Why multiply by 2:
By default, the registered application instance is renewed every half a minute, so the heartbeat is twice a minute, so x 2.
Number of service instances: 10, expected renewal per minute: 10 * 2 = 20, expected threshold: 20 * 0.85 = 17, triggered when self-protection is less than 17.
eliminate:
AbstractInstanceRegistry public void evict(long additionalLeaseMs) { logger.debug("Running the evict task"); if (!isLeaseExpirationEnabled()) { logger.debug("DS: lease expiration is currently disabled."); return; } This code means: if Judged as true,Do not follow this logic, follow the following elimination. If if by false. Follow this logic and don't eliminate it.
PeerAwareInstanceRegistryImpl @Override public boolean isLeaseExpirationEnabled() { if (!isSelfPreservationModeEnabled()) { //If self-protection is turned on, this logic is not entered. // The self preservation mode is disabled, hence allowing the instances to expire. return true; } return numberOfRenewsPerMinThreshold > 0 && getNumOfRenewsInLastMin() > numberOfRenewsPerMinThreshold; }
close
eureka.server.enable-self-preservation=false
Prompt after closing
Cleaning time
Default 60 seconds
eureka.server.eviction-interval-timer-in-ms=3000
Multi network card selection
- ip registration
eureka: instance: prefer-ip-address: true Express that you will ip Register to EurekaServer Come on. No configuration or false,Indicates that the operating system will be hostname Register to server
-
The server has multiple network cards, eh0, eh1 and eh2. Only eh0 can be accessed by other external services, and Eureka client registers eh1 and eh2 on Eureka server, so that other services cannot access the micro service.
-
Specify Ip
eureka: instance: prefer-ip-address: true ip-address: Actually accessible Ip
If the ip address at this time is set, the metadata shows that it is this ip, and other services are also called through this ip.
{ "host": "127.0.0.1", "port": 8084, "metadata": { "yueyi": "2019", "user.password": "root", "management.port": "8084", "jmx.port": "61378", "user.name": "root" }, "secure": false, "uri": "http://127.0.0.1:8084", "instanceId": "api-listen-order:30.136.133.11:port", "serviceId": "API-LISTEN-ORDER", "instanceInfo": { "instanceId": "api-listen-order:30.136.133.11:port", "app": "API-LISTEN-ORDER", "appGroupName": null, "ipAddr": "127.0.0.1", "sid": "na", "homePageUrl": "http://127.0.0.1:8084/", "statusPageUrl": "http://127.0.0.1:8084/actuator/info", "healthCheckUrl": "http://127.0.0.1:8084/actuator/health", "secureHealthCheckUrl": null, "vipAddress": "api-listen-order", "secureVipAddress": "api-listen-order", "countryId": 1, "dataCenterInfo": { "@class": "com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo", "name": "MyOwn" }, "hostName": "127.0.0.1", "status": "UP", "overriddenStatus": "UNKNOWN", "leaseInfo": { "renewalIntervalInSecs": 1, "durationInSecs": 1, "registrationTimestamp": 1579489514655, "lastRenewalTimestamp": 1579489524146, "evictionTimestamp": 0, "serviceUpTimestamp": 1579489514147 }, "isCoordinatingDiscoveryServer": false, "metadata": { "yueyi": "2019", "user.password": "root", "management.port": "8084", "jmx.port": "61378", "user.name": "root" }, "lastUpdatedTimestamp": 1579489514655, "lastDirtyTimestamp": 1579489514111, "actionType": "ADDED", "asgName": null }, "scheme": null }
Or use spring cloud. Inetutils configuration network card selection
Eureka health examination
Because the server and client maintain the service status through heartbeat, only the service in UP status can be accessed. Look at the status in the eureka interface.
For example, the heartbeat is always normal and the service is always UP, but the service DB cannot be connected and cannot provide services normally.
At this point, we need to synchronize the health status of the micro service to the server. Just start eureka's health check. In this way, the micro service will synchronize its health status to eureka. The configuration is as follows.
Turn on manual control
Configure on the client side: propagate your true health status to the server.
eureka: client: healthcheck: enabled: true
Configure actor on Client side
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
Service s that change health status
@Service public class HealthStatusService implements HealthIndicator{ private Boolean status = true; public void setStatus(Boolean status) { this.status = status; } @Override public Health health() { // TODO Auto-generated method stub if(status) return new Health.Builder().up().build(); return new Health.Builder().down().build(); } public String getStatus() { // TODO Auto-generated method stub return this.status.toString(); }
Controller for test
@GetMapping("/health") public String health(@RequestParam("status") Boolean status) { healthStatusSrv.setStatus(status); return healthStatusSrv.getStatus(); }
Security configuration
Open Eureka secure connection
spring.security.user.name=yiming spring.security.user.password=123
If the service registration reports an error
Root name 'timestamp' does not match expected ('instance') for type [simple
Yes, cross domain attack prevention is enabled by default
Manual shutdown
Add configuration classes on the server
@Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter{ @Override protected void configure(HttpSecurity http) throws Exception { // TODO Auto-generated method stub http.csrf().disable(); super.configure(http); } }
Inter service call
In microservices, many service systems run in independent processes, and all business functions of a large project are realized through the cooperation between various service systems. Service systems use a variety of cross process ways to communicate and cooperate, and RESTful network request is one of the most common ways of interaction.
spring cloud provides:
- RestTemplate
- Feign
I am used to using RestTemplate because it is free and convenient to call other third-party http services. feign can also be more object-oriented and elegant. It just needs to be configured.
Rest
RESTful network request refers to RESTful style network request, in which REST is the abbreviation of resource representative state transfer, which is directly translated as "resource presentation layer state transfer".
Resource stands for Internet resources. The so-called "resource" is an entity on the network, or a specific information on the Internet. It can be a piece of text, a song or a service. It can be pointed to by a URI, and each "resource" corresponds to a URI.
Representational means "presentation layer". "Resource" is a kind of message entity, which can have a variety of external forms. We call the form of "resource" as its "expression layer". For example, text can be expressed in TXT format, XML format, JSON format and binary format; Video can be expressed in MP4 format or AVI format. The URI only represents the entity of the resource, not its form. Its specific manifestation should be specified by the HTTP request header information Accept and content type fields, which are the description of the "presentation layer".
State Transfer refers to "State Transfer". The process of client accessing services inevitably involves the transformation of data and state. If the client wants to operate the server-side resources, it must use some means to make the server-side resources "state transition". This transformation is based on the presentation layer, so it is called "presentation layer state transition". The client implements the above operations by using four verbs in the HTTP protocol, which are: GET to obtain resources, POST to create or update resources, PUT to update resources and DELETE to DELETE resources.
RestTemplate is a synchronous HTTP network client interface provided by Spring. It can simplify the interaction between the client and the HTTP server, and it forces the use of RESTful style. It handles HTTP connections and closures, requiring only the user to provide the server's address (URL) and template parameters.
The Web service of the first level (Level 0) only uses HTTP as the transmission mode. In fact, it is only a specific form of remote method call (RPC). Both SOAP and XML-RPC fall into this category.
The Web service of the second level (Level 1) introduces the concept of resources. Each resource has a corresponding identifier and expression.
The Web services of the third level (Level 2) use different HTTP methods to perform different operations, and use HTTP status codes to represent different results. For example, HTTP GET method is used to obtain resources, and HTTP DELETE method is used to delete resources.
The Web services of the fourth level (Level 3) use HATEOAS. Link information is included in the expression of resources. The client can find the actions that can be performed according to the link.
git's restful api