SpringCloud第一篇-Eureka:服务的注册与发现-单机和集群模式

spring cloud概述

中国社区:https://springcloud.cc/

在这里插入图片描述

  • 服务发现——Netflix Eureka
  • 客服端负载均衡——Netflix Ribbon
  • 客服端方便REST服务调用组件——Netflix Feign(包含了Ribbon)
  • 断路器——Netflix Hystrix
  • 服务网关——Netflix Zuul
  • 分布式配置——Spring Cloud Config
  • 断路器监控——Hystrix Dashboard
  • 断路器聚合监控——Hystrix Turbine
  • 消息总线——Spring Cloud Bus
  • 服务链路追踪——Spring Cloud Sleuth-组件zipkin

阿里巴巴cloud组件:

Spring Cloud Nacos 作为注册和配置中心 + Spring Cloud Gateway作为网关 + Sentinel 作为熔断服务
https://blog.csdn.net/cdy1996/article/details/87391609
SpringCloud2.x 的权重路由和灰度控制,以及gateway的路由持久化
https://blog.csdn.net/cdy1996/article/details/94316726

springboot actuator的组件编写
https://blog.csdn.net/cdy1996/article/details/90314361

分布式流量控制框架sentinel初探
https://blog.csdn.net/abreaking2012/article/details/82116993
SpringCloud使用Sentinel 代替 Hystrix
https://blog.csdn.net/Mr_lyh/article/details/86700810

Prometheus采集时序数据
https://www.jianshu.com/p/93c840025f01
Spring Boot Metrics监控之Prometheus&Grafana
https://www.jianshu.com/p/afc3759e75b9

典型的结构图如下
在这里插入图片描述

Eureka是Spring Cloud Netflix的一个子模块,也是核心模块之一。用于云端服务发现,一个基于REST的服务,用于定位服务,以实现云端中间层服务发现和故障转移。

服务注册与发现对于微服务系统来说非常重要。有了服务发现与注册,你就不需要整天改服务调用的配置文件了,你只需要使用服务的标识符,就可以访问到服务。他的功能类似于dubbo的注册中心(register)。

  • 服务发现:服务发现是微服务基础架构的关键原则之一。试图着手配置每个客户端或某种格式的约定可以说是非常困难的和非常脆弱的。Eureka是Netflix服务发现的一种服务和客户端。这种服务是可以被高可用性配置的和部署,并且在注册的服务当中,每个服务的状态可以互相复制给彼此。

  • 服务注册:当一个客户端注册到Eureka,它提供关于自己的元数据(诸如主机和端口,健康指标URL,首页等)Eureka通过一个服务从各个实例接收心跳信息。如果心跳接收失败超过配置的时间,实例将会正常从注册里面移除

这里写图片描述

工具及依赖版本

  1. IDE使用IDEA2017版
  • IDEA 破解方法:
    填入下面的license server:

http://intellij.mandroid.cn/
  http://idea.imsxm.com/
  http://idea.iteblog.com/key.php

  1. maven3.0

  2. Spring Boot 1.5.x ,Spring Cloud版本为Dalston.RELEASE

###Eureka
Spring Cloud Netflix的Eureka ,eureka是一个服务注册和发现模块。
2个工程:

  • eureka-serve工程作为服务注册中心,即Eureka Serve
  • service-hello另一个作为Eureka Client

####application.yml
eureka-server的application.yml配置如下
service-hello的配置也和它一样只是artifactId不同

<?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>com.bamboo</groupId>
    <artifactId>eureka-server</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>


    <repositories><!-- 镜像 -->
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

    <parent><!-- spring-boot -->
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>


    <dependencyManagement><!-- spring-cloud 依赖 -->
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.RC1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

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

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



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





</project>

####java代码

eureka-server 的Application.java

package comm.bamboo;

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



/**
 *
 *EurekaServer  注册监控服务:启动
 *
 * Created by bamboo on 2017/10/19.
 */
@SpringBootApplication
@EnableEurekaServer
public class Application {

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

}

只需要一个注解@EnableEurekaServer

service-hello 的Application.java

package comm.bamboo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * 
 * 服务客户端
 * 
 *  service-hello Application
 */
@SpringBootApplication
@EnableEurekaClient
@RestController
public class Application {

    /**
     * A main() so we can easily run these routing rules in our IDE
     */
    public static void main(String... args) throws Exception {
        SpringApplication.run(Application.class, args);
    }

    @Value("${server.port}")
    String port;
    @RequestMapping("/hello")
    public String home() {
        return "hello from port:" +port;
    }



}


@EnableEurekaClient是不够的,还需要在配置文件中注明自己的服务注册中心的地址

yml配置

eureka-server的application.yml

server:
  port: 8761
eureka:
  instance:
    hostname: localhost
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
     defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

通过eureka.client.registerWithEureka:false和fetchRegistry:false来表明自己是一个eureka server.否则默认认为其为客户端

service-hello的application.yml

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
server:
  port: 8762
spring:
  application:
    name: service-hello

需要指明spring.application.name,这个很重要,这在以后的服务与服务之间相互调用一般都是根据这个name

###启动工程
分别启动eureka-server启动注册服务和service-hello客户端

打开http://localhost:8761 ,即eureka server 的注册服务网址:
这里写图片描述
可以看到这一行已经显示出来了服务名称(SERVICE-HELLO)和服务的状态(UP (1) - DESKTOP-180I6SH:service-hello:8762)

SERVICE-HELLO	n/a (1)	(1)	UP (1) - DESKTOP-180I6SH:service-hello:8762

你会发现一个服务已经注册在服务中了,服务名为SERVICE-HELLO ,端口为7862

这时打开 http://localhost:8762/hello ,你会在浏览器上看到 :

hello from port:8762

保护模式

当我们关闭客户端service-hello的运行,打开注册服务的管理页面
会看到如下红字和红圈部分
这里写图片描述
发现我们把客户端关了但是服务监控上依然显示为UP运行状态,这显然是不合理的。同时会出现红字部分

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.

这段提示,则说明Eureka已经进入了保护模式。

保护模式主要用于一组客户端和Eureka Server之间存在网络分区场景下的保护。一旦进入保护模式,Eureka
Server将会尝试保护其服务注册表中的信息,不再删除服务注册表中的数据(也就是不会注销任何微服务)。

详见:https://github.com/Netflix/eureka/wiki/Understanding-Eureka-Peer-to-Peer-Communication

如何解决Eureka Server不踢出已关停的节点的问题

(1) Eureka Server端:配置关闭自我保护,并按需配置Eureka Server清理无效节点的时间间隔。

server:
  port: 8761
eureka:
  instance:
    hostname: localhost
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
     defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

#新增的配置部分
  server:
       enable-self-preservation: false  # 设为false,关闭自我保护
       eviction-interval-timer-in-ms: 4000  # 清理间隔(单位毫秒,默认是60*1000)

(2) Eureka Client端:配置开启健康检查,并按需配置续约更新时间和到期时间。

server:
  port: 8762
spring:
  application:
    name: service-hello
    
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

  #新增的配置部分
  healthcheck:
        enabled: true # 开启健康检查(需要spring-boot-starter-actuator依赖)
  instance:
      lease-expiration-duration-in-seconds: 30  # 续约更新时间间隔(默认30秒)
      lease-renewal-interval-in-seconds: 10 # 续约到期时间(默认90秒)


客户端的pom需要加入如下依赖

         <!--暴露各种指标-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

重新启动注册服务和客户端,你会发现监控页面出现如下红色字,但是过几分钟刷新后会看到客户端的状态已经不再应用列表中了,说明已经起作用了

THE SELF PRESERVATION MODE IS TURNED OFF.THIS MAY NOT PROTECT INSTANCE EXPIRY IN CASE OF NETWORK/OTHER PROBLEMS.

关闭保护模式,在网络或其他问题的情况下对实例没有有效的保护
这里写图片描述

注意:
更改Eureka更新频率将打破服务器的自我保护功能,生产环境下不建议自定义这些配置。
详见:https://github.com/spring-cloud/spring-cloud-netflix/issues/373

Eureka注册中心加入权限

注册中心在公网中当然不想让其他人使用,那么可以配置账号密码防止别人轻易使用的问题。

  1. 加入注册中心需要引入jar,eureka-server在pom.xml加入
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-security</artifactId>
</dependency>
  1. 配置文件新建一个bootstrap.yml文件
security:
    basic:
      enabled: true
    user:
      name: admin
      password: 123

详细文档参考:Eureka Server 的身份认证

关于spring-cloud-starter-eureka-server 和 spring-cloud-starter-netflix-eureka-server

spring-cloud-starter-eureka-server 已经废弃,spring2.0中已经不再使用;spring-cloud-starter-netflix-eureka-server是替代引用!!
spring boot、spring cloud里面很多引用、配置更新的很快

集群搭建

修改hosts,属性-安全-user-读写权限-确定

c:\windows\system32\drivers\etc下面的hosts文件修改:
127.0.0.1 master slave1 slave2

配置三个yml,对应的端口号配置如下
application-0.yml:master:8000
application-1.yml:slave1 :8001
application-2.yml:slave2:8002

application-0.yml为例

server:
  #服务端口
  port: 8000
spring:
  application:
    #应用名称
    name: eureka-server
eureka:
  server:
    #关闭自我保护【用于本地测试时配置-快速剔除失效服务】
    enable-self-preservation: false
    #检查失效服务间隔【用于本地测试时配置-快速剔除失效服务】
    eviction-interval-timer-in-ms: 9000
  instance:
    #实例主机名(建议使用IP)
    hostname: master
    #自定义实例ID(默认为 主机名:应用名:端口号)
    instance-id: ${eureka.instance.hostname}:${server.port}
  client:
    #非集群服务配置,不将自己当客户端注册到自己
#    register-with-eureka: false
    #非集群服务配置,不从服务端拉取服务列表
#    fetch-registry: false
    #指定eureka集群所有服务地址,逗号分隔
    #如果当前服务是eureka服务端,当前服务地址也要包含在内,服务地址结构:http://[hostname]:[port]/eureka/
    #其中hostname建议最好与配置中的eureka.instance.hostname对应,因为服务端会根据hostname从service-url中区分
    #出本机服务url和集群其它伙伴服务url,如果不对应,会将自身也当成伙伴服务,伙伴服务列表在eureka主页上
    #DS Replicas部分展示
    service-url:
      defaultZone: http://master:8000/eureka/,http://slave1:8001/eureka/,http://slave2:8002/eureka/
management:
  endpoints:
    web:
      exposure:
        #actuator监控中心,开放所有权限
        include: '*'
#################################### eureka 集群配置示例 start #################################
#eureka:
#  server:
#    #关闭自我保护【用于本地测试时配置-快速剔除失效服务】
#    enable-self-preservation: false
#    #检查失效服务间隔【用于本地测试时配置-快速剔除失效服务】
#    eviction-interval-timer-in-ms: 1000
#  instance:
#    #实例主机名(建议使用IP)
#    hostname: 127.0.0.1
#    #自定义实例ID
#    instance-id: ${eureka.instance.hostname}:${server.port}
#    #续约更新时间间隔【用于本地测试时配置-快速剔除失效服务】
#    lease-renewal-interval-in-seconds: 3
#    #续约到期时间【用于本地测试时配置-快速剔除失效服务】
#    lease-expiration-duration-in-seconds: 9
#  client:
#    #指定eureka集群所有服务地址,逗号分隔
#    #如果当前服务是eureka服务端,当前服务地址也要包含在内,服务地址结构:http://[hostname]:[port]/eureka/
#    #其中hostname建议最好与配置中的eureka.instance.hostname对应,因为服务端会根据hostname从service-url中区分
#    #出本机服务url和集群其它伙伴服务url,如果不对应,会将自身也当成伙伴服务,伙伴服务列表在eureka主页上
#    #DS Replicas部分展示
#    service-url:
#      defaultZone: http://127.0.0.1:8001/eureka/,http://localhost:8002/eureka/,http://192.168.10.110:8003/eureka/
#################################### eureka 集群配置示例 end #################################

关闭自我保护【用于本地测试时配置-快速剔除失效服务】
检查失效服务间隔【用于本地测试时配置-快速剔除失效服务】
register-with-eureka: false非集群服务配置,不将自己当客户端注册到自己
fetch-registry: false非集群服务配置,不从服务端拉取服务列表
defaultZone:多个服务逗号分隔

依次启动三个配置服务;
application.yml 方式或者使用java -jar euraker.java -spring.profiles.active=1

spring:
  profiles:
    active: 2

http://slave1:8001/
在这里插入图片描述
可以看到集群模式已经启动起来了,你可以关闭一个服务看看状态;

手工恢复服务和剔除服务api

开发SpingCloud项目时,一个开发组可能有多个人启动服务,将服务注册到Eureka中。当你想本机debug调试代码的时候,由于负载均衡的特性,很多时候服务调用跑不到你本机代码上。这时我们可以通过postman给eureka发送请求,剔除服务或者将剔除的服务恢复回来,方法如下:

1.剔除服务:OUT_OF_SERVICE

put请求:http://127.0.0.1:30000/eureka/apps/SERVICE-AAA/192.168.0.1:service-aaa:8080/status?value=OUT_OF_SERVICE

2.恢复服务:UP

put请求:http://127.0.0.1:30000/eureka/apps/SERVICE-AAA/192.168.0.1:service-aaa:8080/status?value=UP

说明:
1)127.0.0.1:30000为eureka的ip和端口
2)SERVICE-AAA为服务名称(eureka后台页面查看)
3)192.168.0.1:service-aaa:8080为想要剔除/恢复的实例(eureka后台页面查看)
4)PUT请求的header设置Authorization:xxx(登录eurekaF12查看)

在这里插入图片描述

参考文档

注册中心集群搭建

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值