您的位置 首页 java

Java,SpringCloud,微服务注册中心Eureka

注册中心Eureka

Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。

Eureka包含两个组件:

1、Eureka Server(注册中心)

提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,这样Eureka Server中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。

Eureka Server本身也是一个服务,默认情况下会自动注册到Eureka注册中心。

搭建单机版的Eureka Server注册中心,一般配置取消Eureka Server的自动注册逻辑。

Eureka Server通过Register、Get、Renew等接口提供服务的注册、发现和心跳检测等服务。

2、Eureka Client(服务注册)

Eureka Client是一个Java客户端,用于简化与Eureka Server的交互,客户端同时也具备一个内置的、使用轮询(round-robin)负载算法的负载均衡器,在应用启动后,将会向Eureka Server发送心跳,默认周期为30秒,如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒)。

Eureka Client分为两个角色,分别是:Application Service(Service Provider)和Application Client(Service Consumer)。

工程案例:

工程结构:

 父工程springcloud-eureka
子工程----registry-center----Eureka Server
子工程----producer-service----Eureka Client
子工程----consumer-service----Eureka Client  

父工程(springcloud-eureka)

pom .xml—>用于子工程继承

 <?xml version="1.0" encoding="UTF-8"?>
< project  xmlns="#34;
         xmlns:xsi="#34;
         xsi:schemaLocation="  maven -4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.what21.cloud</groupId>
    <artifactId>springcloud-eureka</artifactId>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>registry-center</module>
        <module>producer-service</module>
        <module>consumer-service</module>
    </modules>
    <packaging>pom</packaging>

    <!-- 统一管理JAR包文件 -->
    <properties>
        <project. build .sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <java.version>1.8</java.version>
        <spring-boot.version>2.3.9.RELEASE</spring-boot.version>
        <spring-cloud.version>Hoxton.SR10</spring-cloud.version>
        <alibaba-cloud.version>2.2.5.RELEASE</alibaba-cloud.version>
        <mysql-driver.version>8.0.21</mysql-driver.version>
        <alibaba-druid.version>1.1.22</alibaba-druid.version>
        <mybatis-plus.version>3.4.1</mybatis-plus.version>
        <log4j.version>1.2.17</log4j.version>
        <junit.version>4.12</junit.version>
        <lombok.version>1.16.18</lombok.version>
        <swagger3.version>3.0.0</swagger3.version>
        <project.version>1.0-SNAPSHOT</project.version>
    </properties>

    <!-- 子模块继承 -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <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>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${alibaba-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql-driver.version}</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>${alibaba-druid.version}</version>
            </dependency>
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>${mybatis-plus.version}</version>
            </dependency>
            <!-- pagehelper分页 -->
            <dependency>
                <groupId>com.github.pagehelper</groupId>
                <artifactId>pagehelper-spring-boot-starter</artifactId>
                <version>1.2.13</version>
            </dependency>
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>${log4j.version}</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
                <optional>true</optional>
            </dependency>
            <!--Swagger3-->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-boot-starter</artifactId>
                <version>${swagger3.version}</version>
            </dependency>
            <!-- commons.lang3-->
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-lang3</artifactId>
                <version>3.7</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.73</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

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

</project>  

注册中心工程(registry-center)

pom.xml

 <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="#34;
         xmlns:xsi="#34;
         xsi:schemaLocation=" #34;>
    <parent>
        <artifactId>springcloud-eureka</artifactId>
        <groupId>org.what21.cloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>registry-center</artifactId>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- spring cloud默认配置启动器 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <!-- spring cloud Eureka Server启动器 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>

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

</project>  

application.yml

 server:
  port: 7001

spring:
  application:
    name: registry-center
####################################################################################
eureka:
  instance:
    hostname: localhost
  client:
    # false 表示不向注册中心注册自己
    registerWithEureka: false
    # false表示自己就是注册中心,职责是维护服务清单,不参与检索
    fetchRegistry: false
    #设置eureka server对外服务的地址
    service-url:
      default-zone: {eureka.instance.hostname}:${server.port}/eureka/  
 import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@EnableEurekaServer
@SpringBootApplication
public class RegistryCenterMain70XX {

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

}  

Service Provider工程(producer-service)

pom.xml

 <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="#34;
         xmlns:xsi="#34;
         xsi:schemaLocation=" #34;>
    <parent>
        <artifactId>springcloud-eureka</artifactId>
        <groupId>org.what21.cloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>producer-service</artifactId>

    <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>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
            <optional>true</optional>
        </dependency>
    </dependencies>

</project>  

application.yml

 server:
  port: 9001

spring:
  application:
    name: producer-service
  datasource:
    username: root
    password: root
    url: jdbc:mysql://127.0.0.1:3306/demo?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&tinyInt1isBit=false&allowMultiQueries=true&serverTimezone=GMT%2B8
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      initial-size: 8
      min-idle: 1
      max-active: 20
      max-wait: 60000
      time-between-eviction-runsMillis: 60000
      min-evictable-idle-timeMillis: 300000
      validation-query: select 'x' FROM DUAL
      test-on-borrow: false
      test-on-return: false
      max-open-prepared-statements: 20
      max-pool-prepared-statement-per-connection-size: 20
      filters: stat
      connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
      initialization-mode: always

#eureka
eureka:
  client:
    serviceUrl:
      defaultZone: 

  
 import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@EnableEurekaClient
@SpringBootApplication
@MapperScan(basePackages ={ "org.what21.cloud.mapper"})
public class ProducerService90XX {

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

}  

Service Consumer工程(consumer-service)

pom.xml—>此处略,同Service Provider工程

application.yml

 server:
  port: 8001

#eureka
eureka:
  client:
    serviceUrl:
      defaultZone:   
 import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@EnableEurekaClient
@SpringBootApplication
@MapperScan(basePackages = {"org.what21.cloud.mapper"})
public class ConsumerService80XX {

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

}  
 import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/eureka/center")
public class EurekaController {

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

    /**
     * 获取注册在Eureka中的服务名称
     *
     * @return
     */
    @GetMapping("/getServices")
    public List<String> getServices() {
        List<String> services = new ArrayList<String>();
        // 获取服务
        List<String> serviceNames = discoveryClient.getServices();
        for (String serviceName : serviceNames) {
            // 获取实例
            List<ServiceInstance> serviceInstances = discoveryClient.getInstances(serviceName);
            for (ServiceInstance serviceInstance : serviceInstances) {
                services.add(String.format("%s:%s", serviceName, serviceInstance.getUri()));
            }
        }
        return services;
    }


}  
 import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
@RequestMapping("/user")
public class UserController {

    @RequestMapping(path = "/list", method = {RequestMethod.GET})
    public String list() {
        RestTemplate restTemplate = new RestTemplate();
        String url = "#34;;
        ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class);
        String body = responseEntity.getBody();
        HttpStatus statusCode = responseEntity.getStatusCode();
        int statusCodeValue = responseEntity.getStatusCodeValue();
        HttpHeaders headers = responseEntity.getHeaders();
        StringBuffer result = new StringBuffer();
        result.append("responseEntity.getBody():").append(body).append("n")
                .append("responseEntity.getStatusCode():").append(statusCode).append("n")
                .append("responseEntity.getStatusCodeValue():").append(statusCodeValue).append("n")
                .append("responseEntity.getHeaders():").append(headers).append("n");
        System.out.println(result);
        return body;
    }

}  

把服务都启动:

访问地址:,

EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY’RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.

服务注册到Euraka Server之后,会维护一个心跳连接,去通知Euraka Server存活情况。Euraka Server在运行期间,会统计心跳失败的比例在15分钟内是否低于85%,如果出现低于的情况(在单机调试的时候很容易满足,在生产环境上通常是由于网络不稳定导致),Euraka Server会将当前的实例注册信息保存起来,让这些实例不会过期尽可能地保护这些注册信息,但是在保护期内如果服务刚好这个服务提供者非正常下线了,此时服务消费者就会拿到一个无效的服务实例,此时会调用失败,对于这个问题需要服务消费者端要有一些容错机制,如重试,断路器等。

Euraka自我保护机制开关:

eureka.server.enable-self-preservation=false;参数来关闭保护机制,以确保注册中心可以将不可用的实例正确剔除,默认为true。

非重点代码,省略~

文章来源:智云一二三科技

文章标题:Java,SpringCloud,微服务注册中心Eureka

文章地址:https://www.zhihuclub.com/197448.shtml

关于作者: 智云科技

热门文章

网站地图