本文主要研究一下eureka server的instance註冊及元數據變動接口java
eureka-core-1.8.8-sources.jar!/com/netflix/eureka/resources/ApplicationResource.javagit
@POST @Consumes({"application/json", "application/xml"}) public Response addInstance(InstanceInfo info, @HeaderParam(PeerEurekaNode.HEADER_REPLICATION) String isReplication) { logger.debug("Registering instance {} (replication={})", info.getId(), isReplication); // validate that the instanceinfo contains all the necessary required fields if (isBlank(info.getId())) { return Response.status(400).entity("Missing instanceId").build(); } else if (isBlank(info.getHostName())) { return Response.status(400).entity("Missing hostname").build(); } else if (isBlank(info.getIPAddr())) { return Response.status(400).entity("Missing ip address").build(); } else if (isBlank(info.getAppName())) { return Response.status(400).entity("Missing appName").build(); } else if (!appName.equals(info.getAppName())) { return Response.status(400).entity("Mismatched appName, expecting " + appName + " but was " + info.getAppName()).build(); } else if (info.getDataCenterInfo() == null) { return Response.status(400).entity("Missing dataCenterInfo").build(); } else if (info.getDataCenterInfo().getName() == null) { return Response.status(400).entity("Missing dataCenterInfo Name").build(); } // handle cases where clients may be registering with bad DataCenterInfo with missing data DataCenterInfo dataCenterInfo = info.getDataCenterInfo(); if (dataCenterInfo instanceof UniqueIdentifier) { String dataCenterInfoId = ((UniqueIdentifier) dataCenterInfo).getId(); if (isBlank(dataCenterInfoId)) { boolean experimental = "true".equalsIgnoreCase(serverConfig.getExperimental("registration.validation.dataCenterInfoId")); if (experimental) { String entity = "DataCenterInfo of type " + dataCenterInfo.getClass() + " must contain a valid id"; return Response.status(400).entity(entity).build(); } else if (dataCenterInfo instanceof AmazonInfo) { AmazonInfo amazonInfo = (AmazonInfo) dataCenterInfo; String effectiveId = amazonInfo.get(AmazonInfo.MetaDataKey.instanceId); if (effectiveId == null) { amazonInfo.getMetadata().put(AmazonInfo.MetaDataKey.instanceId.getName(), info.getId()); } } else { logger.warn("Registering DataCenterInfo of type {} without an appropriate id", dataCenterInfo.getClass()); } } } registry.register(info, "true".equals(isReplication)); return Response.status(204).build(); // 204 to be backwards compatible }
這個是註冊應用實例的服務端處理邏輯
curl -i -H "Content-Type: application/json" -H "Accept-Encoding: gzip" -X POST -d '{ "instance": { "instanceId": "test1", "app": "test-service", "appGroupName": null, "ipAddr": "127.0.0.1", "sid": "na", "homePageUrl": null, "statusPageUrl": null, "healthCheckUrl": null, "secureHealthCheckUrl": null, "vipAddress": "test-service", "secureVipAddress": "test-service", "countryId": 1, "dataCenterInfo": { "@class": "com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo", "name": "MyOwn" }, "hostName": "127.0.0.1", "status": "UP", "leaseInfo": null, "isCoordinatingDiscoveryServer": false, "lastUpdatedTimestamp": 1525661162147, "lastDirtyTimestamp": 1525661162147, "actionType": null, "asgName": null, "overridden_status": "UNKNOWN", "port": { "$": 9090, "@enabled": "true" }, "securePort": { "$": 7002, "@enabled": "false" }, "metadata": { "@class": "java.util.Collections$EmptyMap" } } }' http://localhost:8761/eureka/apps/test-service
返回github
HTTP/1.1 204 Content-Type: application/xml Date: Mon, 07 May 2018 03:01:23 GMT
eureka-core-1.8.8-sources.jar!/com/netflix/eureka/resources/InstanceResource.javajson
@PUT @Path("metadata") public Response updateMetadata(@Context UriInfo uriInfo) { try { InstanceInfo instanceInfo = registry.getInstanceByAppAndId(app.getName(), id); // ReplicationInstance information is not found, generate an error if (instanceInfo == null) { logger.error("Cannot find instance while updating metadata for instance {}", id); return Response.serverError().build(); } MultivaluedMap<String, String> queryParams = uriInfo.getQueryParameters(); Set<Entry<String, List<String>>> entrySet = queryParams.entrySet(); Map<String, String> metadataMap = instanceInfo.getMetadata(); // Metadata map is empty - create a new map if (Collections.emptyMap().getClass().equals(metadataMap.getClass())) { metadataMap = new ConcurrentHashMap<String, String>(); InstanceInfo.Builder builder = new InstanceInfo.Builder(instanceInfo); builder.setMetadata(metadataMap); instanceInfo = builder.build(); } // Add all the user supplied entries to the map for (Entry<String, List<String>> entry : entrySet) { metadataMap.put(entry.getKey(), entry.getValue().get(0)); } registry.register(instanceInfo, false); return Response.ok().build(); } catch (Throwable e) { logger.error("Error updating metadata for instance {}", id, e); return Response.serverError().build(); } }
這個是更改meta的服務端處理邏輯
curl -i -X PUT http://localhost:8761/eureka/apps/test-service/test1/metadata?env=prod
返回app
HTTP/1.1 200 Content-Type: application/xml Content-Length: 0 Date: Mon, 07 May 2018 03:03:37 GMT
能夠註冊/更新實例信息curl
能夠用來更新meta信息ui