精华内容
下载资源
问答
  • 下线检测项目
    千次阅读
    2018-11-30 18:08:59

    eureka微服务架构在生产环境部署会出现服务意外宕机的情况,根据eureka的服务注册监听可以实现对服务下线的监听,通过腾信的短信接口发送短信通知(可根据业务需要更改)

     

    @Component
    public class EurekaStateChangeListener {
        //服务下线监听
        @EventListener(condition = "#eurekaInstanceCanceledEvent.replication==false")
        public void listen(EurekaInstanceCanceledEvent eurekaInstanceCanceledEvent) {
            String serviceName = eurekaInstanceCanceledEvent.getAppName();
            String serverId = eurekaInstanceCanceledEvent.getServerId();
            //通知对象
            ArrayList<String> strings = new ArrayList<>();
            strings.add("188****0284");
            strings.add("158****3362");
            strings.add("150****2140");
        }
    
        public void sendNode(String serviceName,String serverId,ArrayList<String> strings,Boolean aBoolean) {
                int appid = 14****6761; // 1400开头
                // 短信应用SDK AppKey
                String appkey = "5************************88a1c7a";
                // 签名
                String smsSign = "****";
                try {
                    int templateId = 187713;
                    SmsMultiSender msender = new SmsMultiSender(appid, appkey);
                    SmsMultiSenderResult result =  msender.send(0, "86", strings,
                            " 服务中心"+serviceName+"下线,"+serverId+"。", "", "");
                } catch (HTTPException e) {
                    // HTTP响应码错误
                    e.printStackTrace();
                } catch (JSONException e) {
                    // json解析错误
                    e.printStackTrace();
                } catch (IOException e) {
                    // 网络IO错误
                    e.printStackTrace();
                } 
        }
        //服务注册监听
        @EventListener (condition = "#event.replication==false")
        public void listen(EurekaInstanceRegisteredEvent event) {
            InstanceInfo instanceInfo = event.getInstanceInfo();
            System.out.println(instanceInfo.getAppName());
    
        }
    

     

    更多相关内容
  • 文章目录主观下线客观下线选举领头Sentinel故障转移修改从服务器的复制目标 主观下线 默认情况下,Sentinel哨兵会以每秒一次的频率向所有与它创建命令连接的实例(包括主服务器、从服务器、其他Sentinel)发送PING...

    主观下线

    • 默认情况下,Sentinel哨兵会以每秒一次的频率向所有与它创建命令连接的实例(包括主服务器、从服务器、其他Sentinel)发送PING命令,并通过实例返回的PING命令回复来判断实例是否在线。
      在这里插入图片描述

    • 收到的有效回复为+PONG、-LOADING、-MASTERDOWN命令,其余都是无效回复(包括没有回复的)。

    • 如果在down-after-milliseconds毫秒以内,sentinel收到的都是无效回复,那么这个源sentinel就会认为实例进入主观下线状态(就是自己认为的),同时修改实例结构中的flags属性,改为SRI_S_DOWN(主观下线的标志)

    down-after-milliseconds毫秒不仅会成为Sentinel判断master进入主观下线的标准,还会成为Sentinel判断master 属下所有从服务器,以及所有同样监视master 的其他Sentinel进入主观下线的标准。

    • 多个Sentinel设置的主观下线时长可能不同
      down-after-milliseconds 选项另一个需要注意的地方是,对于监视同一个主服务器的多个Sentinel来说,这些Sentinel所设置的down-after-milliseconds 选项的值也可能不同,因此,当一个Sentinel将主服务器判断为主观下线时,其他Sentinel可能仍然会认为主服务器处于在线状态。举个例子,如果Sentinell载入了以下配置:
      sentinel monitor master 127.0.0.1 6379 2
      sentinel down-after-milliseconds master 50000
      而Sentinel2则载入了以下配置:
      sentinel monitor master 127.0.0.16379 2
      sentinel down-after-milliseconds master 10000
      那么当master 的断线时长超过10000毫秒之后,Sentinel2会将master 判断为主观下线,而Sentinell却认为master仍然在线。只有当master的断线时长超过50000毫秒之后,Sentinel1和 Sentinel2才会都认为master进入了主观下线状态。

    客观下线

    • 当Sentinel将一个主服务器判断为主观下线之后,为了确认这个主服务器是否真的下线了,它会向同样监视这一主服务器的其他Sentinel进行询问,看它们是否也认为主服务器已经进入了下线状态(可以是主观下线或者客观下线)。当Sentinel 从其他Sentinel那里接收到足够数量的已下线判断之后,Sentinel就会将从服务器判定为客观下线,并对主服务器执行故障转移操作。
    • 根据其他Sentinel发回的SENTINEL is-master-down-by-addr命令回复,Sentinel将统计其他Sentinel同意主服务器已下线的数量,当这一数量达到配置指定的判断客观下线所需的数量时,Sentinel 会将主服务器实例结构flags属性的SRI_O_DOwN标识打开,表示主服务器已经进入客观下线状态,如下图
      在这里插入图片描述

    判断客观下线的数量是Sentinel配置参数中的quorum参数,超过这个值就会被认为客观下线。因为各个Sentinel中的quorum参数可能不同,也就是说对同一个实例,有的可能认为它已经下线了,有的认为它没有下线

    选举领头Sentinel

    当一个主服务器被判断为客观下线时,监视这个下线主服务器的各个Sentinel会进行协商,选举出一个领头 Sentinel,并由领头Sentinel对下线主服务器执行故障转移操作。
    以下是Redis选举领头Sentinel的规则和方法:

    • 所有在线的Sentinel都有被选为领头Sentinel的资格,换句话说,监视同一个主服务器的多个在线Sentinel 中的任意一个都有可能成为领头 Sentinel。
    • 每次进行领头Sentinel选举之后,不论选举是否成功,所有Sentinel的配置纪元( configuration epoch)的值都会自增一次。配置纪元实际上就是一个计数器,并没有什么特别的。
    • 在一个配置纪元里面,所有Sentinel都有一次将某个Sentinel 设置为局部领头Sentinel的机会,并且局部领头一旦设置,在这个配置纪元里面就不能再更改。
    • 每个发现主服务器进入客观下线的Sentinel都会要求其他Sentinel将自己设置为局部领头Sentinel。
    • 当一个Sentinel(源Sentinel)向另一个Sentinel (目标Sentinel)发送SENTINELis-master-down-by-addr命令,并且命令中的runid参数不是*符号而是源Sentinel的运行ID时,这表示源Sentinel要求目标Sentinel将前者设置为后者的局部领头 Sentinel。
    • Sentinel设置局部领头 Sentinel的规则是先到先得:最先向目标Sentinel 发送设置要求的源Sentinel将成为目标Sentinel的局部领头Sentinel,而之后接收到的所有设置要求都会被目标Sentine1拒绝。
    • 目标Sentinel在接收到SENTINEL is-master-down-by-addr命令之后,将向源Sentinel返回一条命令回复,回复中的leader_runid参数和leader_epoch参数分别记录了目标Sentinel的局部领头Sentinel的运行ID和配置纪元。
    • 源Sentinel在接收到目标Sentinel返回的命令回复之后,会检查回复中leader_epoch参数的值和自己的配置纪元是否相同,如果相同的话,那么源Sentinel继续取出回复中的leader_runid参数,如果leader_runid参数的值和源Sentinel的运行ID一致,那么表示目标Sentinel将源Sentinel设置成了局部领头Sentinel。
    • 如果有某个Sentinel被半数以上的Sentinel设置成了局部领头 Sentinel,那么这个Sentinel成为领头entinel。举个例子,在一个由10个Sentinel组成的Sentinel系统里面,只要有大于等于10/2+1=6个Sentinel将某个Sentinel设置为局部领头Sentinel,那么被设置的那个Sentinel就会成为领头Sentinel。
    • 因为领头Sentinel的产生需要半数以上Sentinel的支持,并且每个Sentinel在每个配置纪元里面只能设置一次局部领头 Sentinel,所以在一个配置纪元里面,只会出现一个领头 Sentinel。
    • 如果在给定时限内,没有一个Sentinel被选举为领头Sentinel,那么各个Sentinel将在一段时间之后再次进行选举,直到选出领头 Sentinel 为止。

    故障转移

    • 在选举产生出领头Sentinel之后,领头Sentinel将对已下线的主服务器执行故障转移操作,该操作包含以下三个步骤:
    1. 在已下线主服务器属下的所有从服务器里面,挑选出一个从服务器,并将其转换为主服务器。
    2. 让已下线主服务器属下的所有从服务器改为复制新的主服务器。
    3. 将已下线主服务器设置为新的主服务器的从服务器,当这个旧的主服务器重新上线时,它就会成为新的主服务器的从服务器。

    新的主服务器是怎样挑选出来的
    领头Sentinel会将已下线主服务器的所有从服务器保存到一个列表里面,然后按照以下规则,一项一项地对列表进行过滤:
    1)删除列表中所有处于下线或者断线状态的从服务器,这可以保证列表中剩余的从服务器都是正常在线的。
    2)删除列表中所有最近五秒内没有回复过领头Sentinel的INFO命令的从服务器,这可以保证列表中剩余的从服务器都是最近成功进行过通信的。
    3)删除所有与已下线主服务器连接断开超过down-after-milliseconds * 10毫秒的从服务器:down-after-milliseconds 选项指定了判断主服务器下线所需的时间,而删除断开时长超过down-after-milliseconds * 10毫秒的从服务器,则可以保证列表中剩余的从服务器都没有过早地与主服务器断开连接,换句话说,列表中剩余的从服务器保存的数据都是比较新的。
    之后,领头Sentinel将根据从服务器的优先级,对列表中剩余的从服务器进行排序,并选出其中优先级最高的从服务器。
    如果有多个具有相同最高优先级的从服务器,那么领头Sentinel将按照从服务器的复制偏移量,对具有相同最高优先级的所有从服务器进行排序,并选出其中偏移量最大的从服务器(复制偏移量最大的从服务器就是保存着最新数据的从服务器)。
    最后,如果有多个优先级最高、复制偏移量最大的从服务器,那么领头 Sentinel将按照运行ID对这些从服务器进行排序,并选出其中运行ID最小的从服务器。

    • 在领头Sentinel向被选中的从服务器发送SLAVEOF no one命令之后,领头Sentinel会以每秒一次的频率(平时是每十秒一次),向被升级的从服务器发送INFO命令,并观察命令回复中的角色( role)信息,当被升级服务器的role从原来的slave变为master时,领头Sentinel就知道被选中的从服务器已经顺利升级为主服务器了。如下图
      在这里插入图片描述

    修改从服务器的复制目标

    • 领头Sentinel向向从服务器发送SLAVEOF命令,让他们复制新的主服务器。
      在这里插入图片描述
    • 最后将下线的主服务器设置为从服务器,如果重新上线,就会成为新主服务器的从服务器
      在这里插入图片描述
    展开全文
  • 本篇文章主要介绍了Android端“被挤下线”功能的单点登录实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 近年以来,随着整车功能复杂程度的提升,整车下线流程(EOL,End of Line) 也变得越来越复杂,除了传统的动力、车身部分的下线流程扩充外,更有智能驾驶,网络安全相关的新流程加入。而下线流程作为整车生产环节末端...

    引言

    近年以来,随着整车功能复杂程度的提升,整车下线流程(EOL,End of Line) 也变得越来越复杂,除了传统的动力、车身部分的下线流程扩充外,更有智能驾驶,网络安全相关的新流程加入。而下线流程作为整车生产环节末端的一部分,一旦出现问题,则会对生产效率产生较大影响,甚至导致生产停滞。因此,在车型研发过程中,越来越需要在量产之前基于单部件和实车环境测试验证整车下线流程相关需求,确保产线装车过程中下线流程的功能稳定性。本文将结合北汇信息为多个OEM提供研发阶段下线流程测试的经验,为整车下线流程的测试提供一种可靠的解决方案。


    1.背景知识

    传统的下线流程主要涉及动力和车身两大部分内容,一般是车辆完成装配后,离开生产线以前进行的一系列准备工作,比如制动油液的加注、动力系统自检、门窗天窗的自学习等。近年来智能驾驶和网络安全相关功能在车内得以应用,与之相关的部分流程,例如雷达标定、安全信息写入/校验等也被加入了下线流程。得益于目前车内总线式的通信方式,目前大部分的下线流程,均可通过上位机下发诊断指令来完成,也即通过ISO-14229中定义的2F服务(输入输出控制)和31服务(例程控制)来控制对应控制器执行相关步骤。

    因为下线流程涉及到产线生产,所以一旦出现严重问题往往意味着产线停止,严重影响生产效率。一些涉及到信息安全相关的功能,例如控制器之间的认证流程,一旦出现问题,车辆将无法启动;而涉及到动力和底盘的功能出现问题,也常常导致产线暂停。因此,在一款车型投产之前,对下线相关流程进行测试是很有必要的,尤其面对当今越来越复杂的下线流程,及早测试并发现问题往往意味着生产效率的大幅度提升。

    就下线流程的测试而言,我们可以将其分为两部分:通过仿真上位机的指令来观察下线流程中的诊断数据流是否正确;发送相应指令后观察各执行器的动作是否正常。 这其中,数据流的测试可以通过部件级测试执行,也可以通过实车级测试执行;而后者因为涉及到相关执行器,一般在实车级测试中执行较为方便。

    2.实现难点

    下线流程相较于传统的诊断协议和诊断功能,更注重与控制器功能上的交互;而与功能测试相比,为了提升效率,部分流程可能会通过诊断仪或者产线设备来自动化执行。因此下线流程测试综合了传统诊断测试与功能测试,对测试上位机有更高的要求,我们在分析多个OEM的下线流程后,总结了如下常见的实现难点,并针对这些难点开发了对应的解决方案。

    ①多控制器兼容性: 由于下线流程往往涉及多个控制器,因此需下线设备可同时兼容对多个不同功能控制器的测试

    ②下线流程灵活调配: 开发阶段的下线流程往往尚处于调试过程中,可能会随需求及实际项目进度发生改变,这就要求测试设备可以灵活的增减下线流程,便于开发阶段的调试

    ③多控制器并行诊断: 随着目前车内网络带宽的提升,越来越多的网络架构支持并行诊断或控制器并行升级,下线流程也往往使用并行诊断的方式,这就要求下线流程测试设备也可以做到对诊断请求的并行诊断


    3.方案简介

    针对上文列及的测试难点,北汇信息结合项目实际开发了一套可行测试方案,并在OEM的下线流程测试中进行了实践,获得了较好的效果。 下面我们将对该解决方案做简要介绍。

    该测试方案的核心为基于Vector公司CANoe软件开发的一套下线流程测试工程。如下图所示,工程主要由诊断底层模块,并行处理模块,下线流程模块及环境配置模块组成,并与其相关的外围设备,数据库等进行交互,仿真下线设备的响应指令,从而实现对下线流程的测试。接下来我们将对各个组成模块进行简单介绍:

    在这里插入图片描述


    诊断底层模块: 北汇信息基于CANoe开发环境实现的诊断应用层、TP层,目前已经涵盖了常见的CAN/CANFD/LIN/FlexRay/Ethernet等主流总线协议,并在此基础上实现了诊断应用层协议ISO-14229,可以通过配置适应不同总线的诊断数据发送需求。

    并行处理模块: 提供对多控制器的诊断请求并行发送处理,并可以针对各个控制器单独计算响应时间,判断响应数据。因为模块对于每个诊断地址单独开辟处理通道,因此可以方便的添加或减少支持同时发送的诊断地址数目,具有配置灵活的特点。

    下线流程模块: 包含了EOL所需要的流程,并可以通过方便地进行添加删减或排列组合。此外下线流程模块还可与数据库进行交互,从而获取各个控制器在EOL流程中需要用到的必要信息,或者刷新数据等。

    环境配置模块: 在项目开发的整个周期内,往往测试环境并不相同,以EOL测试为例,在项目前期,由于系统各组成部分尚处于早期开发阶段,测试环境往往为零部件级测试或者HiL台架;而到了测试后期,更多对于整个系统的测试会集中到实车环境。环境配置模块中包含了设备对外围设备控制的指令集,可以随着开发周期及测试环境的改变而适配不同的测试设备。


    从对各个模块的简介中,我们不难发现,该解决方案对上文提到的测试难点给出了一系列解决方案。

    通过该测试工程,使用者可以通过数据库方便地管理整个测试流程,在项目开发过程中及时进行流程上的调整;在完善好数据库后,工程使用时也可以通过勾选配置待测试ECU;此外,可配置的并行处理模块可以方便的调整并行诊断请求发送数目,并且可以通过配置诊断底层来适应多种总线类型;最后,随着项目推进,测试工程还可以方便地配置测试环境。


    4.方案实践

    为了使读者对解决方案有一个更直观的了解,将以我们已经开发的EOL测试工程为例,为读者介绍该方案在实际场景中的应用。

    该测试工程基于以太网DoIP的底层开发,对整车内所有控制器进行下线流程测试。如下图所示,测试工程运行后,会根据数据库中内容,将车内支持的全部控制器显示出来,以供测试人员选取测试控制器。当勾选测试控制器后,测试工程将按照预定流程向整车网关发送相应诊断数据,以仿真实际整车下线流程。
    在这里插入图片描述

    在测试过程中,工程使用并行诊断的方式,同时对多个控制器更新应用程序,且在数据库中,可以方便的配置下线流程。当测试完成后,测试模块会输出测试数据及测试报告,以供测试人员分析。


    在这里插入图片描述


    小结

    整车功能的急剧扩充,预埋软硬件成为趋势,也将测试环节的重要性一再凸显,可以预见,不久的将来整车下线流程将变得越来越复杂,更多的功能需在下线流程环节实现配置,这对于整车下线流程的测试提出了更高的要求。

    北汇信息长期深耕于汽车电子电器测试,为整车电子电器测试提供部件级,系统级,实车级一站式解决方案。同时,我们也更注重从需求设计出发,针对整车应用场景完善测试开发,形成闭环,以期为客户提供更高质量和更具前瞻性的测试方案。

    作者:北汇信息——李靖尧

    在这里插入图片描述

    在这里插入图片描述

    展开全文
  • shutdown脚本中执行类发起下线服务 -> 关闭端口 -> 检查下线服务直至完成 -> 关闭容器的流程。 而更简单的另一种方法是直接在脚本中加入kill -15命令。 优雅上线 优雅上线相对来说可能会更加困难一些,因为没有什么...

    作者:fredal

    fredal.xin/graceful-soa-updown

    对于微服务来说,服务的优雅上下线是必要的。就上线来说,如果组件或者容器没有启动成功,就不应该对外暴露服务,对于下线来说,如果机器已经停机了,就应该保证服务已下线,如此可避免上游流量进入不健康的机器。

    优雅下线

    基础下线(Spring/SpringBoot/内置容器)

    首先JVM本身是支持通过shutdownHook的方式优雅停机的。

    Runtime.getRuntime().addShutdownHook(new Thread() {
        @Override
        public void run() {
            close();
        }
    });
    

    此方式支持在以下几种场景优雅停机:

    1.程序正常退出

    2.使用System.exit()

    3.终端使用Ctrl+C

    4.使用Kill pid干掉进程

    那么如果你偏偏要kill -9 程序肯定是不知所措的。

    而在Springboot中,其实已经帮你实现好了一个shutdownHook,支持响应Ctrl+c或者kill -15 TERM信号。

    随便启动一个应用,然后Ctrl+c一下,观察日志就可知, 它在AnnotationConfigEmbeddedWebApplicationContext这个类中打印出了疑似Closing...的日志,真正的实现逻辑在其父类

    AbstractApplicationContext中(这个其实是spring中的类,意味着什么呢,在spring中就支持了对优雅停机的扩展)。

    public void registerShutdownHook() {    if (this.shutdownHook == nulpublic void registerShutdownHook() {
        if (this.shutdownHook == null) {
            this.shutdownHook = new Thread() {
                public void run() {
                    synchronized(AbstractApplicationContext.this.startupShutdownMonitor) {
                        AbstractApplicationContext.this.doClose();
                    }
                }
            };
            Runtime.getRuntime().addShutdownHook(this.shutdownHook);
        }
     
    }
     
    public void destroy() {
        this.close();
    }
     
    public void close() {
        Object var1 = this.startupShutdownMonitor;
        synchronized(this.startupShutdownMonitor) {
            this.doClose();
            if (this.shutdownHook != null) {
                try {
                    Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
                } catch (IllegalStateException var4) {
                    ;
                }
            }
     
        }
    }
     
    protected void doClose() {
        if (this.active.get() && this.closed.compareAndSet(false, true)) {
            if (this.logger.isInfoEnabled()) {
                this.logger.info("Closing " + this);
            }
     
            LiveBeansView.unregisterApplicationContext(this);
     
            try {
                this.publishEvent((ApplicationEvent)(new ContextClosedEvent(this)));
            } catch (Throwable var3) {
                this.logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", var3);
            }
     
            if (this.lifecycleProcessor != null) {
                try {
                    this.lifecycleProcessor.onClose();
                } catch (Throwable var2) {
                    this.logger.warn("Exception thrown from LifecycleProcessor on context close", var2);
                }
            }
     
            this.destroyBeans();
            this.closeBeanFactory();
            this.onClose();
            this.active.set(false);
        }
     
    }
    

    我们能对它做些什么呢,其实很明显,在doClose方法中它发布了一个ContextClosedEvent的方法,不就是给我们扩展用的么。于是我们可以写个监听器监听ContextClosedEvent,在发生事件的时候做下线逻辑,对微服务来说即是从注册中心中注销掉服务。

    @Component
    public class GracefulShutdownListener implements ApplicationListener<ContextClosedEvent> {
        
        @Override
        public void onApplicationEvent(ContextClosedEvent contextClosedEvent){
           //注销逻辑
           zookeeperRegistry.unregister(mCurrentServiceURL);
           ...
        }
    }
    

    可能会有疑问的是,微服务中一般来说,注销服务往往是优雅下线的第一步,接着才会执行停机操作,那么这个时候流量进来怎么办呢?

    个人会建议是,在注销服务之后就可开启请求挡板拒绝流量了,通过微服务框架本身的故障转移功能去处理被拒绝的流量即可。

    Docker中的下线

    好有人说了,我用docker部署服务,支不支持优雅下线。

    那来看看docker的一些停止命令都会干些啥:

    一般来说,正常人可能会用docker stop或者docker kill 命令去关闭容器(当然如果上一步注册了USR2自定义信息,可能会通过docker exec kill -12去关闭)。

    对于docker stop来说,它会发一个SIGTERM(kill -15 term信息)给容器的PID1进程,并且默认会等待10s,再发送一个SIGKILL(kill -9 信息)给PID1。

    那么很明显,docker stop允许程序有个默认10s的反应时间去做一下优雅停机的操作,程序只要能对kill -15 信号做些反应就好了,如上一步描述。那么这是比较良好的方式。

    当然如果shutdownHook方法执行了个50s,那肯定不优雅了。可以通过docker stop -t 加上等待时间。

    外置容器的shutdown脚本(Jetty)

    如果非要用外置容器方式部署(个人认为浪费资源并提升复杂度)。那么能不能优雅停机呢。

    可以当然也是可以的,这里有两种方式:

    首先RPC框架本身提供优雅上下线接口,以供调用来结束整个应用的生命周期,并且提供扩展点供开发者自定义服务下线自身的停机逻辑。

    同时调用该接口的操作会封装成一个preStop操作固化在jetty或者其他容器的shutdown脚本中,保证在容器停止之前先调用下线接口结束掉整个应用的生命周期。shutdown脚本中执行类发起下线服务 -> 关闭端口 -> 检查下线服务直至完成 -> 关闭容器的流程。

    而更简单的另一种方法是直接在脚本中加入kill -15命令。

    优雅上线

    优雅上线相对来说可能会更加困难一些,因为没有什么默认的实现方式,但是总之呢,一个原则就是确保端口存在之后才上线服务。

    springboot内置容器优雅上线

    这个就很简单了,并且业界在应用层面的优雅上线均是在内置容器的前提下实现的,并且还可以配合一些列健康检查做文章。

    参看sofa-boot的健康检查的源码,它会在程序启动的时候先对springboot的组件做一些健康检查,然后再对它自己搞得sofa的一些中间件做健康检查,整个健康检查的流程完毕之后(sofaboot 目前是没法对自身应用层面做健康检查的,它有写相关接口,但是写死了port is ready...)才会暴露服务或者说优雅上线,那么它健康检查的时机是什么时候呢:

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        healthCheckerProcessor.init();
        healthIndicatorProcessor.init();
        afterHealthCheckCallbackProcessor.init();
        publishBeforeHealthCheckEvent();
        readinessHealthCheck();
    }
    

    可以看到它是监听了ContextRefreshedEvent这个事件。在内置容器模式中,内置容器模式的start方法是在refreshContext方法中,方法执行完成之后发布一个ContextRefreshedEvent事件,也就是说在监听到这个事件的时候,内置容器必然是启动成功了的。

    但ContextRefreshedEvent这个事件,在一些特定场景中由于种种原因,ContextRefreshedEvent会被监听到多次,没有办法保证当前是最后一次event,从而正确执行优雅上线逻辑。

    在springboot中还有一个更加靠后的事件,叫做ApplicationReadyEvent,它的发布藏在了afterRefresh还要后面的那一句listeners.finished(context, null)中,完完全全可以保证内置容器 端口已经存在了,所以我们可以监听这个事件去做优雅上线的逻辑,甚至可以把中间件相关的健康检查集成在这里。

    @Component
    public class GracefulStartupListener implements ApplicationListener<ApplicationReadyEvent> {    
        @Override
        public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent){
           //注册逻辑 优雅上线
           apiRegister.register(urls);
           ...
        }
    }
    

    外置容器(Jetty)优雅上线

    目前大多数应用的部署模式不管是jetty部署模式还是docker部署模式(同样使用jetty镜像),本质上用的都是外置容器。那么这个情况就比较困难了,至少在应用层面无法观察到外部容器的运行状态,并且容器本身没有提供什么hook给你实现。

    那么和优雅上线一样,需要RPC框架提供优雅上线接口来初始化整个应用的生命周期,并且提供扩展点给开发者供执行自定义的上线逻辑(上报版本探测信息等)。

    同样将调用这个接口封装成一个postStart操作,固化在jetty等外置容器的startup脚本中,保证应用在容器启动之后在上线。容器执行类似启动容器 -> 健康检查 -> 上线服务逻辑 -> 健康上线服务直至完成 的流程。

    END

    推荐好文

    强大,10k+点赞的 SpringBoot 后台管理系统竟然出了详细教程!
    
    分享一套基于SpringBoot和Vue的企业级中后台开源项目,代码很规范!
    能挣钱的,开源 SpringBoot 商城系统,功能超全,超漂亮!
    
    
    
    
    展开全文
  • 在上篇文章《微服务:剖析一下源码,Nacos的健康检查竟如此简单》中讲了当微服务突然挂掉的解放方案:调整健康检查周期和故障请求重试。朋友看了文章,建议再聊聊正常关闭服务时如何让微服务优雅下线。 为什么说是...
  • 实际上,优雅下线是目标,而不是手段,它是一个相对的概念,例如kill PID和kill -9 PID都是暴力杀死服务,相对于kill -9 PID来说,kill PID就是优雅的。但如果单独拿kill PID出来说,我们能说它是优雅的下线
  • 【Redis】客观下线

    2022-06-07 09:27:51
    sentinelCheckObjectivelyDownsentinelCheckObjectivelyDown函数用于判断master节点是否客观下线:可以看到,master节点客观下线需要根据其他哨兵实例对主节点的判断来共同决定,具体是通过其他哨兵实例的flag中是否...
  • 文章目录前言优雅下线常见的下线方式优雅的下线方式灰度发布蓝绿部署滚动部署金丝雀部署在生产环境中,如何保证在服务升级的时候,不影响用户的体验,这个是一个非常重要的问题。如果在我们升级服务的时候,会造成一...
  • 前言前两天写了一篇文章,主要讲了下java中如何实现踢人下线,原文连接:java中如何踢人下线?封禁某个帐号后使其会话当即掉线!前端原本只是简单阐述一下踢人下线的业务场景和实现方案,没想到引出那么多大佬把小弟...
  • 真爱,请设置“星标”或点个“在看”来源:blog.csdn.net/qq_35246620/article/details/109166722文章目录前言优雅下线常见的下线方式优雅的下线方式灰度发布蓝绿部署滚动部署金丝雀部署前言在生产环境中,如何保证...
  • Spring Cloud 优雅下线以及灰度发布

    千次阅读 多人点赞 2020-10-20 10:43:55
    文章目录前言优雅下线常见的下线方式优雅的下线方式灰度发布蓝绿部署滚动部署金丝雀部署 前言 在生产环境中,如何保证在服务升级的时候,不影响用户的体验,这个是一个非常重要的问题。如果在我们升级服务的时候,会...
  • 在的redis启动函数main(server.c文件)中,对哨兵模式进行了检查,如果是哨兵模式,将调用initSentinelConfig和initSentinel进行初始化,initServer函数中会注册哨兵的时间事件,最后调用sentinelIsRunning运行哨兵...
  • 其实所说的被挤下线功能,就是一个账号在A客户端保持登陆状态,然后又在B客户端进行了登陆操作,那么A客户端就会被顶下线 很多伙伴在开发自己公司产品的时候,一般都会考虑用户账号安全,或者用户账号功能限制等...
  • 聊天业务 实现单聊 实现群聊 房间人数实时检查 实现离线消息 实现账号冲突强制下线 实现心跳在线检测 案例简介 Netty是Java的一个通信框架,是基于NIO来实现的,有许多的java中间件都是Netty来开发的,Netty的高性能...
  • 那这种被挤下线的行为其实很普遍,我接触过的每个项目几乎都用到过,就是用session来实现,应为每个设备的session不一样,服务端就根据你上传来的session来判断是不是同一台设备登录。首先,登录的时候...
  • 需求场景封禁账号是一个比较常见的业务需求,尤其是在论坛、社区类型的项目中,当出现了违规用户时我们需要将其账号立即封禁。常规的设计思路是:在设计用户表时增加一个状态字段,例如:status,其值为1时代表账号...
  • 服务下线 ```java /** * @Description: 服务下线 * @Author: PABLO * @Date: 2022/5/18 15:27 * @Params: [appName, id, isReplication] * @Return: boolean **/ protected boolean internalCancel(String ...
  • eureka注册中心优雅下线springboot服务

    千次阅读 2019-08-22 21:46:07
    方式一:kill -9 kiil -9 pid 太粗暴了!...这期间导致应用不可用!【非常比建议】 方式二:/shutdown端点【不建议】 ...Spring Boot提供了/shutdown端点,可以... 在想下线应用的applicationyml中添加如下配置,从...
  • 项目场景: SpringCloud 搭建之微服务A 共3个实例(端口8080、8081、8082),微服务B 共1个实例(端口8100)注册到注册中心(端口8761),微服务B调用微服务A,通过Feign及Ribbon默认的轮询,验证如下场景: 1、...
  • Spring Cloud : 如何优雅下线微服务?

    千次阅读 2019-09-10 07:57:11
    本文基于Spring Boot 2.x + Spring Cloud Finchley讲解实际项目中优雅下线服务的四种方式,并探讨各方式的优缺点。 注:Spring Boot 1.x + Spring Cloud Edgware及之前的方式相同,但配置有区别,本文不做讨论。 ...
  • 本文基于Spring Boot 2.x + Spring Cloud Finchley讲解实际项目中优雅下线服务的四种方式,并探讨各方式的优缺点。 注:Spring Boot 1.x + Spring Cloud Edgware及之前的方式相同,但配置有区别,本文不做讨论。 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 21,954
精华内容 8,781
关键字:

下线检测项目