美文网首页
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