前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringCloud-Eureka[优雅停服]

SpringCloud-Eureka[优雅停服]

作者头像
用户4919348
发布2019-06-05 17:04:12
1.3K0
发布2019-06-05 17:04:12
举报
文章被收录于专栏:波波烤鸭

  本文我们来介绍下在Eureka中我们如何比较方便的停止服务,并且将服务从注册中心中移除

Eureka的优雅停服

一、Eureka的自我保护模式

什么是自我保护模式

1.自我保护的条件   一般情况下,微服务在 Eureka 上注册后,会每 30 秒发送心跳包,Eureka 通过心跳来判断服务时候健康,同时会定期删除超过 90 秒没有发送心跳服务。 2.有两种情况会导致 Eureka Server 收不到微服务的心跳   a.是微服务自身的原因   b.是微服务与 Eureka 之间的网络故障    通常(微服务的自身的故障关闭)只会导致个别服务出现故障,一般不会出现大面积故障,而(网络故障)通常会导致 Eureka Server 在短时间内无法收到大批心跳。考虑到这个区别,Eureka 设置了一个阀值,当判断挂掉的服务的数量超过阀值时,Eureka Server 认为很大程度上出现了网络故障,将不再删除心跳过期的服务。 3.那么这个阀值是多少呢?   15 分钟之内是否低于 85%;Eureka Server 在运行期间,会统计心跳失败的比例在 15 分钟内是否低于 85%,这种算法叫做 Eureka Server 的自我保护模式。

为什么要自我保护

1.因为同时保留"好数据"与"坏数据"总比丢掉任何数据要更好,当网络故障恢复后,这个 Eureka 节点会退出"自我保护模式"。 2.Eureka 还有客户端缓存功能(也就是微服务的缓存功能)。即便 Eureka 集群中所有节点都宕机失效,微服务的 Provider 和 Consumer都能正常通信。 3.微服务的负载均衡策略会自动剔除死亡的微服务节点。

如何关闭自我保护

修改 Eureka Server 配置文件

代码语言:javascript
复制
#关闭自我保护:true 为开启自我保护,false 为关闭自我保护
eureka.server.enableSelfPreservation=false
#清理间隔(单位:毫秒,默认是 60*1000)
eureka.server.eviction.interval-timer-in-ms=60000

二、如何优雅停服

1.不需要再 Eureka Server 中配置关闭自我保护

2.需要再服务中添加 actuator.jar 包

  注意actuator的依赖在spring-cloud-starter-eureka-server中,所以我们要将Eureka的依赖修改为此

在这里插入图片描述
在这里插入图片描述

3.修改配置文件

  修改服务提供的application.properties文件

代码语言:javascript
复制
spring.application.name=eureka-provider
server.port=9090

# 设置服务注册中心地址,指向另一个注册中心
eureka.client.serviceUrl.defaultZone=http://eureka1:8761/eureka/,http://eureka2:8761/eureka/

# 启用shutdown
endpoints.shutdown.enabled=true
# 禁用密码验证
endpoints.shutdown.sensitive=false

启动服务

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.发送一个关闭服务的 URL 请求

  我们通过HttpClient来发送一个停止服务的请求

代码语言:javascript
复制
<dependency>
   <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.8</version>
</dependency>

创建一个java类

代码语言:javascript
复制
package com.dpb.spring_cloud_eureka_consumer;

import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @program: springcloud-eureka-consumer
 * @description: httpClient停止服务
 * @author: 波波烤鸭
 * @create: 2019-06-03 21:01
 */
public class HttpClientUtil {
    public static String doGet(String url, Map<String, String> param) {

        // 创建Httpclient对象
        CloseableHttpClient httpclient = HttpClients.createDefault();

        String resultString = "";
        CloseableHttpResponse response = null;
        try {
            // 创建uri
            URIBuilder builder = new URIBuilder(url);
            if (param != null) {
                for (String key : param.keySet()) {
                    builder.addParameter(key, param.get(key));
                }
            }
            URI uri = builder.build();

            // 创建http GET请求
            HttpGet httpGet = new HttpGet(uri);

            // 执行请求
            response = httpclient.execute(httpGet);
            // 判断返回状态是否为200
            if (response.getStatusLine().getStatusCode() == 200) {
                resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return resultString;
    }

    public static String doGet(String url) {
        return doGet(url, null);
    }

    public static String doPost(String url, Map<String, String> param) {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);
            // 创建参数列表
            if (param != null) {
                List<NameValuePair> paramList = new ArrayList<>();
                for (String key : param.keySet()) {
                    paramList.add(new BasicNameValuePair(key, param.get(key)));
                }
                // 模拟表单
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList,"utf-8");
                httpPost.setEntity(entity);
            }
            // 执行http请求
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        return resultString;
    }

    public static String doPost(String url) {
        return doPost(url, null);
    }

    public static String doPostJson(String url, String json) {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);
            // 创建请求内容
            StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
            httpPost.setEntity(entity);
            // 执行http请求
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        return resultString;
    }

    public static void main(String[] args) {
        String url ="http://127.0.0.1:9090/shutdown";
        //该url必须要使用dopost方式来发送
        HttpClientUtil.doPost(url);
    }
}

执行main方法,观察服务提供者及注册中心注册的服务

服务端的服务被停止了

在这里插入图片描述
在这里插入图片描述

注册中心的服务也被相应的移除了~

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019年06月03日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Eureka的优雅停服
    • 一、Eureka的自我保护模式
      • 什么是自我保护模式
      • 为什么要自我保护
      • 如何关闭自我保护
    • 二、如何优雅停服
      • 1.不需要再 Eureka Server 中配置关闭自我保护
      • 2.需要再服务中添加 actuator.jar 包
      • 3.修改配置文件
      • 启动服务
      • 5.发送一个关闭服务的 URL 请求
相关产品与服务
微服务引擎 TSE
微服务引擎(Tencent Cloud Service Engine)提供开箱即用的云上全场景微服务解决方案。支持开源增强的云原生注册配置中心(Zookeeper、Nacos 和 Apollo),北极星网格(腾讯自研并开源的 PolarisMesh)、云原生 API 网关(Kong)以及微服务应用托管的弹性微服务平台。微服务引擎完全兼容开源版本的使用方式,在功能、可用性和可运维性等多个方面进行增强。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档