美文网首页
SpringCloud那些事-Eureka

SpringCloud那些事-Eureka

作者: Dane_404 | 来源:发表于2019-12-02 17:25 被阅读0次

    Eureka,古希腊词语,意思为找到了、我发现了,在微服务架构中,它主要是作为注册中心,实现服务治理功能。Eureka 就像是个平台,例如滴滴、家政服务这些。

    Eureka 入门

    创建 Eureka 注册中心

    我们先来创建个Eureka Demo 工程,首先编写创建个聚合工程,pom依赖如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.2.1.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.dane.springcloud</groupId>
        <artifactId>springcloud</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>springcloud</name>
        <packaging>pom</packaging>
        <description>Demo project for Spring Boot</description>
    
        <properties>
            <java.version>1.8</java.version>
            <spring-cloud.version>Hoxton.RELEASE</spring-cloud.version>
        </properties>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>${spring-cloud.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
    
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-test</artifactId>
                    <scope>test</scope>
                    <exclusions>
                        <exclusion>
                            <groupId>org.junit.vintage</groupId>
                            <artifactId>junit-vintage-engine</artifactId>
                        </exclusion>
                    </exclusions>
                </dependency>
            </dependencies>
    
        </dependencyManagement>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    </project>
    

    然后创建编写 Eureka 注册中心 Module:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.dane.eureka</groupId>
        <artifactId>eureka</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>eureka</name>
        <description>Demo project for Spring Boot</description>
    
        <parent>
            <groupId>com.dane.springcloud</groupId>
            <artifactId>springcloud</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            </dependency>
        </dependencies>
    
    </project>
    

    启动类加入注解 @EnableEurekaServer:

    @EnableEurekaServer
    @SpringBootApplication
    public class EurekaApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(EurekaApplication.class, args);
        }
    }
    

    配置文件,注意的是 eureka.client.register-with-eureka 要设置为false,不然启动把自己当作客户端向自己注册,会报错。

    spring.application.name=eureka-server
    server.port=8761
    #是否注册自己到注册中心,默认是true
    eureka.client.register-with-eureka=false
    #由于注册中心的职责就是维护服务实例,它并不需要去检索服务,所以也设置为false
    eureka.client.fetch-registry=false
    

    接着启动程序访问http://localhost:8761/

    image.png
    编写服务提供者

    新建 Module user-service,,然后加入相关依赖

    <parent>
        <groupId>com.dane.springcloud</groupId>
        <artifactId>springcloud</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>
    

    启动类加入注解 @EnableDiscoveryClient:

    @EnableDiscoveryClient
    @SpringBootApplication
    public class UserserviceApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(UserserviceApplication.class, args);
        }
    }
    

    加入配置:

    spring.application.name=user-service
    server.port=8081
    eureka.client.service-url.defaultZone = http://localhost:8761/eureka
    #采用ip注册
    eureka.instance.prefer-ip-address=true
    # 定义实例ID格式
    eureka.instance.instance-id=${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}
    

    编写UserController

    @RestController
    @RequestMapping("/user")
    public class UserController {
    
        @GetMapping("/hello")
        public String hello(){
            return "hello";
        }
    }
    

    启动程序可以看到:


    image.png
    编写服务消费者

    新建 Module consume,pom 配置、启动类注解和 Module userservice 一样,不过配置文件就不一样:

    spring.application.name=consume
    server.port=8082
    

    配置 RestTemplate,RestTemplate 提供了多种便捷访问远程 Http 服务的方法:

    @Configuration
    public class RestConfig {
        
        @Bean
        public RestTemplate restTemplate(){
            return new RestTemplate();
        }
    }
    

    然后是 Controller ,这里路径是写服务的名词,也就是application.name:

    @RestController
    public class ConsumeController {
    
        @Autowired
        private RestTemplate restTemplate;
    
        @Autowired
        private DiscoveryClient discoveryClient;
    
    
        @GetMapping("/callhello")
        public String callHello(){
    
            List<ServiceInstance> instances = discoveryClient.getInstances("user-service");
            ServiceInstance instance = instances.get(0);
            String url = "http://"+instance.getHost()+":"+instance.getPort()+"/user/hello";
            System.out.println(url);
           return restTemplate.getForObject(url,String.class);
        }
    }
    
    

    这样就可以访问到了


    image.png

    Eureka 高可用

    上面的入门例子中,所有服务都通过 Eureka 去提供给调用者,当 Eureka 服务挂了是时候,整个系统就停止工作了,所以 Eureka 必须搭建集群来保证。

    Eureka 集群只需要在配置中指定另外多个 Eureka 的地址就可以了,比如有 master 和 slaveone 两台机器,我们需要将 master 注册到 slaveone 上面,slaveone 也注册到 master 上面,我们可以通过开发工具这样模拟:

    在 Eureka Module 创建 application-master.properties 和 application-slaveone.properties:


    image.png

    application-master.properties

    server.port=8761
    eureka.client.service-url.defaultZone = http://localhost:8762/eureka
    

    application-slaveone.properties

    server.port=8762
    eureka.client.service-url.defaultZone = http://localhost:8761/eureka
    

    application.properties

    spring.application.name=eureka-server
    spring.profiles.active=master
    

    先启动程序,然后修改spring.profiles.active=master 为 spring.profiles.active=slaveone,然后添加多一个springboot:


    image.png
    image.png

    接着启动,然后在服务提供者 userservice,它要向多个注册中心注册自己,只需要配置:

    eureka.client.service-url.defaultZone = http://localhost:8761/eureka,http://localhost:8762/eureka
    

    然后重新启动就可以了,可以在每个 Eureka 看到:


    image.png

    Eureka 开发过程中的配置

    在实际开发过程中,我们可能会不停的重启服务,由于 Eureka 有自己的保护机制,故节点下线后,服务信息还有一直保存在 Eureka 中,我们可以通过一些配置方便我们使用,当然,只是在开发环境下使用,生产环境不推荐

    Eureka 注册中心配置:

    #关闭自我保护
    eureka.server.enable-self-preservation=false
    #设置清理时间间隔,默认是60s
    eureka.server.eviction-interval-timer-in-ms=5000
    

    服务提供者在注册中心注册后,或保持一个心跳,告诉注册中心“我还活着”,这个行为叫做续约,有一个心跳间隔和超时时间,为了方便开发,我们也可以调整:

    #默认90秒
    eureka.instance.lease-expiration-duration-in-seconds= 5
    #默认30秒
    eureka.instance.lease-renewal-interval-in-seconds= 5
    

    消费者也是定期的拉取服务列表,我们也可以修改方便开发:

    #默认30秒
    eureka.client.registry-fetch-interval-seconds= 5
    

    以上所有方便开发的,都不要在生成环境修改

    Eureka 服务上下线监控

    可能有特定需求需要知道服务上下线,可以进行监控,注意的是,集群环境下,要注意多触发情况。

    @Component
    public class EurekaStateChangeListener {
    
        @EventListener
        public void listen(EurekaRegistryAvailableEvent event){
            System.out.println("注册中心启动");
        }
    
        @EventListener
        public void listen(EurekaServerStartedEvent event){
            System.out.println("EurekaServer 启动");
        }
    
        @EventListener
        public void listen(EurekaInstanceCanceledEvent event){
            System.out.println(event.getServerId()+"\t"+event.getAppName()+"服务下线");
        }
    
        @EventListener
        public void listen(EurekaInstanceRegisteredEvent event){
            System.out.println(event.getInstanceInfo().getAppName()+"服务注册");
        }
    
        @EventListener
        public void listen(EurekaInstanceRenewedEvent event){
            System.out.println(event.getServerId()+"\t"+event.getAppName()+"服务进行续约");
        }
    
    }
    

    相关文章

      网友评论

          本文标题:SpringCloud那些事-Eureka

          本文链接:https://www.haomeiwen.com/subject/awxfgctx.html