[SpringCloud] 유레카 입문과 원리

9483 단어
개발 효율이 효율적이고 업무 논리가 명확하기 위해 점점 더 많은 프로젝트가 분포식 시스템을 채택하고 있다.분포식에서 가장 중요한 것은 등록 센터다.유레카는 SpringCloud 원생이 제공하는 등록 센터입니다. 룩 라운드에 오세요.

초광속 입문


서비스 단말기


의존성 도입:

    org.springframework.cloud
    spring-cloud-starter-netflix-eureka-server
    Greenwich.SR1


시작 클래스에 메모 @EnableEurekaServer
@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaApplication.class, args);
    }
}

yml 파일을 구성하려면:
#   
server:
  port: 8331
#Eureka   ,           
eureka:
  instance:
    hostname: eureka
  #   
  client:
    #        ,      ,     
    register-with-eureka: false
    #        ,             。
    fetch-registry: false
    #      
    service-url:
      defaultZone: http://localhost:8331/eureka/

프로젝트 EurekaApplication 시작, 브라우저 액세스http://localhost:8331/, Euerka 서버 구축에 성공했습니다.
아직 등록할 물건이 없다.

클라이언트


의존성 도입:

    org.springframework.cloud
    spring-cloud-starter-netflix-eureka-server
    Greenwich.SR1


이번 부트 클래스 메모가 변경되었습니다. @EnableDiscoveryClient
@EnableDiscoveryClient
@SpringBootApplication
public class ProviderApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProviderApplication.class, args);
    }
}

다음은 구성 파일입니다.
#   
server:
  port: 8332
#Eureka   ,           
spring:
  application:
    name: first-service
eureka:
  #   
  client:
    #      
    service-url:
      defaultZone: http://localhost:8331/eureka/

그런 다음 프로젝트를 시작하고 나중에 페이지를 새로 고치려면 다음과 같이 하십시오.
등록 센터에 아까 그 서비스가 생겼어요.퍼스트 서비스라고 하는데 등록 센터에 등록하면 생산자일 수도 있고 소비자일 수도 있다. 다른 서비스에 인터페이스를 제공할 수도 있고 다른 서비스가 제공하는 인터페이스를 호출할 수도 있기 때문이다.한 마디로 하면 생산자든 소비자든 모두 클라이언트라고 불리며 @Enable Discovery 클라이언트로 주석을 달아야 한다.내가 부주의로 이 주해 안에 들어갔는데 또 하나의 매개 변수가 있는 것을 발견했다boolean autoRegister() default true.프로젝트가 시작되었는지 여부입니다. 이 서비스는 자동으로 등록 센터에 등록됩니다.기본값은 자동입니다.
@Enable Discovery Client 이외에 @Enable EurekaClient도 사용할 수 있습니다.효과가 동일합니다. 만약에 유레카가 등록 센터를 한다면 @Enable Eureka Client를 사용하고, 다른 등록 센터(예를 들어 아리의nacos)라면 @Enable Discovery Client를 사용하는 것을 권장합니다.

의 원리


하나의 마이크로 서비스를 실행하고 분포식 시스템을 형성하려면 등록 센터와 그 중의 서비스로서 수요를 실현해야 한다.
  • 서비스들은 등록 센터에 순조롭게 등록할 수 있다.
  • 모 서비스는 등록 센터를 통해 등록 센터가 어떤 서비스를 사용할 수 있는지 알 수 있고 이 과정은 실시간성을 확보해야 한다.
  • 등록센터는 서비스들이 살아남았는지 실시간으로 알아야 한다.

  • 하나의 서비스 클라이언트가 등록 센터 eureka에 등록되면 이 클라이언트의 정보는 하나의 맵에 존재하며 첫 번째 단계를 실현한다.또한client는 명단을 한 부 뽑아서 명단에 다른 등록 서비스 정보가 있고 실시간성을 확보하기 위해 30s마다 등록센터에서 명단 정보를 한 부 더 뽑아 두 번째 단계를 실현했다.등록센터가 실시간으로 어떤 서비스가 살아남았는지 확인하기 위해서는 모든client가 필요합니다. 일정 시간(기본 30s)마다 등록센터에 심장박동을 보내서 등록센터에 알려주세요. 저는 아직 있습니다. 등록센터의 명단에 이client가 아직 쓸 수 있다고 기록되어 있습니다. 세 번째 단계를 실현했습니다.
    먼저 등록 센터, 즉 서버 서비스를 살펴보면 부트 클래스인 유어카부트 스트랩을 시작하는 방법이 있습니다.
    @Override
    public void contextInitialized(ServletContextEvent event) {
        try {
            initEurekaEnvironment();
            initEurekaServerContext();
            ServletContext sc = event.getServletContext();
            sc.setAttribute(EurekaServerContext.class.getName(), serverContext);
        } catch (Throwable e) {
            logger.error("Cannot bootstrap eureka server :", e);
            throw new RuntimeException("Cannot bootstrap eureka server :", e);
        }
    }
    

    이 방법은 Eureka 방법을 초기화하는 것이다. 현재 나는 특히 등록센터가 어떤 데이터 구조로 클라이언트client 정보를 저장하는지 알고 싶다. 그래서 나는 등록센터가 클라이언트client에 제공하는 등록 인터페이스를 찾아야 한다. 그래서 init Eureka Server Context()에 들어가 보자. Peer Aware Instance Registry라는 인터페이스가 있는데 다시 눌러서 보면 발견된다.
    void register(InstanceInfo info, boolean isReplication);
    

    그것의 실현류를 보아라
    @Override
    public void register(final InstanceInfo info, final boolean isReplication) {
        int leaseDuration = Lease.DEFAULT_DURATION_IN_SECS;
        if (info.getLeaseInfo() != null && info.getLeaseInfo().getDurationInSecs() > 0) {
            leaseDuration = info.getLeaseInfo().getDurationInSecs();
        }
        super.register(info, leaseDuration, isReplication);
        replicateToPeers(Action.Register, info.getAppName(), info.getId(), info, null, isReplication);
    }
    

    replicateToPeers()라는 방법은 등록 센터가 클러스터인 경우 주로 등록이 끝난 후 이 서비스를 다른 eureka 노드에 동기화하는 데 사용된다.
    public void register(InstanceInfo registrant, int leaseDuration, boolean isReplication) {
        try {
            read.lock();
            Map> gMap = registry.get(registrant.getAppName());
            REGISTER.increment(isReplication);
            if (gMap == null) {
                final ConcurrentHashMap> gNewMap = new ConcurrentHashMap>();
                gMap = registry.putIfAbsent(registrant.getAppName(), gNewMap);
                if (gMap == null) {
                    gMap = gNewMap;
                }
            }
            Lease existingLease = gMap.get(registrant.getId());
            ...        ...
        } finally {
            read.unlock();
        }
    }
    

    목측registry는 모든 서비스를 저장하고 그 구조를 클릭해야 한다.
    private final ConcurrentHashMap>> registry
            = new ConcurrentHashMap>>();
    

    가장 바깥쪽은 라인이 안전한 ConcurrentHashMap이고 키 값은registrant입니다.getappName() 은 인스턴스의 응용 프로그램 이름인 first-service입니다.안에는 또 하나의 ConcurrentHashMap(코드 안에는 Map 인터페이스이지만 사실은 틀림없이 ConcurrentHashMap이다. 너는 gNewMap의 대상이 어떻게 new인지 볼 수 있다).안에 이 키는 레지스터드입니다.getId () 실례 id,value는 Lease입니다. 이 안에 서비스 실례와 만료 시간이 저장되어 있습니다.OK, 구체적으로 등록, 오늘 장소 찾으면 안 볼래.
    client 측에 관해서는 정해진 시간에 서비스 명단을 끌어오고, 정해진 시간에 등록 센터의 심장박동을 보내야 한다.그래서 타이머 두 개를 썼어요.
    Discovery Client 클래스에는 다음과 같이 두 타이머를 초기화하는 initScheduledTasks () 방법이 있습니다.
    private void initScheduledTasks() {
        if (clientConfig.shouldFetchRegistry()) {
            // registry cache refresh timer
            int registryFetchIntervalSeconds = clientConfig.getRegistryFetchIntervalSeconds();
            int expBackOffBound = clientConfig.getCacheRefreshExecutorExponentialBackOffBound();
            scheduler.schedule(
                    new TimedSupervisorTask(
                            "cacheRefresh",
                            scheduler,
                            cacheRefreshExecutor,
                            registryFetchIntervalSeconds,
                            TimeUnit.SECONDS,
                            expBackOffBound,
                            new CacheRefreshThread()
                    ),
                    registryFetchIntervalSeconds, TimeUnit.SECONDS);
        }
    
        if (clientConfig.shouldRegisterWithEureka()) {
            int renewalIntervalInSecs = instanceInfo.getLeaseInfo().getRenewalIntervalInSecs();
            int expBackOffBound = clientConfig.getHeartbeatExecutorExponentialBackOffBound();
            logger.info("Starting heartbeat executor: " + "renew interval is: {}", renewalIntervalInSecs);
    
            // Heartbeat timer
            scheduler.schedule(
                    new TimedSupervisorTask(
                            "heartbeat",
                            scheduler,
                            heartbeatExecutor,
                            renewalIntervalInSecs,
                            TimeUnit.SECONDS,
                            expBackOffBound,
                            new HeartbeatThread()
                    ),
                    renewalIntervalInSecs, TimeUnit.SECONDS);
    
        } else {
            logger.info("Not registering with Eureka server per configuration");
        }
    

    소결


    SpringBoot은 통합 유레카를 매우 간단하게 만들었고, 이 편은 빠른 입문 예시를 제공했다.앞으로 등록 센터 클러스터 문제도 고려해야 한다.물론 현재는 더 좋은 등록 센터가 있다. 아리의 나코스는 등록 센터의 기능이 있을 뿐만 아니라 설정 센터의 기능도 계승했다.Eureka의 작업 원리를 이해하면 분포식 시스템의 등록 센터를 더욱 잘 이해하고 앞으로 다른 등록 센터를 배우기 위해 이론적 기반을 마련할 수 있습니다.
    전재 대상:https://juejin.im/post/5d0238d9f265da1b8333889f

    좋은 웹페이지 즐겨찾기