1. 程式人生 > >Eureka原始碼之服務註冊中心處理

Eureka原始碼之服務註冊中心處理

Eureka所有的互動處理都是通過REST請求發起的,下面看看服務註冊中心對這些請求的處理。Eureka Server對各類REST請求的定義都是位於com.netflix.eurek.resource包中。

以“服務註冊”請求為例:

@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
      ......

        // 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
    }

在對註冊資訊進行了一堆校驗之後,會呼叫org.springframework.cloud.netflix.eureka.server.InstanceRegistry物件的register(InstanceInfo info, int leaseDuration, boolean isReplication)函式進行服務註冊。


    public void register(InstanceInfo info, int leaseDuration, boolean isReplication) {
        handleRegistration(info, leaseDuration, isReplication);
        super.register(info, leaseDuration, isReplication);
    }

    private void handleRegistration(InstanceInfo info, int leaseDuration,
            boolean isReplication) {
        log("register " + info.getAppName() + ", vip " + info.getVIPAddress()
                + ", leaseDuration " + leaseDuration + ", isReplication "
                + isReplication);
        publishEvent(new EurekaInstanceRegisteredEvent(this, info, leaseDuration,
                isReplication));
    }

相關呼叫如上面程式碼:

在註冊函式中,先呼叫publishEvent函式,將該新服務註冊的事件傳播出去,然後呼叫AbstractInstanceRegistry中的註冊實現,將InstanceInfo中的元資料資訊儲存在一個ConcurrentHashMap物件中,註冊中心儲存了兩層Map結構,第一層的key儲存服務名:InstanceInfo中的appName屬性,第二層的key儲存例項名:InstanceInfo中的instanceId屬性。