Spring Cloud of Eureka achieve service discovery and registration Feign implement service calls

This blog mainly on Eureka component implements service registration and discovery and Feign component implementation theory calls between the service and the actual operation.

Eureka

Eureka is part of the Spring Cloud Netfix micro-services suite, and SpringBoot can easily build a micro-service integration. SpringCloud integrate it in their own subprojects spring-cloud-netflix, the realization SpringCloud service discovery.

Eureka consists of two components: Eureka Server (server-side) and Eureka Client (client components) .

Eureka Server (server-side components) : also referred to as a service registry, for improving registration and discovery service. After each node starts, it will be registered in Eureka Server, so EurekaServer in the service registry will store all information available information service node, service node can visually see in the interface. Synchronization of data between Eureka Server is accomplished by way of replication.

Eureka Client (client components) : used to simplify interaction with Eureka Server, including service consumers and service producers. The client also has a built-in polling (round-robin) load load balancer algorithms, the application is running, Eureka client registers its own service provided to the registry and periodically sends a heartbeat to update its service lease, heartbeat sent to Eureka Server, the default period is 30 seconds, if Eureka Server does not receive a node in a multiple heartbeat heartbeat period, Eureka Server service node will be removed from this service registry ( default 90 seconds). Eureka also provides client-side caching mechanism, you can query the currently registered service information from the server and cache them locally and periodically refresh the service status, even if all of Eureka Server will hang up, the client can still use the cache consumer information other API services.

Eureka supports high availability configuration, when the film took part in the cluster fails, Eureka will turn automatic protection mode, which allows fault during fragmentation continues to provide discovery and registration services, when the fault slices back to normal, cluster other fragments will synchronize their state back again.

Eureka by heartbeat checks , the client cache and other mechanisms to ensure high system availability, flexibility and scalability.

Eureka achieve service discovery Register

1. Set up a Maven project, put it back the following modules
Here Insert Picture Description
created as
Here Insert Picture Description
you can delete the src directory, because the project only to be placed in other modules springcloud.

2. build a service registry (eureka-server)

Eureka Server是基于springboot的,只要启动一个springboot就可以了。start.spring.io提供了一系列启动模板。创建module,选择Spring initializer.:
Here Insert Picture Description
加入Eureka Server组件
Here Insert Picture Description
创建完成目录

Here Insert Picture Description
生成的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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.changan</groupId>
    <artifactId>eureka-server</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>eureka-server</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR1</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <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>
        </dependencies>
    </dependencyManagement>

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

</project>

修改启动类EurekaServerApplication.java,添加@EnableEurekaServer

package com.szh.ecurekaserver;

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

@SpringBootApplication
@EnableEurekaServer
public class EcurekaServerApplication {

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

}

在默认情况下,服务注册中心也会把自己当做是一个服务,将自己注册进服务注册中心,所以我们可以通过配置来禁用他的客户端注册行为,修改application.properties文件

spring.application.name=eureka-server
#服务注册中心端口号
server.port=8080
#服务注册中心实例的主机名
eureka.instance.hostname=localhost
#是否向服务注册中心注册自己
eureka.client.register-with-eureka=false
#是否检索服务
eureka.client.fetch-registry=false
#服务注册中心的配置内容,指定服务注册中心的位置
eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/

启动应用,并访问http://localhost:8080/即可看到Eureka信息面板,如下:
Here Insert Picture Description
从上图看到,在"Instances currently registered with Eureka"信息中,没有一个实例,说明目前还没有服务注册。接下来创建一个服务提供者eureka-client进行注册测试。

3.创建并注册服务提供者 Eureka Client

创建方式如eureka-server模块类似;在选择组件的时候需要选择对应的组件

Here Insert Picture Description
Here Insert Picture Description
注意要选择Web组件或者其它能够持久运行的。不然会注册失败
Here Insert Picture Description
创建后目录如下

Here Insert Picture Description
生成的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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.changan</groupId>
    <artifactId>eureka-client</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>eureka-client</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR1</spring-cloud.version>
    </properties>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <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>
        </dependencies>
    </dependencyManagement>

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

</project>

启动类EurekaClientApplication.java添加@EnableEurekaClient注解以实现Eureka中的DiscoveryClient实现。

package com.xuan.eurekaclient;

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

@EnableEurekaClient
@SpringBootApplication
public class EurekaClientApplication {

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

@EnableEurekaClient和@EnableDiscoveryClient的区别
spring cloud中discovery service有许多种实现(eureka、consul、zookeeper等等),@EnableDiscoveryClient基于spring-cloud-commons,@EnableEurekaClient基于spring-cloud-netflix。

就是如果选用的注册中心是eureka,那么就推荐@EnableEurekaClient,如果是其他的注册中心,那么推荐使用@EnableDiscoveryClient。

修改配置文件application.properties

spring.application.name=eureka-client
server.port=8090
# 这个是固定死的,这是我们要注册到哪里去
eureka.client.serviceUrl.defaultZone=http://localhost:8080/eureka/

先启动:eureka-server
Here Insert Picture Description
然后启动eureka-client
Here Insert Picture Description
发现多了一个EUREKA-CLIENT,注册成功了

其它问题:
运行一段时间后,在http://localhost:8080/出现
Here Insert Picture Description
如果在Eureka Server的首页看到以下这段提示,则说明Eureka已经进入了保护模式:

Eureka Server在运行期间,会统计心跳失败的比例在15分钟之内是否低于85%,如果出 现低于的情况(在单机调试的时候很容易满足,实际在生产环境上通常是由于网络不稳 定导致),Eureka Server会将当前的实例注册信息保护起来,同时提示这个警告。保护模式主要用于一组客户端和Eureka Server之间存在网络分区场景下的保护。一旦进入保护模式,Eureka Server将会尝试保护其服务注册表中的信息,不再删除服务注册表中的 数据(也就是不会注销任何微服务)。

停止eureka-client后也没有删除节点。

自我保护模式打开时,已关停节点是会一直显示在 Eureka 首页的
关闭自我保护模式后,由于其默认的心跳周期比较长等原因,要过一会儿才会发现已关停节点被自动踢出了

若想尽快的及时踢出,那就只有修改默认的心跳周期参数了

注册中心eureka-server的配置文件application.properties中修改为

spring.application.name=eureka-server
#服务注册中心端口号
server.port=8080
#服务注册中心实例的主机名
eureka.instance.hostname=localhost
#关闭自我保护
eureka.server.enableSelfPreservation=false
# 续期时间,即扫描失效服务的间隔时间(缺省为60*1000ms)
eureka.server.eviction-interval-timer-in-ms: 1000
#是否向服务注册中心注册自己
eureka.client.register-with-eureka=false
#是否检索服务
eureka.client.fetch-registry=false
#服务注册中心的配置内容,指定服务注册中心的位置
eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/

Eureka客户端eureka-client的配置文件application.properties中修改为

spring.application.name=eureka-client
server.port=8090
# 心跳时间,即服务续约间隔时间(缺省为30s)
eureka.instance.lease-renewal-interval-in-seconds: 5
# 发呆时间,即服务续约到期时间(缺省为90s)
eureka.instance.lease-expiration-duration-in-seconds: 15
# 开启健康检查(依赖spring-boot-starter-actuator)
eureka.client.healthcheck.enabled:true
eureka.client.serviceUrl.defaultZone=http://localhost:8080/eureka/

eureka-client的pom.xml增加

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

修改后,关闭eureka-client,注册中心就会很快删除节点

Feign

Feign是简化Java HTTP客户端开发的工具(java-to-httpclient-binder),它的灵感来自于Retrofit、JAXRS-2.0和WebSocket。Feign的初衷是降低统一绑定Denominator到 HTTP API的复杂度,不区分是否为restful。

Feign实现服务调用

1.创建一个eureka-student和一个eureka-grade

创建方式和ureka-server模块类似;在选择组件的时候需要选择对应的组件
Here Insert Picture Description
Here Insert Picture Description
注意要选择Web组件或者其它能够持久运行的。不然会注册失败

Here Insert Picture Description
如上再创建一个eureka-grade

完成后目录如下

Here Insert Picture Description
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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.changan</groupId>
    <artifactId>eureka-student</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>eureka-student</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR1</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.13</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <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>
        </dependencies>
    </dependencyManagement>

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

启动类EurekaClientApplication.java添加@EnableDiscoveryClient @EnableFeignClients注解

package com.szh.eurekastudent;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@EnableDiscoveryClient
@EnableFeignClients
@SpringBootApplication
public class EurekaStudentApplication {

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

}

package com.szh.eurekagrade;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@EnableDiscoveryClient
@EnableFeignClients
@SpringBootApplication
public class EurekaGradeApplication {

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

}

eureka-student的application.properties

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/studentdb?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root

spring.application.name=eureka-student
server.port=8091
eureka.client.serviceUrl.defaultZone=http://localhost:8080/eureka/

eureka-grade的application.properties

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/studentdb?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root

spring.application.name=eureka-grade
server.port=8094
eureka.client.serviceUrl.defaultZone=http://localhost:8080/eureka/

在eureka-student src文件下写client,controller,mapper,pojo,service等包

创建Student实体类

package com.szh.eurekastudent.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {

    private Integer id;

    private String name;

    private String sex;

    private Integer gradeId;
}

创建Grade实体类

package com.szh.eurekastudent.pojo;

import lombok.Data;

@Data
public class Grade {

    private Integer gradeId;

    private String gradeName;

}

Creating StudentMapper Interface

package com.szh.eurekastudent.mapper;

import com.szh.eurekastudent.pojo.Student;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
public interface StudentMapper {

    @Select("select * from student")
    List<Student> selAllStudent();
}

Creating StudentService Interface

package com.szh.eurekastudent.service;

import com.szh.eurekastudent.pojo.Student;

import java.util.List;

public interface StudentService {

    List<Student> selAllStudent();
}

Creating StudentServiceImpl class

package com.szh.eurekastudent.service.impl;

import com.szh.eurekastudent.mapper.StudentMapper;
import com.szh.eurekastudent.pojo.Student;
import com.szh.eurekastudent.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class StudentServiceImpl implements StudentService {
    @Autowired
    private StudentMapper studentMapper;

    @Override
    public List<Student> selAllStudent() {
        return studentMapper.selAllStudent();
    }
}

Creating StudentController class

package com.szh.eurekastudent.controller;

import com.szh.eurekastudent.client.GradeClient;
import com.szh.eurekastudent.pojo.Grade;
import com.szh.eurekastudent.pojo.Student;
import com.szh.eurekastudent.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class StudentController {

    @Autowired
    private StudentService studentService;

    @Autowired
    private GradeClient gradeClient;

    @GetMapping("/students")
    public List<Student> findStudents(){
        return studentService.selAllStudent();
    }

    @GetMapping("/grades")
    public List<Grade> findGrades(){
        return gradeClient.findStudents();
    }
}

Creating GradeClient class

package com.szh.eurekastudent.client;

import com.szh.eurekastudent.pojo.Grade;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.List;

@FeignClient("eureka-grade")
public interface GradeClient {

    @GetMapping("/grades")
    public List<Grade> findStudents();
}

As shown in FIG:
Here Insert Picture Description
write controller, mapper, pojo, service packages and the like in the eureka-gradesrc files, and the same eureka-student.

Create a Student entity class

package com.szh.eurekagrade.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {

    private Integer id;

    private String name;

    private String sex;

    private Integer gradeId;
}

Create a Grade entity class

package com.szh.eurekagrade.pojo;

import lombok.Data;

@Data
public class Grade {

    private Integer gradeId;

    private String gradeName;

}


Creating StudentMapper Interface

package com.szh.eurekagrade.mapper;

import com.szh.eurekagrade.pojo.Grade;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
public interface StudentMapper {

    @Select("select * from grade")
    List<Grade> selAllGrade();
}


Creating StudentService Interface

package com.szh.eurekagrade.service;

import com.szh.eurekagrade.pojo.Grade;

import java.util.List;

public interface StudentService {

    List<Grade> selAllGrade();
}


Creating StudentServiceImpl class

package com.szh.eurekagrade.service.impl;

import com.szh.eurekagrade.mapper.StudentMapper;
import com.szh.eurekagrade.pojo.Grade;
import com.szh.eurekagrade.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class StudentServiceImpl implements StudentService {
    @Autowired
    private StudentMapper studentMapper;


    @Override
    public List<Grade> selAllGrade() {
        return studentMapper.selAllGrade();
    }
}

Creating StudentController class

package com.szh.eurekagrade.controller;

import com.szh.eurekagrade.pojo.Grade;
import com.szh.eurekagrade.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class StudentController {

    @Autowired
    private StudentService studentService;

    @GetMapping("/grades")
    public List<Grade> findStudents(){
        return studentService.selAllGrade();
    }
}

Remember to add @MapperScan ( "com.szh.eurekastudent.mapper") at the start of class two packages

package com.szh.eurekastudent;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@EnableDiscoveryClient
@EnableFeignClients
@MapperScan("com.szh.eurekastudent.mapper")
@SpringBootApplication
public class EurekaStudentApplication {

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

}

Eureka-server is then started from the four modules.

Here Insert Picture Description
Here Insert Picture Description
To see the results
Here Insert Picture Description
see the result of the call service

Here Insert Picture Description
Call eureka-grade success in eureka-student!
Here Insert Picture Description

Guess you like

Origin blog.csdn.net/weixin_42236165/article/details/92842773