在之前的文章中我们提到服务的优雅下线,见:

SpringCloud服务如何在Eureka安全优雅的下线

但这个对于ribbon调用其实是不平滑的,shutdown请求到后服务就马上关闭了,服务消费此时未感应到服务下线了,会仍然往这个服务发送请求,从而导致报错。

简介方案有:一、开启重试(前提是保证接口做好幂等处理)。

二、使用pause来下线服务(推荐)

操作步骤如下:

1、  服务提供方配置

后台端点禁用安全校验

management.security.enabled=false

# 开启服务暂停端点

endpoints.pause.enabled=true

# 禁用密码验证

endpoints.pause.sensitive=false

由于这些管理端点比较敏感需要加一个filter来过滤IP白名单

代码参考:对actuator的管理端点进行ip白名单限制(springBoot添加filter)

2、  服务消费者

# 2秒拉取最新的注册信息

eureka.client.registry-fetch-interval-seconds=2

# 2秒刷新ribbon中的缓存信息
ribbon.ServerListRefreshInterval=2000

3、发布流程

Curl –X POST http://127.0.0.1:端口/pause

Sleep 6S

Kill -9

Java –jar xx.jar启动服务

curl -I  -m  10  -o  /dev/null  -s  -w  %{http_code} http://127.0.0.1:端口/health 来检测是否是200,持续N秒,如果失败则需要回滚发布并终止后续节点的发布。

说明:这里的sleep的最大理论值为: eureka.client.registry-fetch-interval-seconds + (ribbon.ServerListRefreshInterval+eureka.client.registry-fetch-interval-seconds) = 6S;

后面括号里的相加是因为这2个定时有可能恰好非常巧的错过了才会出现,为了安全起见我们可以基于上述的公式再加个一两秒。

为什么要访问/health呢?主要是为了对服务进行预热(主要是数据库连接池/jedis连接池等),这样当超时时间很多的服务在第一次请求时不会出现超时。

4、eureka

# 5秒清理一次过期的注册信息

# 如果是按照上面的流程来执行发布则其实可以不配,使用默认值

eureka.server.eviction-interval-timer-in-ms=5000

# 关闭自我保护

# 内网服务不需要进行分区保护

eureka.server.enable-self-preservation=false

# 服务注册5秒即可被发现
eureka.server.response-cache-update-interval-ms=5000

三、扩展tomcat的shutdownhook(不推荐,如果切换为成其他容器则无效了)

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import org.apache.catalina.connector.Connector;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.embedded.tomcat.TomcatConnectorCustomizer;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.ContextClosedEvent; import lombok.extern.slf4j.Slf4j; /**
* 优雅关闭tomcat
* @author yangzl
* @data 2019年4月2日
*
*/
@Slf4j
@Configuration
public class TomcatGracefulShutdown implements TomcatConnectorCustomizer,
ApplicationListener<ContextClosedEvent> {
// 有个等待时间的配置
@Autowired
private ShutdownProperties properties; private volatile Connector connector; @Override
public void customize(Connector connector) {
this.connector = connector;
} @Override
public void onApplicationEvent(final ContextClosedEvent event) {
LocalDateTime startShutdown = LocalDateTime.now();
LocalDateTime stopShutdown = LocalDateTime.now();
try {
log.info("We are now in down mode, please wait " + properties.getWaitSecond() + " second(s)..."); if (connector == null) {
log.info("We are running unit test ... ");
Thread.sleep(properties.getWaitSecond() * 1000);
return;
}
connector.pause(); final Executor executor = connector.getProtocolHandler().getExecutor();
if (executor instanceof ThreadPoolExecutor) {
log.info("executor is ThreadPoolExecutor");
final ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executor;
threadPoolExecutor.shutdown();
if (!threadPoolExecutor.awaitTermination(properties.getWaitSecond(), TimeUnit.SECONDS)) {
log.warn("Tomcat thread pool did not shut down gracefully within " + properties.getWaitSecond() + " second(s). Proceeding with force shutdown");
} else {
log.debug("Tomcat thread pool is empty, we stop now");
}
}
stopShutdown = LocalDateTime.now();
} catch (final InterruptedException ex) {
log.error("The await termination has been interrupted : " + ex.getMessage());
Thread.currentThread().interrupt();
} finally {
final long seconds = Duration.between(startShutdown, stopShutdown).getSeconds();
log.info("Shutdown performed in " + seconds + " second(s)");
}
}
}

调用shutdown时tomcat会此等待M秒后再退出,效果基本等同于第二种方案,但最终退出时有时会报错,而且也仅仅适配tomcat,不够通用。

springcloud如何实现服务的平滑发布的更多相关文章

  1. springcloud添加自定义的endpoint来实现平滑发布

    在我之前的文章  springcloud如何实现服务的平滑发布 里介绍了基于pause的发布方案. 平滑发布的核心思想就是:所有服务的调用者不再调用该服务了就表示安全的将服务kill掉. 另外actu ...

  2. 通过Nginx、Consul、Upsync实现动态负载均衡和服务平滑发布

    前提 前段时间顺利地把整个服务集群和中间件全部从UCloud迁移到阿里云,笔者担任了架构和半个运维的角色.这里详细记录一下通过Nginx.Consul.Upsync实现动态负载均衡和服务平滑发布的核心 ...

  3. 实战SpringCloud响应式微服务系列教程(第二章)

    接上一篇:实战SpringCloud响应式微服务系列教程(第一章) 1.1.2背压 背压是响应式编程的核心概念,这一节也是我们了解响应式编程的重点. 1.背压的机制 在生产者/消费者模型中,我们意识到 ...

  4. 实战SpringCloud响应式微服务系列教程(第十章)响应式RESTful服务完整代码示例

    本文为实战SpringCloud响应式微服务系列教程第十章,本章给出响应式RESTful服务完整代码示例.建议没有之前基础的童鞋,先看之前的章节,章节目录放在文末. 1.搭建响应式RESTful服务. ...

  5. 系统架构设计:平滑发布和ABTesting

    平滑发布的介绍 背景 单位的云办公相关系统没有成熟的平滑发布方案,导致每一次发布都是直接发布,dll文件或配置文件的变更会引起站点的重启. 云办公系统的常驻用户有10000+,即使短短半分多钟,也会收 ...

  6. 一个C#开发者学习SpringCloud搭建微服务的心路历程

    前言 Spring Cloud很火,很多文章都有介绍如何使用,但对于我这种初学者,我需要从创建项目开始学起,所以这些文章对于我的启蒙,帮助不大,所以只好自己写一篇文章,用于备忘. SpringClou ...

  7. wcf服务与web发布时无法访问 几种解决办法

    1   如果wcf服务与web发布在同一iis目录下,没有跨域的问题   但发布前要修改 ServiceReferences.ClientConfig 把wcf服务地址改为你发布后的iis的ip地址( ...

  8. WCF报 当前已禁用此服务的元数据发布的错误

    这是 Windows© Communication Foundation 服务. 当前已禁用此服务的元数据发布. 如果具有该服务的访问权限,则可以通过完成下列步骤来修改 Web 或应用程序配置文件以便 ...

  9. springcloud干货之服务消费者(ribbon)

    本章介绍springcloud中的服务消费者 springcloud服务调用方式有两种实现方式: 1,restTemplate+ribbon, 2,feign 本来想一篇讲完,发现篇幅有点长,所以本章 ...

随机推荐

  1. PAT (Basic Level) Practise - 继续(3n+1)猜想

    题目链接:https://www.patest.cn/submissions/4414905 1005. 继续(3n+1)猜想 (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限 ...

  2. 20165319第五周java学习笔记

    教材内容总结 1.String类和StringBuffer类都覆盖了toString方法,都是返回字符串. 所以带不带toString效果是一样的. 2.instanceOf运算符可以用来判断某个对象 ...

  3. server client 套接字连接

    server端: 1. 阻塞型套接字,不能满足多个客户端同时访问 import socket server = socket.socket() server.bind((""127 ...

  4. Java中CardLayout布局方式的应用

    import java.awt.CardLayout; import java.awt.Color; import java.awt.Container; import javax.swing.JBu ...

  5. 001.Redis简介及安装

    一 Redis简介 1.1 Redis 简介 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis 与其他 key-value 缓存产品有以下三个特点: ...

  6. springboot整合视图层之freemarker

    整合freemarker要求必须将视图文件放在 src/main/resources下的templates文件夹下,该文件夹是安全的不可直接访问的,必须由controller之类的接受请求类去跳转,因 ...

  7. Codeforces.487C.Prefix Product Sequence(构造)

    题目链接 \(Description\) 对于一个序列\(a_i\),定义其前缀积序列为\(a_1\ \mathbb{mod}\ n,\ (a_1a_2)\ \mathbb{mod}\ n,...,( ...

  8. Victoria的舞会2——图的连通性及连通分量

    [Vijos1022]]Victoria的舞会2 Description Victoria是一位颇有成就的艺术家,他因油画作品<我爱北京天安门>闻名于世界.现在,他为了报答帮助他的同行们, ...

  9. CY7C68013 USB接口相机开发记录 - 第二天:驱动修改

    上次写了资料的下载,并对资料进行了分类,分完类看起来就比较清晰.同时通过强大的百度,也可以得到不少资料. 这里对比较关键的几个文件进行罗列: 一.驱动相关 cyusb.inf: 修改CYUSB.INF ...

  10. = =用createJS写个flyppyPeople

    声明:本文为原创文章,如需转载,请注明来源WAxes,谢谢! 最近flyppybird很流行啊,今天中午闲着没事干,就用现有的素材写了个flyppyPeople,因为角色是个人,所以就叫People啦 ...