spring-cloud的eureka服务注册与发现的搭建

2020-05-22  本文已影响0人  牙齿不帅

通常我们会遇到这样的问题!如:a服务如何调用b服务,就是我如何找到你?或者我如何让别人知道我?之前我们解决的办法通常是a服务持有b服务的链接,c服务想调用b服务的时候,也是c通过持有b服务的链接,等等到其他的服务,而这样的显然不够弹性,虽然b服务可以对外暴露一个通用的域名接口,但是对其的配置信息也是过于的僵硬,不能随意的修改,怎么办呢?计算机中大多数问题都可以通过加一层来解决!没错,eureka就是中间的那一层,eureka注册中心就是一个服务介绍所,你想要什么服务就来我这里,你能提供什么服务也注册到我这里,其就是用来使微服务相互知晓的桥梁。

ok,开始我们的工程搭建吧。最简单的模式,我们至少需要两个工程对吧,一个提供eureka注册中心的eureka-server工程,一个提供hello服务的hello-service工程。

eureka-server工程

关于spring-cloud与spring-boot之间有版本的对应匹配关系如下:【spring-cloud可能又有最新版了】

Finchley——>兼容Spring Boot 2.0.x,不兼容Spring Boot 1.5.x
Dalston和Edgware——>兼容Spring Boot 1.5.x,不兼容Spring Boot 2.0.x
Camden——>兼容Spring Boot 1.4.x,也兼容Spring Boot 1.5.x
Brixton——>兼容Spring Boot 1.3.x,也兼容Spring Boot 1.4.x
Angel——>兼容Spring Boot 1.2.x
我们配置的是spring-cloud-Brixton.SR5,spring-boot-1.3.7.RELEASE【具体见之后的pom.xml】

1.eurekaserver项目构建图如下:

请忽略application-peer2.properties配置文件,这是我们
构建两个节点的eureka的配置,增加了容错性,但是本文暂时不做介绍。往下继续我们的pom.xml配置。


image.png

eureka-server:pom.xml 如下:

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>cong</groupId>
    <artifactId>eureka-server</artifactId>
    <version>1.0</version>
    <packaging>jar</packaging>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.7.RELEASE</version>
        <relativePath/>
    </parent>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server -->
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
        </dependency>


    </dependencies>


    <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter -->
    <dependencyManagement>

        <dependencies>

            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Brixton.SR5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

eureka-server:Application.java

package com.con;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;


@EnableEurekaServer
@SpringBootApplication
public class Application {
    public static void main(String args[]){
        new SpringApplicationBuilder(Application.class).web(true).run(args);
    }

}

eureka-server:application-peer1.properties 如下:

spring.application.name=eureka-server
server.port=1111
#实例的名字,映射ip,ip可能会变化,但是实例不变
eureka.instance.hostname=peer1
#是否注册服务
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
#关闭自身保护机制:防止关闭的实例无法被注册中心剔除的问题,如果开启:实例一段时间是受到保护,不被剔除。
eureka.server.enable-self-preservation=false
#如果不配置会报错:Network level connection to peer localhost; retrying after delay
eureka.client.service-url.defaultZone=http://peer1:1111/eureka

#java -jar target/eureka-server-1.0.jar --spring.profiles.active=peer1
# 关于:配置界面的参数
# Renew: 服务续约
# Eureka Client 会每隔 30 秒发送一次心跳来续约。
# 通过续约来告知 Eureka Server 该 Eureka Client 运行正常,没有出现问题。
# 默认情况下,如果 Eureka Server 在 90 秒内没有收到 Eureka Client 的续约,Server 端会将实例从其注册表中删除,此时间可配置,一般情况不建议更改。

#RENEWALS ARE LESSER THAN THE THRESHOLD. THE SELF PRESERVATION MODE IS TURNED OFF.THIS MAY NOT PROTECT INSTANCE EXPIRY IN CASE OF NETWORK/OTHER PROBLEMS.
#RENEWALS小于阀值。自身保护模式关闭。在有网络或其他问题的时候可能不会保护到期的实例。

#Uptime 运行的时间

peer1是指映射peer1到本地ip,如果线上的话我们可能需要映射到我们的域名或者ip,能够使其他的微服务器访问到即可。
host文件添加如下:

127.0.0.1   peer1

application-peer1.properties参数说明:
1.只有一个主的注册中心服务eureka-server启动,所以eureka.client.register-with-eureka=false不需要进行注册服务。

  1. eureka.client.service-url.defaultZone=http://peer1:1111/eureka
    是必须配置的,由于eureka也是一个注册服务,既然是一个注册的服务就需要给我发送心跳,告诉我你还活着。

以上,工程配置完成,打出jar包运行如下命令,启动工程:spring.profiles.active=peer1代表加载的是:application-peer1.properties配置文件,

$ java -jar target/eureka-server-1.0.jar --spring.profiles.active=peer1

这时我们浏览eureka注册中心界面:
http://localhost:1111/
提示:No instances available,没有任何可用的实例。正常因为我们还没有注册任何微服务呢,ok,有个红色的错误:

RENEWALS ARE LESSER THAN THE THRESHOLD. THE SELF PRESERVATION MODE IS TURNED OFF.THIS MAY NOT PROTECT INSTANCE EXPIRY IN CASE OF NETWORK/OTHER PROBLEMS.
#RENEWALS小于阀值。自身保护模式关闭。在有网络或其他问题的时候可能不会保护到期的实例

啥意思?就是说你的服务没有在保护内,如果出现网络问题啦,或者其他的情况啦,你的服务会被移除掉,如果是true,就会保护其一段时间不被移除。【具体什么样的条件移除和保护,我暂时还没有检测,配置文件中是一个默认的说明】ok,开始我们的eureka-client工程。

2.eureka-client项目目录结构图: image.png

eureka-client:pom.xml文件和eureka-server的很像,添加了一个:spring-cloud-starter-eureka依赖。

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>cong</groupId>
    <artifactId>eureka-client</artifactId>
    <version>1.0</version>
    <packaging>jar</packaging>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.7.RELEASE</version>
    </parent>
    <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server -->
    <dependencies>
        <dependency>
          <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
    </dependencies>
    <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter -->
    <dependencyManagement>
        <dependencies>
            <dependency>
               <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Brixton.SR5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

eureka-client:Application.java,留意EnableEurekaClient注解配置

package com.con;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@EnableEurekaClient
@SpringBootApplication
public class Application {
    public static void main(String args[]){
        new SpringApplicationBuilder(Application.class).web(true).run(args);
    }
}

eureka-client:HelloController文件,提供hello接口

package com.con;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.Random;

@RestController
public class HelloController {
    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private org.springframework.cloud.client.discovery.DiscoveryClient client;

    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String index()throws Exception {
        ServiceInstance instance = client.getLocalServiceInstance();
        int sleepTime = new Random().nextInt(3000);
        logger.info("sleepTime:"+sleepTime);
        Thread.sleep(sleepTime);
        logger.info("hello host:" + instance.getHost() + " service_id:" + instance.getServiceId());
        return "hello world";
    }
}

eureka-client:application.properties 如下:

#server.port=1111
eureka.instance.hostname=localhost
#eureka.client.register-with-eureka=false
#eureka.client.fetch-registry=false
#注册的服务名
spring.application.name=hello-service
#eureka.client.service-url.defaultZone=http://peer1:1111/eureka/,http://peer2:1112/eureka/
eureka.client.service-url.defaultZone=http://peer1:1111/eureka/

#java -jar target/eureka-client-1.0.jar --server.port=8081
#java -jar target/eureka-client-1.0.jar --server.port=8082
#服务注册与提供者
#用来模块化,形成微服务的

以上,eukera-client配置完成,启动eukera-client工程,我们以8081端口启动,也可以在配置文件中配置。

$ java -jar target/eureka-client-1.0.jar --server.port=8081

注册中心界面:http://localhost:1111/ 显示了我们的hello-service,这说明我们的hello服务注册成功了!

image.png
我们接着请求:http://localhost:8081/hello
image.png
有结果了,但这还不够,我们直接访问了hello接口,其他服务如何调用呢?不能直接访问吧,那又回到了原始社会了。ok,我们来配置消费者服务调用hello服务。

3.消费者服务:ribbon-consumer项目目录结构图:

image.png

ribbon-consumer:pom.xml

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>ribbon-consumer</groupId>
    <artifactId>ribbon-consumer</artifactId>
    <version>1.0</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.7.RELEASE</version>
        <relativePath/>
    </parent>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server -->
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-ribbon</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.6</version>
        </dependency>

        <dependency>
            <!--短容器><groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
        </dependency>

    </dependencies>


    <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter -->
    <dependencyManagement>

        <dependencies>

            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Brixton.SR5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

ribbon-consumer:application.properties

spring.application.name=ribbon-consumer
server.port=9000
eureka.client.service-url.defaultZone=http://peer1:1111/eureka/

#hello-service.ribbon.NFLoadBalancerPingClassName=com.netflix.loadbalancer.PingUrl

#java -jar target/ribbon-consumer-1.0.jar

ribbon-consumer:ConsumerApplication.java如下:
Ribbon是一个负载均衡方式的调用服务,通过其调用者可以通过负载均衡的方式来调用注册的微服务。

package com.consumer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@EnableDiscoveryClient
@SpringBootApplication
public class ConsumerApplication {

    @Bean
    @LoadBalanced
    RestTemplate restTemplate(){//LoadBalanced负载均衡
        return new RestTemplate();
    }

    public static void main(String args[]){
        SpringApplication.run(ConsumerApplication.class,args);
    }

}

ribbon-consumer:ConsumerController.java如下:

package com.consumer;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ConsumerController {

    @Autowired
    HelloService helloService;

    @RequestMapping(value = "/ribbon-consumer",method = RequestMethod.GET)
    public String helloConsumer(){
        return helloService.helloService();
    }
}

ribbon-consumer:HelloService.java如下:
hello服务的调用封装在了service层,RestTemplate已经在Application中配置启动加载。HystrixCommand是断路器,这个是spring-cloud另一个服务功能,这里不做介绍了。

package com.consumer;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class HelloService {
    @Autowired
    RestTemplate restTemplate;

    /**
     * 断容器默认时间好像是1秒,如果服务在1s没有返回,那么就会走fallbackMethod方法。并不是书中说的2s。
     * 注意:被gate-way调用的时候,如大于1s并没有执行短容器,gate-way似乎有1s超时的异常打印。
     * @return
     */
    @HystrixCommand(fallbackMethod = "helloFallback")
    public String helloService(){
        long start = System.currentTimeMillis();
        String r = restTemplate.getForEntity("http://HELLO-SERVICE/hello",String.class).getBody();
        long end = System.currentTimeMillis();
        System.out.println("spend time:"+(end-start));
        return r;
    }

}

配置文件已经配置了端口,直接启动工程:

java -jar target/ribbon-consumer-1.0.jar

我们发现注册中心的界面又多了:10.88.35.92:ribbon-consumer:9000
服务

image.png
调用hello服务接口,返回了我们想要的结果:
http://localhost:9000/ribbon-consumer
image.png

以上,是eureka注册中心的微服务注册和微服务的调用的整个搭建过程,还是比较简单的基本就是工程的配置,本文只是一个简单工程搭建,并不是
深入的理解注册中心,更多深入的参数配置请查看官方网站吧。

上一篇下一篇

猜你喜欢

热点阅读